diff -urN newtree/Documentation/fb/vesafb.txt newtree.2/Documentation/fb/vesafb.txt
--- newtree/Documentation/fb/vesafb.txt	2006-07-15 14:53:08.000000000 -0700
+++ newtree.2/Documentation/fb/vesafb.txt	2006-08-04 14:07:25.000000000 -0700
@@ -2,16 +2,18 @@
 What is vesafb?
 ===============
 
-This is a generic driver for a graphic framebuffer on intel boxes.
+Vesafb is a generic framebuffer driver for x86 and x86_64 boxes.
 
-The idea is simple:  Turn on graphics mode at boot time with the help
-of the BIOS, and use this as framebuffer device /dev/fb0, like the m68k
-(and other) ports do.
-
-This means we decide at boot time whenever we want to run in text or
-graphics mode.  Switching mode later on (in protected mode) is
-impossible; BIOS calls work in real mode only.  VESA BIOS Extensions
-Version 2.0 are required, because we need a linear frame buffer.
+VESA BIOS Extensions Version 2.0 are required, because we need access to
+a linear frame buffer. VBE 3.0 is required if you want to use modes with a
+higher (than the standard 60 Hz) refresh rate.
+
+The VESA framebuffer driver comes in two flavors - the standard 'vesafb'
+and 'vesafb-tng'. Vesafb-tng is available only on 32-bit x86 due to the
+technology it uses (vm86). Vesafb-tng has more features than vesafb
+(adjusting the refresh rate on VBE 3.0 compliant boards, switching the
+video mode without rebooting, selecting a mode by providing its
+modedb name, and more).
 
 Advantages:
 
@@ -29,26 +31,35 @@
 How to use it?
 ==============
 
-Switching modes is done using the vga=... boot parameter.  Read
-Documentation/svga.txt for details.
-
-You should compile in both vgacon (for text mode) and vesafb (for
-graphics mode). Which of them takes over the console depends on
-whenever the specified mode is text or graphics.
-
-The graphic modes are NOT in the list which you get if you boot with
-vga=ask and hit return. The mode you wish to use is derived from the
-VESA mode number. Here are those VESA mode numbers:
+If you are running a 32-bit x86 system and you decide to use vesafb-tng,
+you can either compile the driver into the kernel or use it as a module.
+The graphics mode you want to use is in both cases specified using the
+standard modedb format.
+
+If your system doesn't support vm86 calls, things get a little more tricky.
+Since on such systems you can't do BIOS calls from protected mode in which
+kernel runs, you have to decide at boot time whenever you want to run in text
+or in graphics mode. Switching mode later on is impossible. Switching modes
+is done using the vga=... boot parameter.  Read Documentation/svga.txt for
+details. Below is a more detailed description of what to do on systems using
+the standard vesafb driver.
+
+You should compile in both vgacon (for text mode) and vesafb (for graphics
+mode). Which of them takes over the console depends on whenever the
+specified mode is text or graphics.
+
+The graphic modes are NOT in the list which you get if you boot with vga=ask
+and hit return. The mode you wish to use is derived from the VESA mode number.
+Here are those VESA mode numbers:
 
     | 640x480  800x600  1024x768 1280x1024
 ----+-------------------------------------
-256 |  0x101    0x103    0x105    0x107   
-32k |  0x110    0x113    0x116    0x119   
-64k |  0x111    0x114    0x117    0x11A   
-16M |  0x112    0x115    0x118    0x11B   
+256 |  0x101    0x103    0x105    0x107
+32k |  0x110    0x113    0x116    0x119
+64k |  0x111    0x114    0x117    0x11A
+16M |  0x112    0x115    0x118    0x11B
 
-The video mode number of the Linux kernel is the VESA mode number plus
-0x200.
+The video mode number of the Linux kernel is the VESA mode number plus 0x200.
  
  Linux_kernel_mode_number = VESA_mode_number + 0x200
 
@@ -56,15 +67,15 @@
 
     | 640x480  800x600  1024x768 1280x1024
 ----+-------------------------------------
-256 |  0x301    0x303    0x305    0x307   
-32k |  0x310    0x313    0x316    0x319   
-64k |  0x311    0x314    0x317    0x31A   
-16M |  0x312    0x315    0x318    0x31B   
-
-To enable one of those modes you have to specify "vga=ask" in the
-lilo.conf file and rerun LILO. Then you can type in the desired
-mode at the "vga=ask" prompt. For example if you like to use 
-1024x768x256 colors you have to say "305" at this prompt.
+256 |  0x301    0x303    0x305    0x307
+32k |  0x310    0x313    0x316    0x319
+64k |  0x311    0x314    0x317    0x31A
+16M |  0x312    0x315    0x318    0x31B
+
+To enable one of those modes you have to specify "vga=ask" in the lilo.conf
+file and rerun LILO. Then you can type in the desired mode at the "vga=ask"
+prompt. For example if you like to use 1024x768x256 colors you have to say
+"305" at this prompt.
 
 If this does not work, this might be because your BIOS does not support
 linear framebuffers or because it does not support this mode at all.
@@ -72,11 +83,12 @@
 Extensions v2.0 are required, 1.2 is NOT sufficient.  You will get a
 "bad mode number" message if something goes wrong.
 
-1. Note: LILO cannot handle hex, for booting directly with 
+1. Note: LILO cannot handle hex, for booting directly with
          "vga=mode-number" you have to transform the numbers to decimal.
 2. Note: Some newer versions of LILO appear to work with those hex values,
          if you set the 0x in front of the numbers.
 
+
 X11
 ===
 
@@ -84,98 +96,164 @@
 another (accelerated) X-Server like XF86_SVGA might or might not work.
 It depends on X-Server and graphics board.
 
-The X-Server must restore the video mode correctly, else you end up
+The X-Server must restore the video mode correctly, or else you end up
 with a broken console (and vesafb cannot do anything about this).
+With vesafb-tng chances are that the console will be restored properly
+even if the X server messes up the video mode.
 
 
 Refresh rates
 =============
 
-There is no way to change the vesafb video mode and/or timings after
-booting linux.  If you are not happy with the 60 Hz refresh rate, you
-have these options:
-
- * configure and load the DOS-Tools for your the graphics board (if
-   available) and boot linux with loadlin.
- * use a native driver (matroxfb/atyfb) instead if vesafb.  If none
+With VBE 3.0 compatible BIOSes and vesafb-tng it is possible to change
+the refresh rate either at boot time (by specifying the @<rr> part of
+the mode name) or later, using the fbset utility.
+
+If you want to use the default BIOS refresh rate while switching modes
+on a running system, set pixclock to 0.
+
+With VBE 2.0 there is no way to change the mode timings after booting
+Linux. If you are not happy with the 60 Hz refresh rate, you have
+the following options:
+
+ * Configure and load the DOS tools for your the graphics board (if
+   available) and boot Linux with loadlin.
+ * Use a native driver (matroxfb/atyfb) instead of vesafb.  If none
    is available, write a new one!
- * VBE 3.0 might work too.  I have neither a gfx board with VBE 3.0
-   support nor the specs, so I have not checked this yet.
+ * Use a BIOS editor to change the default refresh rate (such an
+   editor does exist at least for ATI Radeon BIOSes).
+ * If you're running a non-vm86 and VBE 3.0 compatible system, you can
+   use a kernel patch (vesafb-rrc) to hard-code some mode timings in
+   the kernel and use these while setting the video mode at boot time.
+
+Note that there are some boards (nVidia 59**, 57** and newer models)
+claiming that their Video BIOS is VBE 3.0 compliant, while ignoring the
+CRTC values provided by software such as vesafb-tng. You'll not be able
+to adjust the refresh rate if you're using one of these boards.
 
 
 Configuration
 =============
 
-The VESA BIOS provides protected mode interface for changing
-some parameters.  vesafb can use it for palette changes and
-to pan the display.  It is turned off by default because it
-seems not to work with some BIOS versions, but there are options
-to turn it on.
-
-You can pass options to vesafb using "video=vesafb:option" on
-the kernel command line.  Multiple options should be separated
-by comma, like this: "video=vesafb:ypan,invers"
-
-Accepted options:
-
-invers	no comment...
-
-ypan	enable display panning using the VESA protected mode 
-	interface.  The visible screen is just a window of the
-	video memory, console scrolling is done by changing the
-	start of the window.
-	pro:	* scrolling (fullscreen) is fast, because there is
-		  no need to copy around data.
-		* You'll get scrollback (the Shift-PgUp thing),
-		  the video memory can be used as scrollback buffer
-	kontra: * scrolling only parts of the screen causes some
-		  ugly flicker effects (boot logo flickers for
-		  example).
-
-ywrap	Same as ypan, but assumes your gfx board can wrap-around 
-	the video memory (i.e. starts reading from top if it
-	reaches the end of video memory).  Faster than ypan.
-
-redraw	scroll by redrawing the affected part of the screen, this
-	is the safe (and slow) default.
-
-
-vgapal	Use the standard vga registers for palette changes.
-	This is the default.
-pmipal	Use the protected mode interface for palette changes.
-
-mtrr:n	setup memory type range registers for the vesafb framebuffer
-	where n:
-	      0 - disabled (equivalent to nomtrr) (default)
-	      1 - uncachable
-	      2 - write-back
-	      3 - write-combining
-	      4 - write-through
+The VESA BIOS provides protected mode interface for changing some parameters.
+vesafb can use it for palette changes and to pan the display. It is turned
+off by default because it seems not to work with some BIOS versions, but
+there are options to turn it on.
+
+You can pass options to vesafb using "video=vesafb:option" on the kernel
+command line. Multiple options should be separated by a comma, like this:
+"video=vesafb:ypan,1024x768-32@85"
+
+Note that vesafb-tng still uses the "video=vesafb:option" format of the
+kernel command line video parameter. "video=vesafb-tng:xxx" is incorrect.
+
+Accepted options (both vesafb and vesafb-tng):
+
+ypan    Enable display panning using the VESA protected mode interface
+        The visible screen is just a window of the video memory,
+        console scrolling is done by changing the start of the window.
+        pro:    * scrolling (fullscreen) is fast, because there is
+                  no need to copy around data.
+                * you'll get scrollback (the Shift-PgUp thing),
+                  the video memory can be used as scrollback buffer
+        con:    * scrolling only parts of the screen causes some
+                  ugly flicker effects (boot logo flickers for
+                  example).
+
+ywrap   Same as ypan, but assumes your gfx board can wrap-around the video
+        memory (i.e. starts reading from top if it reaches the end of
+        video memory). Faster than ypan.
+
+redraw  Scroll by redrawing the affected part of the screen, this is the
+        safe (and slow) default.
+
+vgapal  Use the standard VGA registers for palette changes.
+
+pmipal  Use the protected mode interface for palette changes.
+        This is the default is the protected mode interface is available.
+
+mtrr:n  Setup memory type range registers for the vesafb framebuffer
+        where n:
+              0 - disabled (equivalent to nomtrr) (default)
+              1 - uncachable
+              2 - write-back
+              3 - write-combining
+              4 - write-through
 
-	If you see the following in dmesg, choose the type that matches the
-	old one. In this example, use "mtrr:2".
+        If you see the following in dmesg, choose the type that matches
+        the old one. In this example, use "mtrr:2".
 ...
 mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
 ...
 
-nomtrr  disable mtrr
+nomtrr  Do not use memory type range registers for vesafb.
 
 vremap:n
         remap 'n' MiB of video RAM. If 0 or not specified, remap memory
-	according to video mode. (2.5.66 patch/idea by Antonino Daplas
-	reversed to give override possibility (allocate more fb memory
-	than the kernel would) to 2.4 by tmb@iki.fi)
+        according to video mode. (2.5.66 patch/idea by Antonino Daplas
+        reversed to give override possibility (allocate more fb memory
+        than the kernel would) to 2.4 by tmb@iki.fi)
 
 vtotal:n
         if the video BIOS of your card incorrectly determines the total
         amount of video RAM, use this option to override the BIOS (in MiB).
 
-Have fun!
+Options accepted only by vesafb-tng:
 
-  Gerd
+<mode>  The mode you want to set, in the standard modedb format. Refer to
+        modedb.txt for a detailed description. If you specify a mode that is
+        not supported by your board's BIOS, vesafb-tng will attempt to set a
+        similar mode. The list of supported modes can be found in
+        /proc/fbx/modes, where x is the framebuffer number (usually 0).
+        When vesafb-tng is compiled as a module, the mode string should be
+        provided as a value of the parameter 'mode'.
+
+vbemode:x
+        Force the use of VBE mode x. The mode will only be set if it's
+        found in the VBE-provided list of supported modes.
+        NOTE: The mode number 'x' should be specified in VESA mode number
+        notation, not the Linux kernel one (eg. 257 instead of 769).
+        HINT: If you use this option because normal <mode> parameter does
+        not work for you and you use a X server, you'll probably want to
+        set the 'nocrtc' option to ensure that the video mode is properly
+        restored after console <-> X switches.
+
+nocrtc  Do not use CRTC timings while setting the video mode. This option
+        makes sence only with VBE 3.0 compliant systems. Use it if you have
+        problems with modes set in the standard way. Note that using this
+		option means that any refresh rate adjustments will be ignored
+		and the refresh rate will stay at your BIOS default (60 Hz).
+
+noedid  Do not try to fetch and use EDID-provided modes.
+
+noblank Disable hardware blanking.
+
+gtf     Force the use of VESA's GTF (Generalized Timing Formula). Specifying
+        this will cause vesafb to skip its internal modedb and EDID-modedb
+        and jump straight to the GTF part of the code (normally used only if
+        everything else failed). This can be useful if you want to get as
+        much as possible from your graphics board but your BIOS doesn't
+        support modes with the refresh rates you require. Note that you may 
+		need to specify the maxhf, maxvf and maxclk parameters if they are not
+        provided by the EDID block.
+
+Additionally, the following parameters may be provided. They all override the
+EDID-provided values and BIOS defaults. Refer to your monitor's specs to get
+the correct values for maxhf, maxvf and maxclk for your hardware.
+
+maxhf:n     Maximum horizontal frequency (in kHz).
+maxvf:n     Maximum vertical frequency (in Hz).
+maxclk:n    Maximum pixel clock (in MHz).
+
+Have fun!
 
 --
+Original document for the vesafb driver by
 Gerd Knorr <kraxel@goldbach.in-berlin.de>
 
-Minor (mostly typo) changes 
-by Nico Schmoigl <schmoigl@rumms.uni-mannheim.de>
+Minor (mostly typo) changes by
+Nico Schmoigl <schmoigl@rumms.uni-mannheim.de>
+
+Extended documentation for vm86, VBE 3.0 and vesafb-tng by
+Michal Januszewski <spock@gentoo.org>
+
diff -urN newtree/arch/i386/boot/video.S newtree.2/arch/i386/boot/video.S
--- newtree/arch/i386/boot/video.S	2006-07-15 14:53:08.000000000 -0700
+++ newtree.2/arch/i386/boot/video.S	2006-08-04 14:07:26.000000000 -0700
@@ -165,10 +165,12 @@
 # parameters in the default 80x25 mode -- these are set directly,
 # because some very obscure BIOSes supply insane values.
 mode_params:
+#ifdef CONFIG_FB_VESA_STD
 #ifdef CONFIG_VIDEO_SELECT
 	cmpb	$0, graphic_mode
 	jnz	mopar_gr
 #endif
+#endif
 	movb	$0x03, %ah			# Read cursor position
 	xorb	%bh, %bh
 	int	$0x10
@@ -201,6 +203,7 @@
 	ret
 
 #ifdef CONFIG_VIDEO_SELECT
+#ifdef CONFIG_FB_VESA_STD
 # Fetching of VESA frame buffer parameters
 mopar_gr:
 	leaw	modelist+1024, %di
@@ -283,6 +286,7 @@
 	movw	%es, %fs:(PARAM_VESAPM_SEG)
 	movw	%di, %fs:(PARAM_VESAPM_OFF)
 no_pm:	ret
+#endif
 
 # The video mode menu
 mode_menu:
@@ -497,10 +501,12 @@
 	
 	cmpb	$VIDEO_FIRST_V7>>8, %ah
 	jz	setv7
-	
+
+#ifdef CONFIG_FB_VESA_STD
 	cmpb	$VIDEO_FIRST_VESA>>8, %ah
 	jnc	check_vesa
-	
+#endif	
+
 	orb	%ah, %ah
 	jz	setmenu
 	
@@ -572,6 +578,7 @@
 	movw	-4(%si), %ax			# Fetch mode ID
 	jmp	_m_s
 
+#ifdef CONFIG_FB_VESA_STD
 check_vesa:
 	leaw	modelist+1024, %di
 	subb	$VIDEO_FIRST_VESA>>8, %bh
@@ -605,6 +612,7 @@
 	ret
 
 _setbad:	jmp	setbad          	# Ugly...
+#endif
 
 # Recalculate vertical display end registers -- this fixes various
 # inconsistencies of extended modes on many adapters. Called when
diff -urN newtree/drivers/usb/storage/unusual_devs.h~ newtree.2/drivers/usb/storage/unusual_devs.h~
--- newtree/drivers/usb/storage/unusual_devs.h~	2006-07-15 14:53:08.000000000 -0700
+++ newtree.2/drivers/usb/storage/unusual_devs.h~	1969-12-31 16:00:00.000000000 -0800
@@ -1,1333 +0,0 @@
-/* Driver for USB Mass Storage compliant devices
- * Unusual Devices File
- *
- * $Id: unusual_devs.h,v 1.32 2002/02/25 02:41:24 mdharm Exp $
- *
- * Current development and maintenance by:
- *   (c) 2000-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
- *
- * Initial work by:
- *   (c) 2000 Adam J. Richter (adam@yggdrasil.com), Yggdrasil Computing, Inc.
- *
- * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
- * information about this driver.
- *
- * 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.
- */
-
-/* IMPORTANT NOTE: This file must be included in another file which does
- * the following thing for it to work:
- * The macro UNUSUAL_DEV() must be defined before this file is included
- */
-
-/* If you edit this file, please try to keep it sorted first by VendorID,
- * then by ProductID.
- *
- * If you want to add an entry for this file, be sure to include the
- * following information:
- *	- a patch that adds the entry for your device, including your
- *	  email address right above the entry (plus maybe a brief
- *	  explanation of the reason for the entry),
- *	- a copy of /proc/bus/usb/devices with your device plugged in
- *	  running with this patch.
- * Send your submission to either Phil Dibowitz <phil@ipom.com> or
- * Alan Stern <stern@rowland.harvard.edu>, and don't forget to CC: the
- * USB development list <linux-usb-devel@lists.sourceforge.net>.
- */
-
-/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
- */
-UNUSUAL_DEV(  0x03eb, 0x2002, 0x0100, 0x0100,
-                "ATMEL",
-                "SND1 Storage",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_IGNORE_RESIDUE),
-
-UNUSUAL_DEV(  0x03ee, 0x6901, 0x0000, 0x0100,
-		"Mitsumi",
-		"USB FDD",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Reported by Rodolfo Quesada <rquesada@roqz.net> */
-UNUSUAL_DEV(  0x03ee, 0x6906, 0x0003, 0x0003,
-		"VIA Technologies Inc.",
-		"Mitsumi multi cardreader",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-UNUSUAL_DEV(  0x03f0, 0x0107, 0x0200, 0x0200, 
-		"HP",
-		"CD-Writer+",
-		US_SC_8070, US_PR_CB, NULL, 0), 
-
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x03f0, 0x0207, 0x0001, 0x0001, 
-		"HP",
-		"CD-Writer+ 8200e",
-		US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-
-UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001, 
-		"HP",
-		"CD-Writer+ CD-4e",
-		US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-#endif
-
-/* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
- * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
- * for USB floppies that need the SINGLE_LUN enforcement.
- */
-UNUSUAL_DEV(  0x0409, 0x0040, 0x0000, 0x9999,
-		"NEC",
-		"NEC USB UF000x",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
-UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
-		"VIA Technologies Inc.",
-		"USB 2.0 Card Reader",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
- * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
- * always fails and confuses drive.
- */
-UNUSUAL_DEV(  0x0411, 0x001c, 0x0113, 0x0113,
-		"Buffalo",
-		"DUB-P40G HDD",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* Submitted by Ernestas Vaiciukevicius <ernisv@gmail.com> */
-UNUSUAL_DEV(  0x0419, 0x0100, 0x0100, 0x0100,
-                "Samsung Info. Systems America, Inc.",
-                "MP3 Player",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Orgad Shaneh <orgads@gmail.com> */
-UNUSUAL_DEV(  0x0419, 0xaace, 0x0100, 0x0100,
-		"Samsung", "MP3 Player",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Christian Leber <christian@leber.de> */
-UNUSUAL_DEV(  0x0419, 0xaaf5, 0x0100, 0x0100,
-		"TrekStor",
-		"i.Beat 115 2.0",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE | US_FL_NOT_LOCKABLE ),
-
-/* Reported by Stefan Werner <dustbln@gmx.de> */
-UNUSUAL_DEV(  0x0419, 0xaaf6, 0x0100, 0x0100,
-		"TrekStor",
-		"i.Beat Joy 2.0",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Pete Zaitcev <zaitcev@redhat.com>, bz#176584 */
-UNUSUAL_DEV(  0x0420, 0x0001, 0x0100, 0x0100,
-		"GENERIC", "MP3 PLAYER", /* MyMusix PD-205 on the outside. */
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
- * Einar Th. Einarsson <einarthered@gmail.com> */
-UNUSUAL_DEV(  0x0421, 0x0444, 0x0100, 0x0100,
-		"Nokia",
-		"N91",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
-
-/* Reported by Jiri Slaby <jirislaby@gmail.com> and
- * Rene C. Castberg <Rene@Castberg.org> */
-UNUSUAL_DEV(  0x0421, 0x0446, 0x0100, 0x0100,
-		"Nokia",
-		"N80",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
-
-/* Reported by Matthew Bloch <matthew@bytemark.co.uk> */
-UNUSUAL_DEV(  0x0421, 0x044e, 0x0100, 0x0100,
-		"Nokia",
-		"E61",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
-
-/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
-UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
-		"SMSC",
-		"FDC GOLD-2.30",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-#ifdef CONFIG_USB_STORAGE_DPCM
-UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
-		"Microtech",
-		"CameraMate (DPCM_USB)",
- 		US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#endif
-
-/* Patch submitted by Daniel Drake <dsd@gentoo.org>
- * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */
-UNUSUAL_DEV(  0x0451, 0x5416, 0x0100, 0x0100,
-		"Neuros Audio",
-		"USB 2.0 HD 2.5",
-		US_SC_DEVICE, US_PR_BULK, NULL,
-		US_FL_NEED_OVERRIDE ),
-
-/*
- * Pete Zaitcev <zaitcev@yahoo.com>, from Patrick C. F. Ernzer, bz#162559.
- * The key does not actually break, but it returns zero sense which
- * makes our SCSI stack to print confusing messages.
- */
-UNUSUAL_DEV(  0x0457, 0x0150, 0x0100, 0x0100,
-		"USBest Technology",	/* sold by Transcend */
-		"USB Mass Storage Device",
-		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
-
-/*
-* Bohdan Linda <bohdan.linda@gmail.com>
-* 1GB USB sticks MyFlash High Speed. I have restricted
-* the revision to my model only
-*/
-UNUSUAL_DEV(  0x0457, 0x0151, 0x0100, 0x0100,
-                "USB 2.0",
-                "Flash Disk",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_NOT_LOCKABLE ),
-
-UNUSUAL_DEV(  0x045a, 0x5210, 0x0101, 0x0101,
-		"Rio",
-		"Rio Karma",
-		US_SC_SCSI, US_PR_BULK, rio_karma_init, 0),
-
-/* Patch submitted by Philipp Friedrich <philipp@void.at> */
-UNUSUAL_DEV(  0x0482, 0x0100, 0x0100, 0x0100,
-		"Kyocera",
-		"Finecam S3x",
-		US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
-
-/* Patch submitted by Philipp Friedrich <philipp@void.at> */
-UNUSUAL_DEV(  0x0482, 0x0101, 0x0100, 0x0100,
-		"Kyocera",
-		"Finecam S4",
-		US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
-
-/* Patch submitted by Stephane Galles <stephane.galles@free.fr> */
-UNUSUAL_DEV(  0x0482, 0x0103, 0x0100, 0x0100,
-		"Kyocera",
-		"Finecam S5",
-		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY),
-
-/* Patch for Kyocera Finecam L3
- * Submitted by Michael Krauth <michael.krauth@web.de>
- * and Alessandro Fracchetti <al.fracchetti@tin.it>
- */
-UNUSUAL_DEV(  0x0482, 0x0105, 0x0100, 0x0100,
-		"Kyocera",
-		"Finecam L3",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_FIX_INQUIRY),
-
-/* Reported by Paul Stewart <stewart@wetlogic.net>
- * This entry is needed because the device reports Sub=ff */
-UNUSUAL_DEV(  0x04a4, 0x0004, 0x0001, 0x0001,
-		"Hitachi",
-		"DVD-CAM DZ-MV100A Camcorder",
-		US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN),
-
-/* Patch for Nikon coolpix 2000
- * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/
-UNUSUAL_DEV(  0x04b0, 0x0301, 0x0010, 0x0010,
-		"NIKON",
-		"NIKON DSC E2000",
-		US_SC_DEVICE, US_PR_DEVICE,NULL,
-		US_FL_NOT_LOCKABLE ),
-
-/* Reported by Andreas Bockhold <andreas@bockionline.de> */
-UNUSUAL_DEV(  0x04b0, 0x0405, 0x0100, 0x0100,
-		"NIKON",
-		"NIKON DSC D70",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY),
-
-/* Reported by Jamie Kitson <jamie@staberinde.fsnet.co.uk> */
-UNUSUAL_DEV(  0x04b0, 0x040d, 0x0100, 0x0100,
-		"NIKON",
-		"NIKON DSC D70s",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY),
-
-/* BENQ DC5330
- * Reported by Manuel Fombuena <mfombuena@ya.com> and
- * Frank Copeland <fjc@thingy.apana.org.au> */
-UNUSUAL_DEV(  0x04a5, 0x3010, 0x0100, 0x0100,
-		"Tekom Technologies, Inc",
-		"300_CAMERA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Simon Levitt <simon@whattf.com>
- * This entry needs Sub and Proto fields */
-UNUSUAL_DEV(  0x04b8, 0x0601, 0x0100, 0x0100,
-		"Epson",
-		"875DC Storage",
-		US_SC_SCSI, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
-
-/* Reported by Khalid Aziz <khalid@gonehiking.org>
- * This entry is needed because the device reports Sub=ff */
-UNUSUAL_DEV(  0x04b8, 0x0602, 0x0110, 0x0110,
-		"Epson",
-		"785EPX Storage",
-		US_SC_SCSI, US_PR_BULK, NULL, US_FL_SINGLE_LUN),
-
-/* Not sure who reported this originally but
- * Pavel Machek <pavel@ucw.cz> reported that the extra US_FL_SINGLE_LUN
- * flag be added */
-UNUSUAL_DEV(  0x04cb, 0x0100, 0x0000, 0x2210,
-		"Fujifilm",
-		"FinePix 1400Zoom",
-		US_SC_UFI, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN),
-
-/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
- * The device needs the flags only.
- */
-UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x0074,
-		"ScanLogic",
-		"SL11R-IDE",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY),
-
-/* Reported by Kriston Fincher <kriston@airmail.net>
- * Patch submitted by Sean Millichamp <sean@bruenor.org>
- * This is to support the Panasonic PalmCam PV-SD4090
- * This entry is needed because the device reports Sub=ff 
- */
-UNUSUAL_DEV(  0x04da, 0x0901, 0x0100, 0x0200,
-		"Panasonic",
-		"LS-120 Camera",
-		US_SC_UFI, US_PR_DEVICE, NULL, 0),
-
-/* From Yukihiro Nakai, via zaitcev@yahoo.com.
- * This is needed for CB instead of CBI */
-UNUSUAL_DEV(  0x04da, 0x0d05, 0x0000, 0x0000,
-		"Sharp CE-CW05",
-		"CD-R/RW Drive",
-		US_SC_8070, US_PR_CB, NULL, 0),
-
-/* Reported by Adriaan Penning <a.penning@luon.net> */
-UNUSUAL_DEV(  0x04da, 0x2372, 0x0000, 0x9999,
-		"Panasonic",
-		"DMC-LCx Camera",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
-
-/* Reported by Simeon Simeonov <simeonov_2000@yahoo.com> */
-UNUSUAL_DEV(  0x04da, 0x2373, 0x0000, 0x9999,
-		"LEICA",
-		"D-LUX Camera",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
-
-/* Most of the following entries were developed with the help of
- * Shuttle/SCM directly.
- */
-UNUSUAL_DEV(  0x04e6, 0x0001, 0x0200, 0x0200, 
-		"Matshita",
-		"LS-120",
-		US_SC_8020, US_PR_CB, NULL, 0),
-
-UNUSUAL_DEV(  0x04e6, 0x0002, 0x0100, 0x0100, 
-		"Shuttle",
-		"eUSCSI Bridge",
-		US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, 
-		US_FL_SCM_MULT_TARG ), 
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999, 
-		"Sandisk",
-		"ImageMate SDDR09",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
-		0),
-
-/* This entry is from Andries.Brouwer@cwi.nl */
-UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
-		"SCM Microsystems",
-		"eUSB SmartMedia / CompactFlash Adapter",
-		US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
-		0), 
-#endif
-
-/* Reported by Markus Demleitner <msdemlei@cl.uni-heidelberg.de> */
-UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0100, 
-		"SCM Microsystems Inc.",
-		"eUSB MMC Adapter",
-		US_SC_SCSI, US_PR_CB, NULL, 
-		US_FL_SINGLE_LUN), 
-
-/* Reported by Daniel Nouri <dpunktnpunkt@web.de> */
-UNUSUAL_DEV(  0x04e6, 0x0006, 0x0205, 0x0205, 
-		"Shuttle",
-		"eUSB MMC Adapter",
-		US_SC_SCSI, US_PR_DEVICE, NULL, 
-		US_FL_SINGLE_LUN), 
-
-UNUSUAL_DEV(  0x04e6, 0x0007, 0x0100, 0x0200, 
-		"Sony",
-		"Hifd",
-		US_SC_SCSI, US_PR_CB, NULL, 
-		US_FL_SINGLE_LUN), 
-
-UNUSUAL_DEV(  0x04e6, 0x0009, 0x0200, 0x0200, 
-		"Shuttle",
-		"eUSB ATA/ATAPI Adapter",
-		US_SC_8020, US_PR_CB, NULL, 0),
-
-UNUSUAL_DEV(  0x04e6, 0x000a, 0x0200, 0x0200, 
-		"Shuttle",
-		"eUSB CompactFlash Adapter",
-		US_SC_8020, US_PR_CB, NULL, 0),
-
-UNUSUAL_DEV(  0x04e6, 0x000B, 0x0100, 0x0100, 
-		"Shuttle",
-		"eUSCSI Bridge",
-		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 
-		US_FL_SCM_MULT_TARG ), 
-
-UNUSUAL_DEV(  0x04e6, 0x000C, 0x0100, 0x0100, 
-		"Shuttle",
-		"eUSCSI Bridge",
-		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 
-		US_FL_SCM_MULT_TARG ), 
-
-UNUSUAL_DEV(  0x04e6, 0x0101, 0x0200, 0x0200, 
-		"Shuttle",
-		"CD-RW Device",
-		US_SC_8020, US_PR_CB, NULL, 0),
-
-/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
- * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
- * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
- */
-
-UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x0100,
-		"Kobian Mercury",
-		"Binocam DCB-132",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_BULK32),
-
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
-		"Shuttle/SCM",
-		"USBAT-02",
-		US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
-		US_FL_SINGLE_LUN),
-#endif
-
-/* Reported by Bob Sass <rls@vectordb.com> -- only rev 1.33 tested */
-UNUSUAL_DEV(  0x050d, 0x0115, 0x0133, 0x0133,
-		"Belkin",
-		"USB SCSI Adaptor",
-		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
-		US_FL_SCM_MULT_TARG ),
-
-/* Iomega Clik! Drive 
- * Reported by David Chatenay <dchatenay@hotmail.com>
- * The reason this is needed is not fully known.
- */
-UNUSUAL_DEV(  0x0525, 0xa140, 0x0100, 0x0100,
-		"Iomega",
-		"USB Clik! 40",
-		US_SC_8070, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* Yakumo Mega Image 37
- * Submitted by Stephan Fuhrmann <atomenergie@t-online.de> */
-UNUSUAL_DEV(  0x052b, 0x1801, 0x0100, 0x0100,
-		"Tekom Technologies, Inc",
-		"300_CAMERA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Another Yakumo camera.
- * Reported by Michele Alzetta <michele.alzetta@aliceposta.it> */
-UNUSUAL_DEV(  0x052b, 0x1804, 0x0100, 0x0100,
-		"Tekom Technologies, Inc",
-		"300_CAMERA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Iacopo Spalletti <avvisi@spalletti.it> */
-UNUSUAL_DEV(  0x052b, 0x1807, 0x0100, 0x0100,
-		"Tekom Technologies, Inc",
-		"300_CAMERA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Yakumo Mega Image 47
- * Reported by Bjoern Paetzel <kolrabi@kolrabi.de> */
-UNUSUAL_DEV(  0x052b, 0x1905, 0x0100, 0x0100,
-		"Tekom Technologies, Inc",
-		"400_CAMERA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Paul Ortyl <ortylp@3miasto.net>
- * Note that it's similar to the device above, only different prodID */
-UNUSUAL_DEV(  0x052b, 0x1911, 0x0100, 0x0100,
-		"Tekom Technologies, Inc",
-		"400_CAMERA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0450, 
-		"Sony",
-		"DSC-S30/S70/S75/505V/F505/F707/F717/P8", 
-		US_SC_SCSI, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
-
-/* Submitted by Lars Jacob <jacob.lars@googlemail.com>
- * This entry is needed because the device reports Sub=ff */
-UNUSUAL_DEV(  0x054c, 0x0010, 0x0500, 0x0610,
-		"Sony",
-		"DSC-T1/T5/H5",
-		US_SC_8070, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-
-/* Reported by wim@geeks.nl */
-UNUSUAL_DEV(  0x054c, 0x0025, 0x0100, 0x0100, 
-		"Sony",
-		"Memorystick NW-MS7",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV(  0x054c, 0x002b, 0x0100, 0x0110,
-		"Sony",
-		"Portable USB Harddrive V2",
-		US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-		0 ),
-#endif
-
-/* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */
-UNUSUAL_DEV(  0x054c, 0x002c, 0x0501, 0x0501,
-		"Sony",
-		"USB Floppy Drive",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV(  0x054c, 0x002d, 0x0100, 0x0100, 
-		"Sony",
-		"Memorystick MSAC-US1",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Submitted by Klaus Mueller <k.mueller@intershop.de> */
-UNUSUAL_DEV(  0x054c, 0x002e, 0x0106, 0x0310, 
-		"Sony",
-		"Handycam",
-		US_SC_SCSI, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Submitted by Rajesh Kumble Nayak <nayak@obs-nice.fr> */
-UNUSUAL_DEV(  0x054c, 0x002e, 0x0500, 0x0500, 
-		"Sony",
-		"Handycam HC-85",
-		US_SC_UFI, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV(  0x054c, 0x0032, 0x0000, 0x9999,
-		"Sony",
-		"Memorystick MSC-U01N",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Submitted by Michal Mlotek <mlotek@foobar.pl> */
-UNUSUAL_DEV(  0x054c, 0x0058, 0x0000, 0x9999,
-		"Sony",
-		"PEG N760c Memorystick",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-		
-UNUSUAL_DEV(  0x054c, 0x0069, 0x0000, 0x9999,
-		"Sony",
-		"Memorystick MSC-U03",
-		US_SC_UFI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Submitted by Nathan Babb <nathan@lexi.com> */
-UNUSUAL_DEV(  0x054c, 0x006d, 0x0000, 0x9999,
-		"Sony",
-		"PEG Mass Storage",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* Submitted by Mike Alborn <malborn@deandra.homeip.net> */
-UNUSUAL_DEV(  0x054c, 0x016a, 0x0000, 0x9999,
-		"Sony",
-		"PEG Mass Storage",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-		
-/* Submitted by Frank Engel <frankie@cse.unsw.edu.au> */
-UNUSUAL_DEV(  0x054c, 0x0099, 0x0000, 0x9999,
-                "Sony",
-                "PEG Mass Storage",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_FIX_INQUIRY ),
-
-		
-UNUSUAL_DEV(  0x057b, 0x0000, 0x0000, 0x0299, 
-		"Y-E Data",
-		"Flashbuster-U",
-		US_SC_DEVICE,  US_PR_CB, NULL,
-		US_FL_SINGLE_LUN),
-
-UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999, 
-		"Y-E Data",
-		"Flashbuster-U",
-		US_SC_DEVICE,  US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN),
-
-/* Reported by Johann Cardon <johann.cardon@free.fr>
- * This entry is needed only because the device reports
- * bInterfaceClass = 0xff (vendor-specific)
- */
-UNUSUAL_DEV(  0x057b, 0x0022, 0x0000, 0x9999, 
-		"Y-E Data",
-		"Silicon Media R/W",
-		US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
-
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV(  0x0584, 0x0008, 0x0102, 0x0102,
-		"Fujifilm",
-		"DPC-R1 (Alauda)",
- 		US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
-/* Fabrizio Fellini <fello@libero.it> */
-UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
-		"Fujifilm",
-		"Digital Camera EX-20 DSC",
-		US_SC_8070, US_PR_DEVICE, NULL, 0 ),
-
-/* The entry was here before I took over, and had US_SC_RBC. It turns
- * out that isn't needed. Additionally, Torsten Eriksson
- * <Torsten.Eriksson@bergianska.se> is able to use his device fine
- * without this entry at all - but I don't suspect that will be true
- * for all users (the protocol is likely needed), so is staying at
- * this time. - Phil Dibowitz <phil@ipom.com>
- */
-UNUSUAL_DEV(  0x059f, 0xa601, 0x0200, 0x0200, 
-		"LaCie",
-		"USB Hard Disk",
-		US_SC_DEVICE, US_PR_CB, NULL, 0 ),
-
-/* Submitted by Joel Bourquard <numlock@freesurf.ch>
- * Some versions of this device need the SubClass and Protocol overrides
- * while others don't.
- */
-UNUSUAL_DEV(  0x05ab, 0x0060, 0x1104, 0x1110,
-		"In-System",
-		"PyroGate External CD-ROM Enclosure (FCD-523)",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_NEED_OVERRIDE ),
-
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV(  0x05ab, 0x0031, 0x0100, 0x0110,
-		"In-System",
-		"USB/IDE Bridge (ATA/ATAPI)",
-		US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-		0 ),
-
-UNUSUAL_DEV(  0x05ab, 0x0301, 0x0100, 0x0110,
-		"In-System",
-		"Portable USB Harddrive V2",
-		US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-		0 ),
-
-UNUSUAL_DEV(  0x05ab, 0x0351, 0x0100, 0x0110,
-		"In-System",
-		"Portable USB Harddrive V2",
-		US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-		0 ),
-
-UNUSUAL_DEV(  0x05ab, 0x5701, 0x0100, 0x0110,
-		"In-System",
-		"USB Storage Adapter V2",
-		US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-		0 ),
-#endif
-
-/* Submitted by Sven Anderson <sven-linux@anderson.de>
- * There are at least four ProductIDs used for iPods, so I added 0x1202 and
- * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears
- * to change with firmware updates, I changed the range to maximum for all
- * iPod entries.
- */
-UNUSUAL_DEV( 0x05ac, 0x1202, 0x0000, 0x9999,
-		"Apple",
-		"iPod",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-/* Reported by Avi Kivity <avi@argo.co.il> */
-UNUSUAL_DEV( 0x05ac, 0x1203, 0x0000, 0x9999,
-		"Apple",
-		"iPod",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-UNUSUAL_DEV( 0x05ac, 0x1204, 0x0000, 0x9999,
-		"Apple",
-		"iPod",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999,
-		"Apple",
-		"iPod",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-/*
- * Reported by Tyson Vinson <lornoss@gmail.com>
- * This particular productId is the iPod Nano
- */
-UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999,
-		"Apple",
-		"iPod",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-UNUSUAL_DEV(  0x05dc, 0x0001, 0x0000, 0x0001,
-		"Lexar",
-		"Jumpshot USB CF Reader",
-		US_SC_SCSI, US_PR_JUMPSHOT, NULL,
-		US_FL_NEED_OVERRIDE ),
-#endif
-
-/* Reported by Blake Matheny <bmatheny@purdue.edu> */
-UNUSUAL_DEV(  0x05dc, 0xb002, 0x0000, 0x0113,
-		"Lexar",
-		"USB CF Reader",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* The following two entries are for a Genesys USB to IDE
- * converter chip, but it changes its ProductId depending
- * on whether or not a disk or an optical device is enclosed
- * They were originally reported by Alexander Oltu
- * <alexander@all-2.com> and Peter Marks <peter.marks@turner.com>
- * respectively.
- *
- * US_FL_GO_SLOW and US_FL_MAX_SECTORS_64 added by Phil Dibowitz
- * <phil@ipom.com> as these flags were made and hard-coded
- * special-cases were pulled from scsiglue.c.
- */
-UNUSUAL_DEV(  0x05e3, 0x0701, 0x0000, 0xffff,
-		"Genesys Logic",
-		"USB to IDE Optical",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
-
-UNUSUAL_DEV(  0x05e3, 0x0702, 0x0000, 0xffff,
-		"Genesys Logic",
-		"USB to IDE Disk",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
-
-/* Reported by Hanno Boeck <hanno@gmx.de>
- * Taken from the Lycoris Kernel */
-UNUSUAL_DEV(  0x0636, 0x0003, 0x0000, 0x9999,
-		"Vivitar",
-		"Vivicam 35Xx",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_FIX_INQUIRY ),
-
-UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100, 
-		"TEAC",
-		"Floppy Drive",
-		US_SC_UFI, US_PR_CB, NULL, 0 ), 
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100, 
-		"Olympus",
-		"Camedia MAUSB-2",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
-		0),
-#endif
-
-/* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
-UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
-		"SigmaTel",
-		"USBMSC Audio Player",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-/* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */
-UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100,
-		"Prolific Technology Inc.",
-		"Mass Storage Device",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY | US_FL_GO_SLOW ),
-
-/* Reported by Alex Butcher <alex.butcher@assursys.co.uk> */
-UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001,
-		"Prolific Technology Inc.",
-		"ATAPI-6 Bridge Controller",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY | US_FL_GO_SLOW ),
-
-/* Submitted by Benny Sjostrand <benny@hostmobility.com> */
-UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
-		"Minolta",
-		"Dimage F300",
-		US_SC_SCSI, US_PR_BULK, NULL, 0 ),
-
-/* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
-UNUSUAL_DEV(  0x0686, 0x4017, 0x0001, 0x0001,
-                "Minolta",
-                "DIMAGE E223",
-                US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
-
-UNUSUAL_DEV(  0x0693, 0x0005, 0x0100, 0x0100,
-		"Hagiwara",
-		"Flashgate",
-		US_SC_SCSI, US_PR_BULK, NULL, 0 ), 
-
-/* Reported by David Hamilton <niftimusmaximus@lycos.com> */
-UNUSUAL_DEV(  0x069b, 0x3004, 0x0001, 0x0001,
-		"Thomson Multimedia Inc.",
-		"RCA RD1080 MP3 Player",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-/* Reported by Olivier Blondeau <zeitoun@gmail.com> */
-UNUSUAL_DEV(  0x0727, 0x0306, 0x0100, 0x0100,
-		"ATMEL",
-		"SND1 Storage",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE),
-
-/* Submitted by Roman Hodek <roman@hodek.net> */
-UNUSUAL_DEV(  0x0781, 0x0001, 0x0200, 0x0200,
-		"Sandisk",
-		"ImageMate SDDR-05a",
-		US_SC_SCSI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV(  0x0781, 0x0002, 0x0009, 0x0009,
-		"SanDisk Corporation",
-		"ImageMate CompactFlash USB",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x0781, 0x0005, 0x0005, 0x0005,
-		"Sandisk",
-		"ImageMate SDDR-05b",
-		US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
-		US_FL_SINGLE_LUN ),
-#endif
-
-UNUSUAL_DEV(  0x0781, 0x0100, 0x0100, 0x0100,
-		"Sandisk",
-		"ImageMate SDDR-12",
-		US_SC_SCSI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN ),
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999, 
-		"Sandisk",
-		"ImageMate SDDR-09",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
-		0),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-UNUSUAL_DEV(  0x07ab, 0xfc01, 0x0000, 0x9999,
-		"Freecom",
-		"USB-IDE",
-		US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
-#endif
-
-/* Reported by Eero Volotinen <eero@ping-viini.org> */
-UNUSUAL_DEV(  0x07ab, 0xfccd, 0x0000, 0x9999,
-		"Freecom Technologies",
-		"FHD-Classic",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY),
-
-UNUSUAL_DEV(  0x07af, 0x0004, 0x0100, 0x0133, 
-		"Microtech",
-		"USB-SCSI-DB25",
-		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
-		US_FL_SCM_MULT_TARG ), 
-
-UNUSUAL_DEV(  0x07af, 0x0005, 0x0100, 0x0100, 
-		"Microtech",
-		"USB-SCSI-HD50",
-		US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
-		US_FL_SCM_MULT_TARG ), 
-
-#ifdef CONFIG_USB_STORAGE_DPCM
-UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
-		"Microtech",
-		"CameraMate (DPCM_USB)",
- 		US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV(  0x07b4, 0x010a, 0x0102, 0x0102,
-		"Olympus",
-		"MAUSB-10 (Alauda)",
- 		US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV(  0x07c4, 0xa000, 0x0000, 0x0015,
-		"Datafab",
-		"MDCFE-B USB CF Reader",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-
-/*
- * The following Datafab-based devices may or may not work
- * using the current driver...the 0xffff is arbitrary since I
- * don't know what device versions exist for these guys.
- *
- * The 0xa003 and 0xa004 devices in particular I'm curious about.
- * I'm told they exist but so far nobody has come forward to say that
- * they work with this driver.  Given the success we've had getting
- * other Datafab-based cards operational with this driver, I've decided
- * to leave these two devices in the list.
- */
-UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
-		"SIIG/Datafab",
-		"SIIG/Datafab Memory Stick+CF Reader/Writer",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-
-/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
-UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
-		"Datafab/Unknown",
-		"MD2/MD3 Disk enclosure",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
-		"Datafab/Unknown",
-		"Datafab-based Reader",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
-		"Datafab/Unknown",
-		"Datafab-based Reader",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
-		"PNY/Datafab",
-		"PNY/Datafab CF+SM Reader",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
-		"Simple Tech/Datafab",
-		"Simple Tech/Datafab CF+SM Reader",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-#endif
-		
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* Contributed by Peter Waechtler */
-UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
-		"Datafab",
-		"MDSM-B reader",
-		US_SC_SCSI, US_PR_SDDR55, NULL,
-		US_FL_FIX_INQUIRY ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Submitted by Olaf Hering <olh@suse.de> */
-UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
-		"Datafab Systems, Inc.",
-		"USB to CF + SM Combo (LC1)",
-		US_SC_SCSI, US_PR_DATAFAB, NULL,
-		0 ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* SM part - aeb <Andries.Brouwer@cwi.nl> */
-UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
-		"Datafab Systems, Inc.",
-		"USB to CF + SM Combo (LC1)",
-		US_SC_SCSI, US_PR_SDDR55, NULL,
-		US_FL_SINGLE_LUN ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Reported by Felix Moeller <felix@derklecks.de>
- * in Germany this is sold by Hama with the productnumber 46952
- * as "DualSlot CompactFlash(TM) & MStick Drive USB"
- */
-UNUSUAL_DEV(  0x07c4, 0xa10b, 0x0000, 0xffff,
-                "DataFab Systems Inc.",
-                "USB CF+MS",
-                US_SC_SCSI, US_PR_DATAFAB, NULL,
-                0 ),
-
-#endif
-
-/* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
- * Only revision 1.13 tested (same for all of the above devices,
- * based on the Datafab DF-UG-07 chip).  Needed for US_FL_FIX_INQUIRY.
- * Submitted by Marek Michalkiewicz <marekm@amelek.gda.pl>.
- * See also http://martin.wilck.bei.t-online.de/#kecf .
- */
-UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0xffff,
-		"Datafab",
-		"KECF-USB",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
- * to the USB storage specification in two ways:
- * - They tell us they are using transport protocol CBI. In reality they
- *   are using transport protocol CB.
- * - They don't like the INQUIRY command. So we must handle this command
- *   of the SCSI layer ourselves.
- * - Some cameras with idProduct=0x1001 and bcdDevice=0x1000 have
- *   bInterfaceProtocol=0x00 (US_PR_CBI) while others have 0x01 (US_PR_CB).
- *   So don't remove the US_PR_CB override!
- * - Cameras with bcdDevice=0x9009 require the US_SC_8070 override.
- */
-UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999,
-		"Casio",
-		"QV DigitalCamera",
-		US_SC_8070, US_PR_CB, NULL,
-		US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ),
-
-/* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/
-UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
-		"Samsung",
-		"Digimax 410",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY),
-
-/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
- * Flag will support Bulk devices which use a standards-violating 32-byte
- * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
- * Grandtech GT892x chip, which request "Proprietary SCSI Bulk" support.
- */
-
-UNUSUAL_DEV(  0x084d, 0x0011, 0x0110, 0x0110,
-		"Grandtech",
-		"DC2MEGA",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_BULK32),
-
-/* Submitted by Jan De Luyck <lkml@kcore.org> */
-UNUSUAL_DEV(  0x08bd, 0x1100, 0x0000, 0x0000,
-		"CITIZEN",
-		"X1DE-USB",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN),
-
-/* Entry needed for flags. Moreover, all devices with this ID use
- * bulk-only transport, but _some_ falsely report Control/Bulk instead.
- * One example is "Trumpion Digital Research MYMP3".
- * Submitted by Bjoern Brill <brill(at)fs.math.uni-frankfurt.de>
- */
-UNUSUAL_DEV(  0x090a, 0x1001, 0x0100, 0x0100,
-		"Trumpion",
-		"t33520 USB Flash Card Controller",
-		US_SC_DEVICE, US_PR_BULK, NULL,
-		US_FL_NEED_OVERRIDE ),
-
-/* Reported by Filippo Bardelli <filibard@libero.it>
- * The device reports a subclass of RBC, which is wrong.
- */
-UNUSUAL_DEV(  0x090a, 0x1050, 0x0100, 0x0100,
-		"Trumpion Microelectronics, Inc.",
-		"33520 USB Digital Voice Recorder",
-		US_SC_UFI, US_PR_DEVICE, NULL,
-		0),
-
-/* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */
-UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
-		"Trumpion",
-		"MP3 player",
-		US_SC_RBC, US_PR_BULK, NULL,
-		0 ),
-
-/* aeb */
-UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
-		"Feiya",
-		"5-in-1 Card Reader",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
-/* This Pentax still camera is not conformant
- * to the USB storage specification: -
- * - It does not like the INQUIRY command. So we must handle this command
- *   of the SCSI layer ourselves.
- * Tested on Rev. 10.00 (0x1000)
- * Submitted by James Courtier-Dutton <James@superbug.demon.co.uk>
- */
-UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
-                "Pentax",
-                "Optio 2/3/400",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_FIX_INQUIRY ),
-
-
-/* Submitted by Per Winkvist <per.winkvist@uk.com> */
-UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
-                "Pentax",
-                "Optio S/S4",
-                US_SC_DEVICE, US_PR_DEVICE, NULL,
-                US_FL_FIX_INQUIRY ),
-		
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
-		"ATI",
-		"USB Cable 205",
-		US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-		0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
-	       "Acomdata",
-	       "CF",
-	       US_SC_SCSI, US_PR_DATAFAB, NULL,
-	       US_FL_SINGLE_LUN ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
-	       "Acomdata",
-	       "SM",
-	       US_SC_SCSI, US_PR_SDDR55, NULL,
-	       US_FL_SINGLE_LUN ),
-#endif
-
-/* Submitted by: Nick Sillik <n.sillik@temple.edu>
- * Needed for OneTouch extension to usb-storage
- *
- */
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
-	UNUSUAL_DEV(  0x0d49, 0x7000, 0x0000, 0x9999,
-			"Maxtor",
-			"OneTouch External Harddrive",
-			US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
-			0),
-	UNUSUAL_DEV(  0x0d49, 0x7010, 0x0000, 0x9999,
-			"Maxtor",
-			"OneTouch External Harddrive",
-			US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
-			0),
-#endif
-
-/*
- * Pete Zaitcev <zaitcev@yahoo.com>, bz#164688.
- * The device blatantly ignores LUN and returns 1 in GetMaxLUN.
- */
-UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100,
-		"Unknown",
-		"Unknown",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_SINGLE_LUN ),
-
-/* Submitted by Joris Struyve <joris@struyve.be> */
-UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
-		"Medion",
-		"MD 7425",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY),
-
-/*
- * Entry for Jenoptik JD 5200z3
- *
- * email: car.busse@gmx.de
- */
-UNUSUAL_DEV(  0x0d96, 0x5200, 0x0001, 0x0200,
-		"Jenoptik",
-		"JD 5200 z3",
-		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY),
-
-/* Reported by Lubomir Blaha <tritol@trilogic.cz>
- * I _REALLY_ don't know what 3rd, 4th number and all defines mean, but this
- * works for me. Can anybody correct these values? (I able to test corrected
- * version.)
- */
-UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff,
-		"Netac",
-		"USB-CF-Card",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* Patch by Stephan Walter <stephan.walter@epfl.ch>
- * I don't know why, but it works... */
-UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012,
-		"WINWARD",
-		"Music Disk",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Ian McConnell <ian at emit.demon.co.uk> */
-UNUSUAL_DEV(  0x0dda, 0x0301, 0x0012, 0x0012,
-		"PNP_MP3",
-		"PNP_MP3 PLAYER",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Jim McCloskey <mcclosk@ucsc.edu> */
-UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100,
-		"Cowon Systems",
-		"iAUDIO M5",
-		US_SC_DEVICE, US_PR_BULK, NULL,
-		0 ),
-
-/* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */
-UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300,
-		"USB",
-		"Solid state disk",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
-/* Submitted by Daniel Drake <dsd@gentoo.org>
- * Reported by dayul on the Gentoo Forums */
-UNUSUAL_DEV(  0x0ea0, 0x2168, 0x0110, 0x0110,
-		"Ours Technology",
-		"Flash Disk",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Rastislav Stanik <rs_kernel@yahoo.com> */
-UNUSUAL_DEV(  0x0ea0, 0x6828, 0x0110, 0x0110,
-		"USB",
-		"Flash Disk",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Benjamin Schiller <sbenni@gmx.de>
- * It is also sold by Easylite as DJ 20 */
-UNUSUAL_DEV(  0x0ed1, 0x7636, 0x0103, 0x0103,
-		"Typhoon",
-		"My DJ 1820",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
-
-/* Reported by Michael Stattmann <michael@stattmann.com> */
-UNUSUAL_DEV(  0x0fce, 0xd008, 0x0000, 0x0000,
-		"Sony Ericsson",
-		"V800-Vodafone 802",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_NO_WP_DETECT ),
-
-/* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
- * Tested on hardware version 1.10.
- * Entry is needed only for the initializer function override.
- */
-UNUSUAL_DEV(  0x1019, 0x0c55, 0x0000, 0x9999,
-		"Desknote",
-		"UCR-61S2B",
-		US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
-		0 ),
-
-/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
-UNUSUAL_DEV(  0x132b, 0x000b, 0x0001, 0x0001,
-		"Minolta",
-		"Dimage Z10",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		0 ),
-
-/* Reported by Kotrla Vitezslav <kotrla@ceb.cz> */
-UNUSUAL_DEV(  0x1370, 0x6828, 0x0110, 0x0110,
-		"SWISSBIT",
-		"Black Silver",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
-/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
- * and Renato Perini <rperini@email.it>
- */
-UNUSUAL_DEV(  0x22b8, 0x3010, 0x0001, 0x0001,
-		"Motorola",
-		"RAZR V3x",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
-
-/* Reported by Radovan Garabik <garabik@kassiopeia.juls.savba.sk> */
-UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
-		"MPIO",
-		"HS200",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_GO_SLOW ),
-
-/*
- * David Härdeman <david@2gen.com>
- * The key makes the SCSI stack print confusing (but harmless) messages
- */
-UNUSUAL_DEV(  0x4146, 0xba01, 0x0100, 0x0100,
-		"Iomega",
-		"Micro Mini 1GB",
-		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
-
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV(  0x55aa, 0xa103, 0x0000, 0x9999, 
-		"Sandisk",
-		"ImageMate SDDR55",
-		US_SC_SCSI, US_PR_SDDR55, NULL,
-		US_FL_SINGLE_LUN),
-#endif
-
-/* Reported by Andrew Simmons <andrew.simmons@gmail.com> */
-UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001,
-		"DataStor",
-		"USB4500 FW1.04",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY),
-
-/* Control/Bulk transport for all SubClass values */
-USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR),
-
-/* Control/Bulk/Interrupt transport for all SubClass values */
-USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR),
-
-/* Bulk-only transport for all SubClass values */
-USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR),
-USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0),
diff -urN newtree/drivers/video/Kconfig newtree.2/drivers/video/Kconfig
--- newtree/drivers/video/Kconfig	2006-08-04 10:03:06.000000000 -0700
+++ newtree.2/drivers/video/Kconfig	2006-08-04 14:09:00.000000000 -0700
@@ -541,8 +541,22 @@
 	  cards. Say Y if you have one of those.
 
 config FB_VESA
-	bool "VESA VGA graphics support"
-	depends on (FB = y) && X86 && !VGA_NOPROBE
+        tristate "VESA VGA graphics support"
+        depends on (FB = y) && (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.
+
+choice
+        prompt "VESA driver type"
+        depends on FB_VESA
+        default FB_VESA_STD if X86_64
+        default FB_VESA_TNG if X86
+
+config FB_VESA_STD
+        bool "vesafb"
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
@@ -550,7 +564,43 @@
 	  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.
+	  read <file:Documentation/fb/vesafb.txt>. Choose this driver if you
+	  are experiencing problems with vesafb-tng or if you own a 64-bit system.
+
+	  Note that this driver cannot be compiled as a module.
+
+config FB_VESA_TNG
+	bool "vesafb-tng"
+	depends on !X86_64
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for generic VESA 2.0 
+	  compliant graphic cards. It is capable of taking advantage of 
+	  VBE 3.0 features. With this driver you will be able to adjust
+	  the refresh rate (VBE 3.0 compliant boards only) and change
+	  the graphic mode on-the-fly.
+	  
+	  You will also get a boot time penguin logo at no additional cost. Please
+	  read <file:Documentation/fb/vesafb.txt>.
+
+endchoice
+
+config FB_VESA_DEFAULT_MODE
+	string "VESA default mode"
+	depends on FB_VESA_TNG
+	default "640x480@60"
+	help 
+	  This option is used to determine the default mode vesafb is
+	  supposed to switch to in case no mode is provided as a kernel
+	  command line parameter.
+
+config VIDEO_SELECT
+	bool
+	depends on FB_VESA
+	default y
 
 config FB_IMAC
 	bool "Intel-based Macintosh Framebuffer Support"
diff -urN newtree/drivers/video/fbmem.c newtree.2/drivers/video/fbmem.c
--- newtree/drivers/video/fbmem.c	2006-08-02 07:14:21.000000000 -0700
+++ newtree.2/drivers/video/fbmem.c	2006-08-04 14:07:26.000000000 -0700
@@ -1407,6 +1407,7 @@
 		printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
 		fb_class = NULL;
 	}
+
 	return 0;
 }
 
diff -urN newtree/drivers/video/modedb.c newtree.2/drivers/video/modedb.c
--- newtree/drivers/video/modedb.c	2006-07-15 14:53:08.000000000 -0700
+++ newtree.2/drivers/video/modedb.c	2006-08-04 14:07:26.000000000 -0700
@@ -674,6 +674,7 @@
 {
 	u32 pixclock, hfreq, htotal, vtotal;
 
+	mode->refresh = 0;
 	mode->name = NULL;
 	mode->xres = var->xres;
 	mode->yres = var->yres;
@@ -1025,3 +1026,4 @@
 EXPORT_SYMBOL(fb_find_nearest_mode);
 EXPORT_SYMBOL(fb_videomode_to_modelist);
 EXPORT_SYMBOL(fb_find_mode);
+EXPORT_SYMBOL(fb_destroy_modelist);
diff -urN newtree/drivers/video/vesafb-thread.c newtree.2/drivers/video/vesafb-thread.c
--- newtree/drivers/video/vesafb-thread.c	1969-12-31 16:00:00.000000000 -0800
+++ newtree.2/drivers/video/vesafb-thread.c	2006-08-04 14:07:26.000000000 -0700
@@ -0,0 +1,727 @@
+/*
+ * Framebuffer driver for VBE 2.0+ compliant graphic boards.
+ * Kernel thread and vm86 routines.
+ *
+ * (c) 2004-2006 Michal Januszewski <spock@gentoo.org>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/signal.h>
+#include <linux/suspend.h>
+#include <linux/unistd.h>
+#include <video/vesa.h>
+#include <video/edid.h>
+#include <asm/mman.h>
+#include <asm/page.h>
+#include <asm/vm86.h>
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include "edid.h"
+
+#ifdef MODULE
+int errno;
+#endif
+
+static DECLARE_COMPLETION(vesafb_th_completion);
+static DECLARE_MUTEX(vesafb_task_list_sem);
+static LIST_HEAD(vesafb_task_list);
+static DECLARE_WAIT_QUEUE_HEAD(vesafb_wait);
+
+static struct vm86_struct vm86;
+static int vesafb_pid = 0;
+
+_syscall3(int,ioperm,unsigned long, a, unsigned long, b, unsigned long, c);
+_syscall1(int,vm86old,struct vm86_struct __user*, v86);
+
+#define DEFAULT_VM86_FLAGS (IF_MASK | IOPL_MASK)
+#define VM86_PUSHW(x)					\
+do { 							\
+	vm86.regs.esp -= 2; 				\
+	*(u16*)(STACK_ADDR + vm86.regs.esp) = x;	\
+} while(0);
+
+/* Stack, the return code and buffers will be put into
+ * one contiguous memory chunk:
+ *
+ * [ STACK | RET_CODE | BUFFER ]
+ *
+ * Some video BIOSes (sis6326) try to store data somewhere
+ * in 0x7000-0x7fff, so we zeromap more memory to be safe.
+ */
+#define IVTBDA_SIZE 	PAGE_SIZE
+#define RET_CODE_SIZE	0x0010
+#define STACK_SIZE	0x0500
+#define BUFFER_SIZE	0x10000
+
+/* The amount of memory that will be allocated should be a multiple
+ * of PAGE_SIZE. */
+#define __MEM_SIZE 	(RET_CODE_SIZE + STACK_SIZE + BUFFER_SIZE)
+#define REAL_MEM_SIZE	(((__MEM_SIZE / PAGE_SIZE) + 1) * PAGE_SIZE)
+
+#define IVTBDA_ADDR	0x00000
+#define STACK_ADDR	(IVTBDA_ADDR + IVTBDA_SIZE)
+#define RET_CODE_ADDR	(STACK_ADDR + STACK_SIZE)
+#define BUF_ADDR	(RET_CODE_ADDR + RET_CODE_SIZE)
+
+#define FLAG_D 		(1 << 10)
+
+/* Segment prefix opcodes */
+enum {
+	P_CS = 0x2e,
+	P_SS = 0x36,
+	P_DS = 0x3e,
+	P_ES = 0x26,
+	P_FS = 0x64,
+	P_GS = 0x65
+};
+
+/* Emulated vm86 ins instruction */
+static void vm86_ins(int size)
+{
+	u32 edx, edi;
+	edx = vm86.regs.edx & 0xffff;
+	edi = (vm86.regs.edi & 0xffff) + (u32)(vm86.regs.es << 4);
+
+	if (vm86.regs.eflags & FLAG_D)
+		asm volatile ("std\n");
+	else
+		asm volatile ("cld\n");
+
+	switch (size) {
+	case 4:
+		asm volatile ("insl\n" : "=D" (edi) : "d" (edx), "0" (edi));
+		break;
+	case 2:
+		asm volatile ("insw\n" : "=D" (edi) : "d" (edx), "0" (edi));
+		break;
+	case 1:
+		asm volatile ("insb\n" : "=D" (edi) : "d" (edx), "0" (edi));
+		break;
+	}
+
+	if (vm86.regs.eflags & FLAG_D)
+		asm volatile ("cld\n");
+
+	edi -= (u32)(vm86.regs.es << 4);
+
+	vm86.regs.edi &= 0xffff0000;
+	vm86.regs.edi |= edi & 0xffff;
+}
+
+static void vm86_rep_ins(int size)
+{
+	u16 cx = vm86.regs.ecx;
+	while (cx--)
+		vm86_ins(size);
+
+	vm86.regs.ecx &= 0xffff0000;
+}
+
+/* Emulated vm86 outs instruction */
+static void vm86_outs(int size, int segment)
+{
+	u32 edx, esi, base;
+
+	edx = vm86.regs.edx & 0xffff;
+	esi = vm86.regs.esi & 0xffff;
+
+	switch (segment) {
+	case P_CS: base = vm86.regs.cs; break;
+	case P_SS: base = vm86.regs.ss; break;
+	case P_ES: base = vm86.regs.es; break;
+	case P_FS: base = vm86.regs.fs; break;
+	case P_GS: base = vm86.regs.gs; break;
+	default:   base = vm86.regs.ds; break;
+	}
+
+	esi += base << 4;
+
+	if (vm86.regs.eflags & FLAG_D)
+		asm volatile ("std\n");
+	else
+		asm volatile ("cld\n");
+
+	switch (size) {
+	case 4:
+		asm volatile ("outsl\n" : "=S" (esi) : "d" (edx), "0" (esi));
+		break;
+	case 2:
+		asm volatile ("outsw\n" : "=S" (esi) : "d" (edx), "0" (esi));
+		break;
+	case 1:
+		asm volatile ("outsb\n" : "=S" (esi) : "d" (edx), "0" (esi));
+		break;
+	}
+
+	if (vm86.regs.eflags & FLAG_D)
+		asm volatile ("cld");
+
+	esi -= base << 4;
+	vm86.regs.esi &= 0xffff0000;
+	vm86.regs.esi |= (esi & 0xffff);
+}
+
+static void vm86_rep_outs(int size, int segment)
+{
+	u16 cx = vm86.regs.ecx;
+	while (cx--)
+		vm86_outs(size, segment);
+
+	vm86.regs.ecx &= 0xffff0000;
+}
+
+static int vm86_do_unknown(void)
+{
+	u8 data32 = 0, segment = P_DS, rep = 0;
+	u8 *instr;
+	int ret = 0, i = 0;
+
+	instr = (u8*)((vm86.regs.cs << 4) + vm86.regs.eip);
+
+	while (1) {
+		switch(instr[i]) {
+		case 0x66:	/* operand size prefix */
+			data32 = 1 - data32;
+			i++;
+			break;
+		case 0xf2:	/* repnz */
+		case 0xf3:	/* rep */
+			rep = 1;
+			i++;
+			break;
+		case P_CS:	/* segment prefix */
+		case P_SS:
+		case P_DS:
+		case P_ES:
+		case P_FS:
+		case P_GS:
+			segment = instr[i];
+			i++;
+			break;
+		case 0xf0:	/* LOCK - ignored */
+		case 0x67:	/* address size prefix - ignored */
+			i++;
+			break;
+		case 0x6c:	/* insb */
+			if (rep)
+				vm86_rep_ins(1);
+			else
+				vm86_ins(1);
+			i++;
+			goto out;
+		case 0x6d:	/* insw / insd */
+			if (rep) {
+				if (data32)
+					vm86_rep_ins(4);
+				else
+					vm86_rep_ins(2);
+			} else {
+				if (data32)
+					vm86_ins(4);
+				else
+					vm86_ins(2);
+			}
+			i++;
+			goto out;
+		case 0x6e:	/* outsb */
+			if (rep)
+				vm86_rep_outs(1, segment);
+			else
+				vm86_outs(1, segment);
+			i++;
+			goto out;
+		case 0x6f:	/* outsw / outsd */
+			if (rep) {
+				if (data32)
+					vm86_rep_outs(4, segment);
+				else
+					vm86_rep_outs(2, segment);
+			} else {
+				if (data32)
+					vm86_outs(4, segment);
+				else
+					vm86_outs(2, segment);
+			}
+			i++;
+			goto out;
+		case 0xe4:	/* inb xx */
+			asm volatile (
+				"inb %w1, %b0"
+				: "=a" (vm86.regs.eax)
+				: "d" (instr[i+1]), "0" (vm86.regs.eax));
+			i += 2;
+			goto out;
+		case 0xe5:	/* inw xx / ind xx */
+			if (data32) {
+				asm volatile (
+					"inl %w1, %0"
+					: "=a" (vm86.regs.eax)
+					: "d" (instr[i+1]),
+					  "0" (vm86.regs.eax));
+			} else {
+				asm volatile (
+					"inw %w1, %w0"
+					: "=a" (vm86.regs.eax)
+					: "d" (instr[i+1]),
+					  "0" (vm86.regs.eax));
+			}
+			i += 2;
+			goto out;
+
+		case 0xec:	/* inb dx */
+			asm volatile (
+				"inb %w1, %b0"
+	 			: "=a" (vm86.regs.eax)
+				: "d" (vm86.regs.edx), "0" (vm86.regs.eax));
+			i++;
+			goto out;
+		case 0xed:	/* inw dx / ind dx */
+			if (data32) {
+				asm volatile (
+					"inl %w1, %0"
+					: "=a" (vm86.regs.eax)
+					: "d" (vm86.regs.edx));
+			} else {
+				asm volatile (
+					"inw %w1, %w0"
+					: "=a" (vm86.regs.eax)
+					: "d" (vm86.regs.edx));
+			}
+			i++;
+			goto out;
+		case 0xe6:	/* outb xx */
+			asm volatile (
+				"outb %b0, %w1"
+				: /* no return value */
+				: "a" (vm86.regs.eax), "d" (instr[i+1]));
+			i += 2;
+			goto out;
+		case 0xe7:	/* outw xx / outd xx */
+			if (data32) {
+				asm volatile (
+					"outl %0, %w1"
+					: /* no return value */
+					: "a" (vm86.regs.eax),
+					  "d" (instr[i+1]));
+			} else {
+				asm volatile (
+					"outw %w0, %w1"
+					: /* no return value */
+					: "a" (vm86.regs.eax),
+					  "d" (instr[i+1]));
+			}
+			i += 2;
+			goto out;
+		case 0xee:	/* outb dx */
+			asm volatile (
+				"outb %b0, %w1"
+				: /* no return value */
+				: "a" (vm86.regs.eax), "d" (vm86.regs.edx));
+			i++;
+			goto out;
+		case 0xef:	/* outw dx / outd dx */
+			if (data32) {
+				asm volatile (
+					"outl %0, %w1"
+					: /* no return value */
+					: "a" (vm86.regs.eax),
+					  "d" (vm86.regs.edx));
+			} else {
+				asm volatile (
+					"outw %w0, %w1"
+					: /* no return value */
+					: "a" (vm86.regs.eax),
+					  "d" (vm86.regs.edx));
+			}
+			i++;
+			goto out;
+		default:
+			printk(KERN_ERR "vesafb: BUG, opcode 0x%x emulation "
+					"not supported (EIP: 0x%lx)\n",
+					instr[i], (u32)(vm86.regs.cs << 4) +
+					vm86.regs.eip);
+			ret = 1;
+			goto out;
+		}
+	}
+out: 	vm86.regs.eip += i;
+	return ret;
+}
+
+void vesafb_do_vm86(struct vm86_regs *regs)
+{
+	unsigned int ret;
+	u8 *retcode = (void*)RET_CODE_ADDR;
+
+	memset(&vm86,0,sizeof(vm86));
+	memcpy(&vm86.regs, regs, sizeof(struct vm86_regs));
+
+	/* The return code */
+	retcode[0] = 0xcd;  		/* int opcode */
+	retcode[1] = 0xff;		/* int number (255) */
+
+        /* We use int 0xff to get back to protected mode */
+	memset(&vm86.int_revectored, 0, sizeof(vm86.int_revectored));
+        ((unsigned char *)&vm86.int_revectored)[0xff / 8] |= (1 << (0xff % 8));
+
+	/*
+	 * We want to call int 0x10, so we set:
+	 *   CS = 0x42 = 0x10 * 4 + 2
+	 *   IP = 0x40 = 0x10 * 4
+	 * and SS:ESP. It's up to the caller to set the rest of the registers.
+	 */
+	vm86.regs.eflags = DEFAULT_VM86_FLAGS;
+	vm86.regs.cs = *(unsigned short *)0x42;
+	vm86.regs.eip = *(unsigned short *)0x40;
+	vm86.regs.ss = (STACK_ADDR >> 4);
+	vm86.regs.esp = ((STACK_ADDR & 0x0000f) + STACK_SIZE);
+
+	/* These will be fetched off the stack when we come to an iret in the
+	 * int's 0x10 code. */
+	VM86_PUSHW(DEFAULT_VM86_FLAGS);
+	VM86_PUSHW((RET_CODE_ADDR >> 4));	/* return code segment */
+	VM86_PUSHW((RET_CODE_ADDR & 0x0000f));	/* return code offset */
+
+	while(1) {
+		ret = vm86old(&vm86);
+
+		if (VM86_TYPE(ret) == VM86_INTx) {
+			int vint = VM86_ARG(ret);
+
+			/* If exit from vm86 was caused by int 0xff, then
+			 * we're done.. */
+			if (vint == 0xff)
+				goto out;
+
+			/* .. otherwise, we have to call the int handler
+			 * manually */
+			VM86_PUSHW(vm86.regs.eflags);
+			VM86_PUSHW(vm86.regs.cs);
+			VM86_PUSHW(vm86.regs.eip);
+
+			vm86.regs.cs = *(u16 *)((vint << 2) + 2);
+			vm86.regs.eip = *(u16 *)(vint << 2);
+			vm86.regs.eflags &= ~(VIF_MASK | TF_MASK);
+		} else if (VM86_TYPE(ret) == VM86_UNKNOWN) {
+			if (vm86_do_unknown())
+				goto out;
+		} else {
+			printk(KERN_ERR "vesafb: BUG, returned from "
+					"vm86 with %x (EIP: 0x%lx)\n",
+					ret, (u32)(vm86.regs.cs << 4) +
+					vm86.regs.eip);
+			goto out;
+		}
+	}
+
+out:	/* copy the registers' state back to the caller's struct */
+	memcpy(regs, &vm86.regs, sizeof(struct vm86_regs));
+}
+
+static int vesafb_remap_pfn_range(unsigned long start, unsigned long end,
+				  unsigned long pgoff, unsigned long prot,
+				  int type)
+{
+	struct vm_area_struct *vma;
+	struct mm_struct *mm = current->mm;
+	int ret = 0;
+
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!vma)
+		return -ENOMEM;
+	memset(vma, 0, sizeof(*vma));
+	down_write(&mm->mmap_sem);
+	vma->vm_mm = mm;
+	vma->vm_start = start;
+	vma->vm_end = end;
+	vma->vm_flags = VM_READ | VM_WRITE | VM_EXEC;
+	vma->vm_flags |= mm->def_flags;
+	vma->vm_page_prot.pgprot = prot;
+	vma->vm_pgoff = pgoff;
+
+	if ((ret = insert_vm_struct(mm, vma))) {
+		up_write(&mm->mmap_sem);
+		kmem_cache_free(vm_area_cachep, vma);
+		return ret;
+	}
+
+	if (type) {
+		ret = zeromap_page_range(vma,
+					 vma->vm_start,
+					 vma->vm_end - vma->vm_start,
+					 vma->vm_page_prot);
+	} else {
+		vma->vm_flags |= VM_SHARED;
+		ret = remap_pfn_range(vma,
+				      vma->vm_start,
+				      vma->vm_pgoff,
+				      vma->vm_end - vma->vm_start,
+				      vma->vm_page_prot);
+	}
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+static inline int vesafb_init_mem(void)
+{
+	int ret = 0;
+
+	/* The memory chunks we're remapping here should be multiples
+	 * of PAGE_SIZE. */
+	ret += vesafb_remap_pfn_range(0x00000, IVTBDA_SIZE, 0,
+				      PROT_READ | PROT_EXEC | PROT_WRITE, 0);
+	ret += vesafb_remap_pfn_range(IVTBDA_SIZE, REAL_MEM_SIZE, 0,
+				      PROT_READ | PROT_EXEC | PROT_WRITE, 1);
+	ret += vesafb_remap_pfn_range(0x9f000, 0x100000, 
+				      0x9f000 >> PAGE_SHIFT,
+				      PROT_READ | PROT_EXEC | PROT_WRITE, 0);
+	if (ret)
+		printk(KERN_ERR "vesafb thread: memory remapping failed\n");
+
+	return ret;
+}
+
+#define vesafb_get_string(str) \
+{ 									\
+	/* The address is in the form ssssoooo, where oooo = offset,	\
+	 * ssss = segment */						\
+	addr = ((p_vbe(tsk->buf)->str & 0xffff0000) >> 12) +		\
+		(p_vbe(tsk->buf)->str & 0x0000ffff);			\
+									\
+	/* The data is in ROM which is shared between processes, so we 	\
+	 * just translate the real mode address into one visible from 	\
+	 * kernel space */						\
+	if (addr >= 0xa0000) {						\
+		p_vbe(tsk->buf)->str = (u32) __va(addr);		\
+									\
+	/* The data is in the buffer, we just have to convert the	\
+	 * address so that it points into the buffer user provided. */	\
+	} else if (addr > BUF_ADDR && addr < BUF_ADDR +			\
+		   sizeof(struct vesafb_vbe_ib)) {			\
+		addr -= BUF_ADDR;					\
+		p_vbe(tsk->buf)->str = (u32) (tsk->buf + addr);		\
+									\
+	/* This should never happen: someone was insane enough to put	\
+	 * the data somewhere in RAM.. */				\
+	} else {							\
+		p_vbe(tsk->buf)->str = (u32) "";			\
+	}								\
+}
+
+void vesafb_handle_getvbeib(struct vesafb_task *tsk)
+{
+	int addr, res;
+
+	tsk->regs.es  = (BUF_ADDR >> 4);
+	tsk->regs.edi = (BUF_ADDR & 0x000f);
+	strncpy(p_vbe(BUF_ADDR)->vbe_signature, "VBE2", 4);
+
+	vesafb_do_vm86(&tsk->regs);
+	memcpy(tsk->buf, (void*)(BUF_ADDR), sizeof(struct vesafb_vbe_ib));
+
+	/* The OEM fields were not defined prior to VBE 2.0 */
+	if (p_vbe(tsk->buf)->vbe_version >= 0x200) {
+		vesafb_get_string(oem_string_ptr);
+		vesafb_get_string(oem_vendor_name_ptr);
+		vesafb_get_string(oem_product_name_ptr);
+		vesafb_get_string(oem_product_rev_ptr);
+	}
+
+	/* This is basically the same as vesafb_get_string() */
+	addr = ((p_vbe(tsk->buf)->mode_list_ptr & 0xffff0000) >> 12) +
+		(p_vbe(tsk->buf)->mode_list_ptr & 0x0000ffff);
+
+	if (addr >= 0xa0000) {
+		p_vbe(tsk->buf)->mode_list_ptr = (u32) __va(addr);
+	} else if (addr > BUF_ADDR && addr < BUF_ADDR +
+		   sizeof(struct vesafb_vbe_ib)) {
+		addr -= BUF_ADDR;
+		p_vbe(tsk->buf)->mode_list_ptr = (u32) (tsk->buf + addr);
+	} else {
+		res = 0;
+		printk(KERN_WARNING "vesafb: warning, copying modelist "
+				    "from somewhere in RAM!\n");
+		while (*(u16*)(addr+res) != 0xffff &&
+		       res < (sizeof(p_vbe(tsk->buf)->reserved) - 2)) {
+			*(u16*) ((u32)&(p_vbe(tsk->buf)->reserved) + res) =
+				*(u16*)(addr+res);
+			res += 2;
+		}
+		*(u16*) ((u32)&(p_vbe(tsk->buf)->reserved) + res) = 0xffff;
+	}
+}
+
+int vesafb_handle_tasks(void)
+{
+	struct vesafb_task *tsk;
+	struct list_head *curr, *next;
+	int ret = 0;
+
+	down(&vesafb_task_list_sem);
+	list_for_each_safe(curr, next, &vesafb_task_list) {
+		tsk = list_entry(curr, struct vesafb_task, node);
+
+		if (tsk->flags & TF_EXIT) {
+			ret = 1;
+			goto task_done;
+		}
+		if (tsk->flags & TF_GETVBEIB) {
+			vesafb_handle_getvbeib(tsk);
+			goto task_done;
+		}
+		/* Do we need to store a pointer to the buffer in ES:EDI? */
+		if (tsk->flags & TF_BUF_DI) {
+			tsk->regs.es  = (BUF_ADDR >> 4);
+			tsk->regs.edi = (BUF_ADDR & 0x000f);
+		}
+		/* Sometimes the pointer has to be in ES:EBX. */
+		if (tsk->flags & TF_BUF_BX) {
+			tsk->regs.es  = (BUF_ADDR >> 4);
+			tsk->regs.ebx = (BUF_ADDR & 0x000f);
+		}
+		if (tsk->flags & (TF_BUF_DI | TF_BUF_BX))
+			memcpy((void*)BUF_ADDR, tsk->buf, tsk->buf_len);
+
+		vesafb_do_vm86(&tsk->regs);
+
+		if (tsk->flags & TF_RETURN_BUF)
+			memcpy(tsk->buf, (void*)BUF_ADDR, tsk->buf_len);
+
+task_done:	list_del(curr);
+		complete(&tsk->done);
+	}
+
+	/* If we're going to kill this thread, don't allow any elements
+	 * to be added to the task list. */
+	if (!ret)
+		up(&vesafb_task_list_sem);
+
+	return ret;
+}
+
+/*
+ * This 'hybrid' thread serves as a backend for vesafb-tng, handling all vm86
+ * calls. It is started as a kernel thread. It then creates its own mm struct,
+ * thus separating itself from any userspace processes. At this moment, it
+ * stops being a kernel thread (kernel threads have mm = NULL) and becomes
+ * a 'hybrid' thread -- one that has full access to kernel space, yet runs
+ * with its own address space.
+ *
+ * This is necessary because in order to make vm86 calls some parts of the
+ * first 1MB of RAM have to be setup to mimic the real mode. These are:
+ *  - interrupt vector table	[0x00000-0x003ff]
+ *  - BIOS data area		[0x00400-0x004ff]
+ *  - Extended BIOS data area	[0x9fc00-0x9ffff]
+ *  - the video RAM		[0xa0000-0xbffff]
+ *  - video BIOS		[0xc0000-0xcffff]
+ *  - motherboard BIOS		[0xf0000-0xfffff]
+ */
+int vesafb_thread(void *unused)
+{
+	int err = 0;
+
+	set_fs(KERNEL_DS);
+	daemonize("vesafb");
+
+	if (set_new_mm()) {
+		err = -ENOMEM;
+		goto thr_end;
+	}
+	if (vesafb_init_mem()) {
+		err = -ENOMEM;
+		goto thr_end;
+	}
+
+	DPRINTK("started vesafb thread\n");
+
+	/* Having an IO bitmap makes things faster as we avoid GPFs
+	 * when running vm86 code. We can live if it fails, though,
+	 * so don't bother checking for errors. */
+	ioperm(0,1024,1);
+	set_user_nice(current, -10);
+
+	complete(&vesafb_th_completion);
+
+	while (1) {
+		if (vesafb_handle_tasks())
+			break;
+		wait_event_interruptible(vesafb_wait,
+					 !list_empty(&vesafb_task_list));
+		try_to_freeze();
+	}
+
+out:	DPRINTK("exiting the vesafb thread\n");
+	vesafb_pid = -1;
+
+	/* Now that all callers know this thread is no longer running
+	 * (pid < 0), allow them to continue. */
+	up(&vesafb_task_list_sem);
+	return err;
+thr_end:
+	down(&vesafb_task_list_sem);
+	complete(&vesafb_th_completion);
+	goto out;	
+}
+
+int vesafb_queue_task(struct vesafb_task *tsk)
+{
+	down(&vesafb_task_list_sem);
+	if (vesafb_pid < 0)
+		return -1;
+	list_add_tail(&tsk->node, &vesafb_task_list);
+	up(&vesafb_task_list_sem);
+	wake_up(&vesafb_wait);
+	return 0;
+}
+
+int vesafb_wait_for_thread(void)
+{
+	/* PID 0 means that the thread is still initializing. */
+	if (vesafb_pid < 0)
+		return -1;
+	wait_for_completion(&vesafb_th_completion);
+	return 0;
+}
+
+int __init vesafb_init_thread(void)
+{
+	vesafb_pid = kernel_thread(vesafb_thread,NULL,0);
+	return 0;
+}
+
+#ifdef MODULE
+void __exit vesafb_kill_thread(void)
+{
+	struct vesafb_task *tsk;
+	if (vesafb_pid <= 0)
+		return;
+
+	vesafb_create_task(tsk);
+	if (!tsk)
+		return;
+	tsk->flags |= TF_EXIT;
+	vesafb_queue_task(tsk);
+	vesafb_wait_for_task(tsk);
+	kfree(tsk);
+	return;
+}
+module_exit(vesafb_kill_thread);
+#endif
+module_init(vesafb_init_thread);
+
+EXPORT_SYMBOL_GPL(vesafb_queue_task);
+EXPORT_SYMBOL_GPL(vesafb_wait_for_thread);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal Januszewski");
+
diff -urN newtree/drivers/video/vesafb-tng.c newtree.2/drivers/video/vesafb-tng.c
--- newtree/drivers/video/vesafb-tng.c	1969-12-31 16:00:00.000000000 -0800
+++ newtree.2/drivers/video/vesafb-tng.c	2006-08-04 14:07:26.000000000 -0700
@@ -0,0 +1,1598 @@
+/*
+ * Framebuffer driver for VBE 2.0+ compliant graphic boards
+ *
+ * (c) 2004-2006 Michal Januszewski <spock@gentoo.org>
+ *     Based upon vesafb code by Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *
+ */
+
+#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/delay.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/completion.h>
+#include <linux/platform_device.h>
+#include <video/edid.h>
+#include <video/vesa.h>
+#include <video/vga.h>
+#include <asm/io.h>
+#include <asm/mtrr.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include "edid.h"
+
+#define dac_reg	(0x3c8)
+#define dac_val	(0x3c9)
+
+#define VESAFB_NEED_EXACT_RES 	1
+#define VESAFB_NEED_EXACT_DEPTH 2
+
+/* --------------------------------------------------------------------- */
+
+static struct fb_var_screeninfo vesafb_defined __initdata = {
+	.activate	= FB_ACTIVATE_NOW,
+	.height		= 0,
+	.width		= 0,
+	.right_margin	= 32,
+	.upper_margin	= 16,
+	.lower_margin	= 4,
+	.vsync_len	= 4,
+	.vmode		= FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo vesafb_fix __initdata = {
+	.id	= "VESA VGA",
+	.type	= FB_TYPE_PACKED_PIXELS,
+	.accel	= FB_ACCEL_NONE,
+};
+
+static int  mtrr       = 0;	/* disable mtrr by default */
+static int  blank      = 1;     /* enable blanking by default */
+static int  ypan       = 0;	/* 0 - nothing, 1 - ypan, 2 - ywrap */
+static int  pmi_setpal = 1;	/* pmi for palette changes */
+static u16  *pmi_base  = NULL;  /* protected mode interface location */
+static void (*pmi_start)(void) = NULL;
+static void (*pmi_pal)(void)   = NULL;
+static struct vesafb_vbe_ib  vbe_ib;
+static struct vesafb_mode_ib *vbe_modes;
+static int                   vbe_modes_cnt = 0;
+static struct fb_info	     *vesafb_info = NULL;
+static int  nocrtc		    = 0; /* ignore CRTC settings */
+static int  noedid       __initdata = 0; /* don't try DDC transfers */
+static int  vram_remap   __initdata = 0; /* set amount of memory to be used */
+static int  vram_total   __initdata = 0; /* set total amount of memory */
+static u16  maxclk       __initdata = 0; /* maximum pixel clock */
+static u16  maxvf        __initdata = 0; /* maximum vertical frequency */
+static u16  maxhf        __initdata = 0; /* maximum horizontal frequency */
+static int  gtf          __initdata = 0; /* forces use of the GTF */
+static char *mode_option __initdata = NULL;
+static u16  vbemode      __initdata = 0;
+
+/* --------------------------------------------------------------------- */
+
+static int vesafb_find_vbe_mode(int xres, int yres, int depth,
+				unsigned char flags)
+{
+	int i, match = -1, h = 0, d = 0x7fffffff;
+
+	for (i = 0; i < vbe_modes_cnt; i++) {
+		h = abs(vbe_modes[i].x_res - xres) +
+		    abs(vbe_modes[i].y_res - yres) +
+		    abs(depth - vbe_modes[i].depth);
+		if (h == 0)
+			return i;
+		if (h < d || (h == d && vbe_modes[i].depth > depth)) {
+			d = h;
+			match = i;
+		}
+	}
+	i = 1;
+
+	if (flags & VESAFB_NEED_EXACT_DEPTH && vbe_modes[match].depth != depth)
+		i = 0;
+	if (flags & VESAFB_NEED_EXACT_RES && d > 24)
+		i = 0;
+	if (i != 0)
+		return match;
+	else
+		return -1;
+}
+
+static int vesafb_pan_display(struct fb_var_screeninfo *var,
+                              struct fb_info *info)
+{
+	int offset;
+
+	offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
+
+	/* It turns out it's not the best idea to do panning via vm86,
+	 * so we only allow it if we have a PMI. */
+	if (pmi_start) {
+		__asm__ __volatile__(
+			"call *(%%edi)"
+			: /* no return value */
+			: "a" (0x4f07),         /* EAX */
+			  "b" (0),              /* EBX */
+			  "c" (offset),         /* ECX */
+			  "d" (offset >> 16),   /* EDX */
+			  "D" (&pmi_start));    /* EDI */
+	}
+	return 0;
+}
+
+static int vesafb_blank(int blank, struct fb_info *info)
+{
+	struct vesafb_task *tsk;
+	int err = 1;
+
+	if (vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
+		int loop = 10000;
+		u8 seq = 0, crtc17 = 0;
+
+		if (blank == FB_BLANK_POWERDOWN) {
+			seq = 0x20;
+			crtc17 = 0x00;
+			err = 0;
+		} else {
+			seq = 0x00;
+			crtc17 = 0x80;
+			err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
+		}
+
+		vga_wseq(NULL, 0x00, 0x01);
+		seq |= vga_rseq(NULL, 0x01) & ~0x20;
+		vga_wseq(NULL, 0x00, seq);
+
+		crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
+		while (loop--);
+		vga_wcrt(NULL, 0x17, crtc17);
+		vga_wseq(NULL, 0x00, 0x03);
+	} else {
+		vesafb_create_task (tsk);
+		if (!tsk)
+			return -ENOMEM;
+		tsk->regs.eax = 0x4f10;
+		switch (blank) {
+		case FB_BLANK_UNBLANK:
+			tsk->regs.ebx = 0x0001;
+			break;
+		case FB_BLANK_NORMAL:
+			tsk->regs.ebx = 0x0101;	/* standby */
+			break;
+		case FB_BLANK_POWERDOWN:
+			tsk->regs.ebx = 0x0401;	/* powerdown */
+			break;
+		default:
+			goto out;
+		}
+		tsk->flags = TF_CALL;
+		if (!vesafb_queue_task (tsk))
+			vesafb_wait_for_task(tsk);
+
+		if ((tsk->regs.eax & 0xffff) == 0x004f)
+			err = 0;
+out:		kfree(tsk);
+	}
+	return err;
+}
+
+static int vesafb_setpalette(struct vesafb_pal_entry *entries, int count,
+			     int start, struct fb_info *info)
+{
+	struct vesafb_task *tsk;
+	int i = ((struct vesafb_par*)info->par)->mode_idx;
+	int ret = 0;
+
+	/* We support palette modifications for 8 bpp modes only, so
+	 * there can never be more than 256 entries. */
+	if (start + count > 256)
+		return -EINVAL;
+
+	/* Use VGA registers if mode is VGA-compatible. */
+	if (i >= 0 && i < vbe_modes_cnt &&
+	    vbe_modes[i].mode_attr & VBE_MODE_VGACOMPAT) {
+		for (i = 0; i < count; i++) {
+			outb_p(start + i,        dac_reg);
+			outb_p(entries[i].red,   dac_val);
+			outb_p(entries[i].green, dac_val);
+			outb_p(entries[i].blue,  dac_val);
+		}
+	} else if (pmi_setpal) {
+		__asm__ __volatile__(
+		"call *(%%esi)"
+		: /* no return value */
+		: "a" (0x4f09),         /* EAX */
+		  "b" (0),              /* EBX */
+		  "c" (count),          /* ECX */
+		  "d" (start),          /* EDX */
+		  "D" (entries),        /* EDI */
+		  "S" (&pmi_pal));      /* ESI */
+	} else {
+		vesafb_create_task (tsk);
+		if (!tsk)
+			return -ENOMEM;
+		tsk->regs.eax = 0x4f09;
+		tsk->regs.ebx = 0x0;
+		tsk->regs.ecx = count;
+		tsk->regs.edx = start;
+		tsk->buf = entries;
+		tsk->buf_len = sizeof(struct vesafb_pal_entry) * count;
+		tsk->flags = TF_CALL | TF_BUF_DI;
+
+		if (!vesafb_queue_task (tsk))
+			vesafb_wait_for_task(tsk);
+		if ((tsk->regs.eax & 0xffff) != 0x004f)
+			ret = 1;
+		kfree(tsk);
+	}
+	return ret;
+}
+
+static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp,
+			    struct fb_info *info)
+{
+	struct vesafb_pal_entry entry;
+	int shift = 16 - info->var.green.length;
+	int ret = 0;
+
+	if (regno >= info->cmap.len)
+		return -EINVAL;
+
+	if (info->var.bits_per_pixel == 8) {
+		entry.red   = red   >> shift;
+		entry.green = green >> shift;
+		entry.blue  = blue  >> shift;
+		entry.pad   = 0;
+
+		ret = vesafb_setpalette(&entry, 1, regno, info);
+	} else if (regno < 16) {
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			if (info->var.red.offset == 10) {
+				/* 1:5:5:5 */
+				((u32*) (info->pseudo_palette))[regno] =
+						((red   & 0xf800) >>  1) |
+						((green & 0xf800) >>  6) |
+						((blue  & 0xf800) >> 11);
+			} else {
+				/* 0:5:6:5 */
+				((u32*) (info->pseudo_palette))[regno] =
+						((red   & 0xf800)      ) |
+						((green & 0xfc00) >>  5) |
+						((blue  & 0xf800) >> 11);
+			}
+			break;
+
+		case 24:
+		case 32:
+			red   >>= 8;
+			green >>= 8;
+			blue  >>= 8;
+			((u32 *)(info->pseudo_palette))[regno] =
+				(red   << info->var.red.offset)   |
+				(green << info->var.green.offset) |
+				(blue  << info->var.blue.offset);
+			break;
+		}
+	}
+	return ret;
+}
+
+static int vesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+	struct vesafb_pal_entry *entries;
+	int shift = 16 - info->var.green.length;
+	int i, ret = 0;
+
+	if (info->var.bits_per_pixel == 8) {
+		if (cmap->start + cmap->len > info->cmap.start +
+		    info->cmap.len || cmap->start < info->cmap.start)
+			return -EINVAL;
+
+		entries = vmalloc(sizeof(struct vesafb_pal_entry) * cmap->len);
+		if (!entries)
+			return -ENOMEM;
+		for (i = 0; i < cmap->len; i++) {
+			entries[i].red   = cmap->red[i]   >> shift;
+			entries[i].green = cmap->green[i] >> shift;
+			entries[i].blue  = cmap->blue[i]  >> shift;
+			entries[i].pad   = 0;
+		}
+		ret = vesafb_setpalette(entries, cmap->len, cmap->start, info);
+		vfree(entries);
+	} else {
+		/* For modes with bpp > 8, we only set the pseudo palette in
+		 * the fb_info struct. We rely on vesafb_setcolreg to do all
+		 * sanity checking. */
+		for (i = 0; i < cmap->len; i++) {
+			ret += vesafb_setcolreg(cmap->start + i, cmap->red[i],
+						cmap->green[i], cmap->blue[i],
+						0, info);
+		}
+	}
+	return ret;
+}
+
+static int vesafb_set_par(struct fb_info *info)
+{
+	struct vesafb_par *par = (struct vesafb_par *) info->par;
+	struct vesafb_task *tsk;
+	struct vesafb_crtc_ib *crtc = NULL;
+	struct vesafb_mode_ib *mode = NULL;
+	int i, err = 0, depth = info->var.bits_per_pixel;
+
+	if (depth > 8 && depth != 32)
+		depth = info->var.red.length + info->var.green.length +
+			info->var.blue.length;
+
+	i = vesafb_find_vbe_mode(info->var.xres, info->var.yres, depth,
+				 VESAFB_NEED_EXACT_RES |
+				 VESAFB_NEED_EXACT_DEPTH);
+	if (i >= 0)
+		mode = &vbe_modes[i];
+	else
+		return -EINVAL;
+
+	vesafb_create_task (tsk);
+	if (!tsk)
+		return -ENOMEM;
+	tsk->regs.eax = 0x4f02;
+	tsk->regs.ebx = mode->mode_id | 0x4000;		/* use LFB */
+	tsk->flags = TF_CALL;
+
+	if (vbe_ib.vbe_version >= 0x0300 && !nocrtc &&
+	    info->var.pixclock != 0) {
+		tsk->regs.ebx |= 0x0800; 		/* use CRTC data */
+		tsk->flags |= TF_BUF_DI;
+		crtc = kmalloc(sizeof(struct vesafb_crtc_ib), GFP_KERNEL);
+		if (!crtc) {
+			err = -ENOMEM;
+			goto out;
+		}
+		crtc->horiz_start = info->var.xres + info->var.right_margin;
+		crtc->horiz_end	  = crtc->horiz_start + info->var.hsync_len;
+		crtc->horiz_total = crtc->horiz_end + info->var.left_margin;
+
+		crtc->vert_start  = info->var.yres + info->var.lower_margin;
+		crtc->vert_end    = crtc->vert_start + info->var.vsync_len;
+		crtc->vert_total  = crtc->vert_end + info->var.upper_margin;
+
+		crtc->pixel_clock = PICOS2KHZ(info->var.pixclock) * 1000;
+		crtc->refresh_rate = (u16)(100 * (crtc->pixel_clock /
+				     (crtc->vert_total * crtc->horiz_total)));
+		crtc->flags = 0;
+
+		if (info->var.vmode & FB_VMODE_DOUBLE)
+			crtc->flags |= 0x1;
+		if (info->var.vmode & FB_VMODE_INTERLACED)
+			crtc->flags |= 0x2;
+		if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
+			crtc->flags |= 0x4;
+		if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
+			crtc->flags |= 0x8;
+		memcpy(&par->crtc, crtc, sizeof(struct vesafb_crtc_ib));
+	} else
+		memset(&par->crtc, 0, sizeof(struct vesafb_crtc_ib));
+
+	tsk->buf = (void*)crtc;
+	tsk->buf_len = sizeof(struct vesafb_crtc_ib);
+
+	if (vesafb_queue_task (tsk)) {
+		err = -EINVAL;
+		goto out;
+	}
+	vesafb_wait_for_task(tsk);
+
+	if ((tsk->regs.eax & 0xffff) != 0x004f) {
+		printk(KERN_ERR "vesafb: mode switch failed (eax: 0x%lx)\n",
+				tsk->regs.eax);
+		err = -EINVAL;
+		goto out;
+	}
+	par->mode_idx = i;
+
+	/* For 8bpp modes, always try to set the DAC to 8 bits. */
+	if (vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC &&
+	    mode->bits_per_pixel <= 8) {
+		vesafb_reset_task(tsk);
+		tsk->flags = TF_CALL;
+		tsk->regs.eax = 0x4f08;
+		tsk->regs.ebx = 0x0800;
+
+		if (!vesafb_queue_task (tsk))
+			vesafb_wait_for_task(tsk);
+
+		if ((tsk->regs.eax & 0xffff) != 0x004f ||
+		    ((tsk->regs.ebx & 0xff00) >> 8) != 8) {
+			/* We've failed to set the DAC palette format -
+			 * time to correct var. */
+			info->var.red.length    = 6;
+			info->var.green.length  = 6;
+			info->var.blue.length   = 6;
+		}
+	}
+
+	info->fix.visual = (info->var.bits_per_pixel == 8) ?
+		           FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+	info->fix.line_length = mode->bytes_per_scan_line;
+
+	DPRINTK("set new mode %dx%d-%d (0x%x)\n",
+		info->var.xres, info->var.yres, info->var.bits_per_pixel,
+		mode->mode_id);
+
+out:	if (crtc != NULL)
+		kfree(crtc);
+	kfree(tsk);
+
+	return err;
+}
+
+static void vesafb_setup_var(struct fb_var_screeninfo *var, struct fb_info *info,
+			     struct vesafb_mode_ib *mode)
+{
+	var->xres = mode->x_res;
+	var->yres = mode->y_res;
+	var->xres_virtual = mode->x_res;
+	var->yres_virtual = (ypan) ?
+			      info->fix.smem_len / mode->bytes_per_scan_line :
+			      mode->y_res;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->bits_per_pixel = mode->bits_per_pixel;
+
+	if (var->bits_per_pixel == 15)
+		var->bits_per_pixel = 16;
+
+	if (var->bits_per_pixel > 8) {
+		var->red.offset    = mode->red_off;
+		var->red.length    = mode->red_len;
+		var->green.offset  = mode->green_off;
+		var->green.length  = mode->green_len;
+		var->blue.offset   = mode->blue_off;
+		var->blue.length   = mode->blue_len;
+		var->transp.offset = mode->rsvd_off;
+		var->transp.length = mode->rsvd_len;
+
+		DPRINTK("directcolor: size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+			mode->rsvd_len,
+			mode->red_len,
+			mode->green_len,
+			mode->blue_len,
+			mode->rsvd_off,
+			mode->red_off,
+			mode->green_off,
+			mode->blue_off);
+	} else {
+		var->red.offset    = 0;
+		var->green.offset  = 0;
+		var->blue.offset   = 0;
+		var->transp.offset = 0;
+
+		/* We're assuming that we can switch the DAC to 8 bits. If
+		 * this proves to be incorrect, we'll update the fields
+		 * later in set_par(). */
+		if (vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
+			var->red.length    = 8;
+			var->green.length  = 8;
+			var->blue.length   = 8;
+			var->transp.length = 0;
+		} else {
+			var->red.length    = 6;
+			var->green.length  = 6;
+			var->blue.length   = 6;
+			var->transp.length = 0;
+		}
+	}
+}
+
+static void inline vesafb_check_limits(struct fb_var_screeninfo *var,
+		 		       struct fb_info *info)
+{
+	struct fb_videomode *mode;
+
+	if (!var->pixclock)
+		return;
+	if (vbe_ib.vbe_version < 0x0300) {
+		fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, var, info);
+		return;
+	}
+	if (!fb_validate_mode(var, info))
+		return;
+	mode = fb_find_best_mode(var, &info->modelist);
+	if (mode) {
+		DPRINTK("find_best_mode: %d %d @ %d (vmode: %d)\n",
+			mode->xres, mode->yres, mode->refresh, mode->vmode);
+		if (mode->xres == var->xres && mode->yres == var->yres &&
+		    !(mode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))) {
+			fb_videomode_to_var(var, mode);
+			return;
+		}
+	}
+	if (info->monspecs.gtf && !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+		return;
+	/* Use default refresh rate */
+	var->pixclock = 0;
+}
+
+static int vesafb_check_var(struct fb_var_screeninfo *var,
+			    struct fb_info *info)
+{
+	int match = -1;
+	int depth = var->red.length + var->green.length + var->blue.length;
+
+	/* Various apps will use bits_per_pixel to set the color depth,
+	 * which is theoretically incorrect, but which we'll try to handle
+	 * here. */
+	if (depth == 0 || abs(depth - var->bits_per_pixel) >= 8)
+		depth = var->bits_per_pixel;
+	match = vesafb_find_vbe_mode(var->xres, var->yres, depth,
+				     VESAFB_NEED_EXACT_RES);
+
+	if (match == -1) {
+		DPRINTK("vesafb: mode %dx%d-%d not found\n", var->xres,
+			var->yres, depth);
+		return -EINVAL;
+	}
+
+	vesafb_setup_var(var, info, &vbe_modes[match]);
+	DPRINTK("found mode 0x%x (%dx%d-%dbpp)\n",
+		vbe_modes[match].mode_id, vbe_modes[match].x_res,
+		vbe_modes[match].y_res, vbe_modes[match].depth);
+
+	/* Check whether we have remapped enough memory for this mode. */
+	if (var->yres * vbe_modes[match].bytes_per_scan_line >
+	    info->fix.smem_len) {
+		return -EINVAL;
+	}
+
+	if ((var->vmode & FB_VMODE_DOUBLE) &&
+	    !(vbe_modes[match].mode_attr & 0x100))
+		var->vmode &= ~FB_VMODE_DOUBLE;
+	if ((var->vmode & FB_VMODE_INTERLACED) &&
+	    !(vbe_modes[match].mode_attr & 0x200))
+		var->vmode &= ~FB_VMODE_INTERLACED;
+	vesafb_check_limits(var, info);
+	return 0;
+}
+
+static int vesafb_open(struct fb_info *info, int user)
+{
+	struct vesafb_task *tsk = NULL;
+	struct vesafb_par *par = info->par;
+	int cnt = atomic_read(&par->ref_count);
+
+	if (!cnt) {
+		vesafb_create_task(tsk);
+		if (!tsk)
+			goto out;
+
+		/* Get the VBE state buffer size. We want all available
+		 * hardware state data (CL = 0x0f). */
+		tsk->regs.eax = 0x4f04;
+		tsk->regs.ecx = 0x000f;
+		tsk->regs.edx = 0x0000;
+		tsk->flags = TF_CALL;
+
+		if (vesafb_queue_task(tsk))
+			goto out;
+	
+		vesafb_wait_for_task(tsk);
+		
+		if ((tsk->regs.eax & 0xffff) != 0x004f) {
+			printk(KERN_WARNING "vesafb: VBE state buffer size "
+				"cannot be determined (eax: 0x%lx)\n",
+				tsk->regs.eax);
+			goto out;
+		}
+
+		par->vbe_state_size = 64 * (tsk->regs.ebx & 0xffff);
+		par->vbe_state = kzalloc(par->vbe_state_size, GFP_KERNEL);
+		if (!par->vbe_state) 
+			goto out;
+
+		vesafb_reset_task(tsk);
+		tsk->regs.eax = 0x4f04;
+		tsk->regs.ecx = 0x000f;
+		tsk->regs.edx = 0x0001;
+		tsk->flags = TF_CALL | TF_BUF_BX | TF_RETURN_BUF;
+		tsk->buf = (void*)(par->vbe_state);
+		tsk->buf_len = par->vbe_state_size;
+
+		if (vesafb_queue_task(tsk))
+			goto getstate_failed;
+		vesafb_wait_for_task(tsk);
+
+		if ((tsk->regs.eax & 0xffff) != 0x004f) {
+			printk(KERN_WARNING "vesafb: VBE get state call "
+				"failed (eax: 0x%lx)\n", tsk->regs.eax);
+			goto getstate_failed;
+		}
+	}
+out:
+	atomic_inc(&par->ref_count);
+	if (tsk)
+		kfree(tsk);
+	return 0;
+
+getstate_failed:
+	kfree(par->vbe_state);
+	par->vbe_state = NULL;
+	par->vbe_state_size = 0;
+	goto out;
+}
+
+static int vesafb_release(struct fb_info *info, int user)
+{
+	struct vesafb_task *tsk = NULL;
+	struct vesafb_par *par = info->par;
+	int cnt = atomic_read(&par->ref_count);
+
+	if (!cnt)
+		return -EINVAL;
+	
+	if (cnt == 1 && par->vbe_state && par->vbe_state_size) {
+		vesafb_create_task(tsk);
+		if (!tsk)
+			goto out;
+
+		tsk->regs.eax = 0x0003;
+		tsk->regs.ebx = 0x0000;
+		tsk->flags = TF_CALL;
+
+		if (vesafb_queue_task(tsk))
+			goto out;
+	
+		vesafb_wait_for_task(tsk);
+
+		vesafb_reset_task(tsk);
+		tsk->regs.eax = 0x4f04;
+		tsk->regs.ecx = 0x000f;
+		tsk->regs.edx = 0x0002;
+		tsk->buf = (void*)(par->vbe_state);
+		tsk->buf_len = par->vbe_state_size;
+		tsk->flags = TF_CALL | TF_BUF_BX;
+
+		if (vesafb_queue_task(tsk))
+			goto out;
+	
+		vesafb_wait_for_task(tsk);
+
+		if ((tsk->regs.eax & 0xffff) != 0x004f)
+			printk(KERN_WARNING "vesafb: VBE state restore call "
+				"failed (eax: 0x%lx)\n",
+				tsk->regs.eax);
+	}
+out:
+	atomic_dec(&par->ref_count);
+	if (tsk)
+		kfree(tsk);
+	return 0;
+}
+
+static int __init vesafb_probe(struct platform_device *device);
+
+static struct fb_ops vesafb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= vesafb_open,
+	.fb_release	= vesafb_release,
+	.fb_setcolreg	= vesafb_setcolreg,
+	.fb_setcmap	= vesafb_setcmap,
+	.fb_pan_display	= vesafb_pan_display,
+	.fb_blank       = vesafb_blank,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_check_var	= vesafb_check_var,
+	.fb_set_par	= vesafb_set_par
+};
+
+static struct platform_driver vesafb_driver = {
+	.probe	= vesafb_probe,
+	.driver	= {
+		.name	= "vesafb",
+	},
+};
+
+static struct platform_device *vesafb_device;
+ 
+#ifndef MODULE
+int __init vesafb_setup(char *options)
+{
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	DPRINTK("options %s\n",options);
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!*this_opt) continue;
+
+		DPRINTK("this_opt: %s\n",this_opt);
+
+		if (! strcmp(this_opt, "redraw"))
+			ypan=0;
+		else if (! strcmp(this_opt, "ypan"))
+			ypan=1;
+		else if (! strcmp(this_opt, "ywrap"))
+			ypan=2;
+		else if (! strcmp(this_opt, "vgapal"))
+			pmi_setpal=0;
+		else if (! strcmp(this_opt, "pmipal"))
+			pmi_setpal=1;
+		else if (! strncmp(this_opt, "mtrr:", 5))
+			mtrr = simple_strtoul(this_opt+5, NULL, 0);
+		else if (! strcmp(this_opt, "nomtrr"))
+			mtrr=0;
+		else if (! strcmp(this_opt, "nocrtc"))
+			nocrtc=1;
+		else if (! strcmp(this_opt, "noedid"))
+			noedid=1;
+		else if (! strcmp(this_opt, "noblank"))
+			blank=0;
+		else if (! strcmp(this_opt, "gtf"))
+			gtf=1;
+		else if (! strncmp(this_opt, "vtotal:", 7))
+			vram_total = simple_strtoul(this_opt + 7, NULL, 0);
+		else if (! strncmp(this_opt, "vremap:", 7))
+			vram_remap = simple_strtoul(this_opt + 7, NULL, 0);
+		else if (! strncmp(this_opt, "maxhf:", 6))
+			maxhf = simple_strtoul(this_opt + 6, NULL, 0);
+		else if (! strncmp(this_opt, "maxvf:", 6))
+			maxvf = simple_strtoul(this_opt + 6, NULL, 0);
+		else if (! strncmp(this_opt, "maxclk:", 7))
+			maxclk = simple_strtoul(this_opt + 7, NULL, 0);
+		else if (! strncmp(this_opt, "vbemode:", 8))
+			vbemode = simple_strtoul(this_opt + 8, NULL,0);
+		else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
+			DPRINTK("mode_option: %s\n",this_opt);
+			mode_option = this_opt;
+		} else {
+			printk(KERN_WARNING
+			       "vesafb: unrecognized option %s\n", this_opt);
+		}
+	}
+
+	return 0;
+}
+#endif /* !MODULE */
+
+static int vesafb_read_proc_modes(char *buf, char **start, off_t offset,
+			    	  int len, int *eof, void *private)
+{
+	int clen = 0, i;
+
+	for (i = 0; i < vbe_modes_cnt; i++) {
+		clen += sprintf(buf + clen, "%dx%d-%d\n", vbe_modes[i].x_res,
+				vbe_modes[i].y_res, vbe_modes[i].depth);
+	}
+	*start = buf + offset;
+
+	if (clen > offset) {
+		clen -= offset;
+	} else {
+		clen = 0;
+	}
+	return clen;
+}
+
+static int vesafb_read_proc_vbe_info(char *buf, char **start, off_t offset,
+			    	     int len, int *eof, void *private)
+{
+	int clen = 0;
+
+	clen += sprintf(buf + clen, "Version:    %d.%d\n",
+			((vbe_ib.vbe_version & 0xff00) >> 8),
+			vbe_ib.vbe_version & 0xff);
+	clen += sprintf(buf + clen, "Vendor:     %s\n",
+			(char*)vbe_ib.oem_vendor_name_ptr);
+	clen += sprintf(buf + clen, "Product:    %s\n",
+			(char*)vbe_ib.oem_product_name_ptr);
+	clen += sprintf(buf + clen, "OEM rev:    %s\n",
+			(char*)vbe_ib.oem_product_rev_ptr);
+	clen += sprintf(buf + clen, "OEM string: %s\n",
+			(char*)vbe_ib.oem_string_ptr);
+
+	*start = buf + offset;
+
+	if (clen > offset) {
+		clen -= offset;
+	} else {
+		clen = 0;
+	}
+	return clen;
+}
+
+static int __init inline vesafb_vbe_getinfo(struct vesafb_task *tsk)
+{
+	tsk->regs.eax = 0x4f00;
+	tsk->flags = TF_CALL | TF_GETVBEIB;
+	tsk->buf = &vbe_ib;
+	tsk->buf_len = sizeof(vbe_ib);
+	if (vesafb_queue_task (tsk))
+		return -EINVAL;
+	vesafb_wait_for_task(tsk);
+
+	if (vbe_ib.vbe_version < 0x0200) {
+		printk(KERN_ERR "vesafb: Sorry, pre-VBE 2.0 cards are "
+				"not supported.\n");
+		return -EINVAL;
+	}
+
+	if ((tsk->regs.eax & 0xffff) != 0x004f) {
+		printk(KERN_ERR "vesafb: Getting mode info block failed "
+				"(eax=0x%x)\n", (u32)tsk->regs.eax);
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO "vesafb: %s, %s, %s (OEM: %s)\n",
+		(char*)vbe_ib.oem_vendor_name_ptr,
+		(char*)vbe_ib.oem_product_name_ptr,
+		(char*)vbe_ib.oem_product_rev_ptr,
+		(char*)vbe_ib.oem_string_ptr);
+
+	printk(KERN_INFO "vesafb: VBE version: %d.%d\n",
+			 ((vbe_ib.vbe_version & 0xff00) >> 8),
+			 vbe_ib.vbe_version & 0xff);
+	return 0;
+}
+
+static int __init inline vesafb_vbe_getmodes(struct vesafb_task *tsk)
+{
+	u16 *mode = 0;
+	int off = 0;
+
+	/* Count available modes. */
+	mode = (u16*)vbe_ib.mode_list_ptr;
+	while (*mode != 0xffff) {
+		vbe_modes_cnt++;
+		mode++;
+	}
+
+	vbe_modes = kmalloc(sizeof(struct vesafb_mode_ib)*
+			    vbe_modes_cnt, GFP_KERNEL);
+	if (!vbe_modes)
+		return -ENOMEM;
+
+	/* Get mode info for all available modes. */
+	mode = (u16*)vbe_ib.mode_list_ptr;
+
+	while (*mode != 0xffff) {
+		struct vesafb_mode_ib *mib;
+
+		vesafb_reset_task(tsk);
+		tsk->regs.eax = 0x4f01;
+		tsk->regs.ecx = (u32) *mode;
+		tsk->flags = TF_CALL | TF_RETURN_BUF | TF_BUF_DI;
+		tsk->buf = vbe_modes+off;
+		tsk->buf_len = sizeof(struct vesafb_mode_ib);
+		if (vesafb_queue_task(tsk))
+			return -EINVAL;
+		vesafb_wait_for_task(tsk);
+		mib = p_mode(tsk->buf);
+		mib->mode_id = *mode;
+
+		/* We only want modes that are supported with the currennt
+		 * hardware configuration (D0), color (D3), graphics (D4)
+		 * and that have support for the LFB (D7). */
+		if ((mib->mode_attr & 0x99) == 0x99 &&
+		    mib->bits_per_pixel >= 8) {
+			off++;
+		} else {
+			vbe_modes_cnt--;
+		}
+		mode++;
+		mib->depth = mib->red_len + mib->green_len + mib->blue_len;
+		/* Handle 8bpp modes and modes with broken color component
+		 * lengths. */
+		if (mib->depth == 0 ||
+		    (mib->depth == 24 && mib->bits_per_pixel == 32))
+			mib->depth = mib->bits_per_pixel;
+	}
+
+	return 0;
+}
+
+static int __init inline vesafb_vbe_getpmi(struct vesafb_task *tsk)
+{
+	int i;
+
+	vesafb_reset_task(tsk);
+	tsk->regs.eax = 0x4f0a;
+	tsk->regs.ebx = 0x0;
+	tsk->flags = TF_CALL;
+	if (vesafb_queue_task(tsk))
+		return -EINVAL;
+	vesafb_wait_for_task(tsk);
+
+	if ((tsk->regs.eax & 0xffff) != 0x004f || tsk->regs.es < 0xc000) {
+		pmi_setpal = ypan = 0;
+	} else {
+		pmi_base  = (u16*)phys_to_virt(((u32)tsk->regs.es << 4) +
+			     tsk->regs.edi);
+		pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
+		pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
+		printk(KERN_INFO "vesafb: protected mode interface info at "
+				 "%04x:%04x\n",
+				 (u16)tsk->regs.es, (u16)tsk->regs.edi);
+		printk(KERN_INFO "vesafb: pmi: set display start = %p, "
+				 "set palette = %p\n", pmi_start, pmi_pal);
+
+		if (pmi_base[3]) {
+			printk(KERN_INFO "vesafb: pmi: ports = ");
+			for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
+				printk("%x ",pmi_base[i]);
+			printk("\n");
+
+			/*
+			 * memory areas not supported (yet?)
+			 *
+			 * Rules are: we have to set up a descriptor for the
+			 * requested memory area and pass it in the ES register
+			 * to the BIOS function.
+			 */
+			if (pmi_base[i] != 0xffff) {
+				printk(KERN_INFO "vesafb: can't handle memory "
+						 "requests, pmi disabled\n");
+				ypan = pmi_setpal = 0;
+			}
+		}
+	}
+	return 0;
+}
+
+static int __init inline vesafb_vbe_getedid(struct vesafb_task *tsk,
+					    struct fb_info *info)
+{
+	int res = 0;
+
+	if (noedid || vbe_ib.vbe_version < 0x0300)
+		return -EINVAL;
+
+	vesafb_reset_task(tsk);
+	tsk->regs.eax = 0x4f15;
+	tsk->regs.ebx = 0;
+	tsk->regs.ecx = 0;
+	if (vesafb_queue_task(tsk))
+		return -EINVAL;
+	vesafb_wait_for_task(tsk);
+
+	if ((tsk->regs.eax & 0xffff) != 0x004f)
+		return -EINVAL;
+
+	if ((tsk->regs.ebx & 0x3) == 3) {
+		printk(KERN_INFO "vesafb: VBIOS/hardware supports both "
+				 "DDC1 and DDC2 transfers\n");
+	} else if ((tsk->regs.ebx & 0x3) == 2) {
+		printk(KERN_INFO "vesafb: VBIOS/hardware supports DDC2 "
+				 "transfers\n");
+	} else if ((tsk->regs.ebx & 0x3) == 1) {
+		printk(KERN_INFO "vesafb: VBIOS/hardware supports DDC1 "
+				 "transfers\n");
+	} else {
+		printk(KERN_INFO "vesafb: VBIOS/hardware doesn't support "
+				 "DDC transfers\n");
+		return -EINVAL;
+	}
+
+	vesafb_reset_task(tsk);
+	tsk->regs.eax = 0x4f15;
+	tsk->regs.ebx = 1;
+	tsk->regs.ecx = tsk->regs.edx = 0;
+	tsk->flags = TF_CALL | TF_RETURN_BUF | TF_BUF_DI;
+	tsk->buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+	tsk->buf_len = EDID_LENGTH;
+
+	if (vesafb_queue_task(tsk)) {
+		res = -EINVAL;
+		goto out;
+	}
+	vesafb_wait_for_task(tsk);
+
+	if ((tsk->regs.eax & 0xffff) == 0x004f) {
+		fb_edid_to_monspecs(tsk->buf, &info->monspecs);
+		fb_videomode_to_modelist(info->monspecs.modedb,
+				info->monspecs.modedb_len, &info->modelist);
+		if (info->monspecs.vfmax && info->monspecs.hfmax) {
+			/* If the maximum pixel clock wasn't specified in
+			 * the EDID block, set it to 300 MHz. */
+			if (info->monspecs.dclkmax == 0)
+				info->monspecs.dclkmax = 300 * 1000000;
+			info->monspecs.gtf = 1;
+		} else {
+			res = -EINVAL;
+		}
+	}
+
+out:	kfree(tsk->buf);
+	return res;
+}
+
+static void __init inline vesafb_vbe_getmonspecs(struct vesafb_task *tsk,
+		                                 struct fb_info *info)
+{
+	struct fb_var_screeninfo var;
+	int i;
+	memset(&info->monspecs, 0, sizeof(struct fb_monspecs));
+
+	/* If we didn't get all necessary data from the EDID block,
+	 * mark it as incompatible with the GTF. */
+	if (vesafb_vbe_getedid(tsk, info))
+		info->monspecs.gtf = 0;
+
+	/* Kernel command line overrides. */
+	if (maxclk)
+		info->monspecs.dclkmax = maxclk * 1000000;
+	if (maxvf)
+		info->monspecs.vfmax = maxvf;
+	if (maxhf)
+		info->monspecs.hfmax = maxhf * 1000;
+
+	/* In case DDC transfers are not supported the user can provide
+	 * monitor limits manually. Lower limits are set to "safe" values. */
+	if (info->monspecs.gtf == 0 && maxclk && maxvf && maxhf) {
+		info->monspecs.dclkmin = 0;
+		info->monspecs.vfmin = 60;
+		info->monspecs.hfmin = 29000;
+		info->monspecs.gtf = 1;
+	}
+
+	if (info->monspecs.gtf) {
+		printk(KERN_INFO
+		       	"vesafb: monitor limits: vf = %d Hz, hf = %d kHz, "
+			"clk = %d MHz\n", info->monspecs.vfmax,
+			(int)(info->monspecs.hfmax / 1000),
+			(int)(info->monspecs.dclkmax / 1000000));
+		/* Add valid VESA video modes to our modelist. */
+		for (i = 0; i < VESA_MODEDB_SIZE; i++) {
+			fb_videomode_to_var(&var, (struct fb_videomode *)
+					    &vesa_modes[i]);
+			if (!fb_validate_mode(&var, info))
+				fb_add_videomode((struct fb_videomode *)
+						 &vesa_modes[i],
+						 &info->modelist);
+		}
+	} else {
+		/* Add all VESA video modes to our modelist. */
+		fb_videomode_to_modelist((struct fb_videomode *)vesa_modes,
+				 	 VESA_MODEDB_SIZE, &info->modelist);
+		printk(KERN_INFO "vesafb: no monitor limits have been set\n");
+	}
+	return;
+}
+
+static int __init inline vesafb_vbe_init(struct fb_info *info)
+{
+	struct vesafb_task *tsk;
+	int res = 0;
+
+	vesafb_create_task(tsk);
+	if (!tsk)
+		return -EINVAL;
+	if ((res = vesafb_vbe_getinfo(tsk)) != 0)
+		goto out;
+	if ((res = vesafb_vbe_getmodes(tsk)) != 0)
+		goto out;
+	if (pmi_setpal || ypan)
+		vesafb_vbe_getpmi(tsk);
+
+	INIT_LIST_HEAD(&info->modelist);
+	vesafb_vbe_getmonspecs(tsk, info);
+
+out:	kfree(tsk);
+	return res;
+}
+
+static int __init decode_mode(u32 *xres, u32 *yres, u32 *bpp, u32 *refresh)
+{
+	int len = strlen(mode_option), i, err = 0;
+	u8 res_specified = 0, bpp_specified = 0, refresh_specified = 0,
+	   yres_specified = 0;
+
+	for (i = len-1; i >= 0; i--) {
+ 		switch (mode_option[i]) {
+		case '@':
+    			len = i;
+    			if (!refresh_specified && !bpp_specified &&
+			    !yres_specified) {
+				*refresh = simple_strtoul(&mode_option[i+1],
+							  NULL, 0);
+				refresh_specified = 1;
+			} else
+				goto out;
+		    	break;
+		case '-':
+			len = i;
+		    	if (!bpp_specified && !yres_specified) {
+			    	*bpp = simple_strtoul(&mode_option[i+1],
+						      NULL, 0);
+				bpp_specified = 1;
+		    	} else
+				goto out;
+		    	break;
+		case 'x':
+			if (!yres_specified) {
+				*yres = simple_strtoul(&mode_option[i+1],
+						       NULL, 0);
+				yres_specified = 1;
+		    	} else
+				goto out;
+		    	break;
+		case '0'...'9':
+			break;
+		default:
+			goto out;
+	    	}
+	}
+
+	if (i < 0 && yres_specified) {
+		*xres = simple_strtoul(mode_option, NULL, 0);
+	   	res_specified = 1;
+	}
+
+out:	if (!res_specified || !yres_specified) {
+		printk(KERN_ERR "vesafb: invalid resolution, "
+				"%s not specified\n",
+				(!res_specified) ? "width" : "height");
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+static int __init vesafb_init_set_mode(struct fb_info *info)
+{
+	struct fb_videomode *fbmode;
+	struct fb_videomode mode;
+	int i, modeid, refresh = 0;
+	u8 refresh_specified = 0;
+
+	if (!mode_option)
+		mode_option = CONFIG_FB_VESA_DEFAULT_MODE;
+
+	if (vbemode > 0) {
+		for (i = 0; i < vbe_modes_cnt; i++) {
+			if (vbe_modes[i].mode_id == vbemode) {
+				info->var.vmode = FB_VMODE_NONINTERLACED;
+				info->var.sync = FB_SYNC_VERT_HIGH_ACT;
+				vesafb_setup_var(&info->var, info,
+						 &vbe_modes[i]);
+				fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON,
+					    60, &info->var, info);
+				/* With pixclock set to 0, the default BIOS
+				 * timings will be used in set_par(). */
+				info->var.pixclock = 0;
+				modeid = i;
+				goto out;
+			}
+		}
+		printk(KERN_INFO "specified VBE mode %d not found\n",
+				 vbemode);
+		vbemode = 0;
+	}
+
+	/* Decode the mode specified on the kernel command line. We save
+	 * the depth into bits_per_pixel, which is wrong, but will work
+	 * anyway. */
+	if (decode_mode(&info->var.xres, &info->var.yres,
+			&info->var.bits_per_pixel, &refresh))
+		return -EINVAL;
+	if (refresh)
+		refresh_specified = 1;
+	else
+		refresh = 60;
+
+	/* Look for a matching VBE mode. We can live if an exact match
+	 * cannot be found. */
+	modeid = vesafb_find_vbe_mode(info->var.xres, info->var.yres,
+			              info->var.bits_per_pixel, 0);
+
+	if (modeid == -1) {
+		return -EINVAL;
+	} else {
+		info->var.vmode = FB_VMODE_NONINTERLACED;
+		info->var.sync = FB_SYNC_VERT_HIGH_ACT;
+		vesafb_setup_var(&info->var, info, &vbe_modes[modeid]);
+	}
+	if (vbe_ib.vbe_version < 0x0300) {
+		fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
+			    &info->var, info);
+		goto out;
+	}
+	if (!gtf) {
+		struct fb_videomode tmode;
+
+		if (refresh_specified) {
+			fb_var_to_videomode(&tmode, &info->var);
+			tmode.refresh = refresh;
+			fbmode = fb_find_nearest_mode(&tmode, 
+						      &info->modelist);
+		} else
+			fbmode = fb_find_best_mode(&info->var, 
+						   &info->modelist);
+
+		if (fbmode->xres == info->var.xres &&
+		    fbmode->yres == info->var.yres &&
+		    !(fbmode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))
+		    && (!refresh_specified || 
+		    abs(refresh - fbmode->refresh) <= 5)) {
+			fb_videomode_to_var(&info->var, fbmode);
+			return modeid;
+		}
+	}
+	i = FB_MAXTIMINGS;
+	if (!info->monspecs.gtf)
+		i = FB_IGNOREMON | FB_VSYNCTIMINGS;
+	else if (refresh_specified)
+		i = FB_VSYNCTIMINGS;
+	if (!fb_get_mode(i, refresh, &info->var, info))
+		goto out;
+	if (info->monspecs.gtf &&
+	    !fb_get_mode(FB_MAXTIMINGS, 0, &info->var, info))
+		goto out;
+	/* Use default refresh rate */
+	printk(KERN_WARNING "vesafb: using default BIOS refresh rate\n");
+	info->var.pixclock = 0;
+
+out:
+	fb_var_to_videomode(&mode, &info->var);
+	fb_add_videomode(&mode, &info->modelist);
+	return modeid;
+}
+
+static int __init vesafb_probe(struct platform_device *dev)
+{
+	char entry[16];
+	struct fb_info *info;
+	struct vesafb_mode_ib *mode = NULL;
+	int err = 0, i, h;
+	unsigned int size_vmode;
+	unsigned int size_remap;
+	unsigned int size_total;
+
+	vesafb_info = info = framebuffer_alloc(sizeof(struct vesafb_par) +
+			                       sizeof(u32) * 256, &dev->dev);
+	if (!info)
+	 	return -ENOMEM;
+
+	if (vesafb_wait_for_thread()) {
+		printk(KERN_ERR "vesafb: vesafb thread not running\n");
+		framebuffer_release(info);
+		return -EINVAL;
+	}
+
+	if (vesafb_vbe_init(info)) {
+		printk(KERN_ERR "vesafb: vbe_init failed\n");
+		err = -EINVAL;
+		goto out;
+	}
+
+	vesafb_fix.ypanstep  = ypan     ? 1 : 0;
+	vesafb_fix.ywrapstep = (ypan>1) ? 1 : 0;
+
+	info->pseudo_palette = ((u8*)info->par + sizeof(struct vesafb_par));
+	info->fbops = &vesafb_ops;
+	info->var = vesafb_defined;
+	info->fix = vesafb_fix;
+
+	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+		err = -ENXIO;
+		goto out;
+	}
+
+	i = vesafb_init_set_mode(info);
+	if (i < 0) {
+		err = -EINVAL;
+		goto out_cmap;
+	} else
+		mode = &vbe_modes[i];
+
+	/* Disable blanking if the user requested so. */
+	if (!blank) {
+		info->fbops->fb_blank = NULL;
+	}
+
+	/* Find out how much IO memory is required for the mode with
+	 * the highest resolution. */
+	size_remap = 0;
+	for (i = 0; i < vbe_modes_cnt; i++) {
+		h = vbe_modes[i].bytes_per_scan_line * vbe_modes[i].y_res;
+		if (h > size_remap)
+			size_remap = h;
+	}
+	size_remap *= 2;
+
+	/*   size_vmode -- that is the amount of memory needed for the
+	 *                 used video mode, i.e. the minimum amount of
+	 *                 memory we need. */
+	if (mode != NULL) {
+		size_vmode = info->var.yres * mode->bytes_per_scan_line;
+	} else {
+		size_vmode = info->var.yres * info->var.xres *
+			     ((info->var.bits_per_pixel + 7) >> 3);
+	}
+
+	/*   size_total -- all video memory we have. Used for mtrr
+	 *                 entries, ressource allocation and bounds
+	 *                 checking. */
+	size_total = vbe_ib.total_memory * 65536;
+	if (vram_total)
+		size_total = vram_total * 1024 * 1024;
+	if (size_total < size_vmode)
+		size_total = size_vmode;
+	((struct vesafb_par*)(info->par))->mem_total = size_total;
+
+	/*   size_remap -- the amount of video memory we are going to
+	 *                 use for vesafb.  With modern cards it is no
+	 *                 option to simply use size_total as th
+	 *                 wastes plenty of kernel address space. */
+	if (vram_remap)
+		size_remap = vram_remap * 1024 * 1024;
+	if (size_remap < size_vmode)
+		size_remap = size_vmode;
+	if (size_remap > size_total)
+		size_remap = size_total;
+
+	info->fix.smem_len = size_remap;
+	info->fix.smem_start = mode->phys_base_ptr;
+
+	/* We have to set it here, because when setup_var() was called,
+	 * smem_len wasn't defined yet. */
+	info->var.yres_virtual = info->fix.smem_len /
+				 mode->bytes_per_scan_line;
+
+	if (ypan && info->var.yres_virtual > info->var.yres) {
+		printk(KERN_INFO "vesafb: scrolling: %s "
+		       "using protected mode interface, "
+		       "yres_virtual=%d\n",
+		       (ypan > 1) ? "ywrap" : "ypan",info->var.yres_virtual);
+	} else {
+		printk(KERN_INFO "vesafb: scrolling: redraw\n");
+		info->var.yres_virtual = info->var.yres;
+		ypan = 0;
+	}
+
+	info->flags = FBINFO_FLAG_DEFAULT |
+		(ypan) ? FBINFO_HWACCEL_YPAN : 0;
+
+	if (!ypan)
+		info->fbops->fb_pan_display = NULL;
+
+	if (!request_mem_region(info->fix.smem_start, size_total, "vesafb")) {
+		printk(KERN_WARNING "vesafb: cannot reserve video memory at "
+		       "0x%lx\n", info->fix.smem_start);
+		/* We cannot make this fatal. Sometimes this comes from magic
+		   spaces our resource handlers simply don't know about. */
+	}
+
+	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+
+	if (!info->screen_base) {
+		printk(KERN_ERR
+		       "vesafb: abort, cannot ioremap video memory "
+		       "0x%x @ 0x%lx\n",
+		       info->fix.smem_len, info->fix.smem_start);
+		err = -EIO;
+		goto out_mem;
+ 	}
+
+	/* Request failure does not faze us, as vgacon probably has this
+	   region already (FIXME) */
+	request_region(0x3c0, 32, "vesafb");
+
+#ifdef CONFIG_MTRR
+	if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
+		int temp_size = size_total;
+		unsigned int type = 0;
+
+		switch (mtrr) {
+		case 1:
+			type = MTRR_TYPE_UNCACHABLE;
+			break;
+		case 2:
+			type = MTRR_TYPE_WRBACK;
+			break;
+		case 3:
+			type = MTRR_TYPE_WRCOMB;
+			break;
+		case 4:
+			type = MTRR_TYPE_WRTHROUGH;
+			break;
+		default:
+			type = 0;
+			break;
+		}
+
+		if (type) {
+			int rc;
+
+			/* Find the largest power-of-two */
+			while (temp_size & (temp_size - 1))
+				temp_size &= (temp_size - 1);
+
+			/* Try and find a power of two to add */
+			do {
+				rc = mtrr_add(info->fix.smem_start,
+					      temp_size, type, 1);
+				temp_size >>= 1;
+			} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
+  		}
+  	}
+#endif /* CONFIG_MTRR */
+
+	if (register_framebuffer(info) < 0) {
+		printk(KERN_ERR
+		       "vesafb: failed to register framebuffer device\n");
+		err = -EINVAL;
+		goto out_mem;
+	}
+
+  	printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
+	       "using %dk, total %dk\n", info->fix.smem_start,
+	       info->screen_base, size_remap/1024, size_total/1024);
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+	       info->fix.id);
+
+	sprintf(entry, "fb%d", info->node);
+	proc_mkdir(entry, 0);
+
+	sprintf(entry, "fb%d/modes", info->node);
+	create_proc_read_entry(entry, 0, 0, vesafb_read_proc_modes, NULL);
+
+	sprintf(entry, "fb%d/vbe_info", info->node);
+	create_proc_read_entry(entry, 0, 0, vesafb_read_proc_vbe_info, NULL);
+	return 0;
+
+out_mem:
+	release_mem_region(info->fix.smem_start, size_total);
+	if (!list_empty(&info->modelist))
+		fb_destroy_modelist(&info->modelist);
+	fb_destroy_modedb(info->monspecs.modedb);
+out_cmap:
+	fb_dealloc_cmap(&info->cmap);
+out:
+	framebuffer_release(info);
+	vesafb_info = NULL;
+	kfree(vbe_modes);
+	vbe_modes = NULL;
+	return err;
+}
+
+int __init vesafb_init(void)
+{
+	int ret;
+#ifndef MODULE
+	char *option = NULL;
+
+	if (fb_get_options("vesafb", &option))
+		return -ENODEV;
+	vesafb_setup(option);
+#endif
+	ret = platform_driver_register(&vesafb_driver);
+
+	if (!ret) {
+		vesafb_device = platform_device_alloc("vesafb", 0);
+
+		if (vesafb_device)
+			ret = platform_device_add(vesafb_device);
+		else
+			ret = -ENOMEM;
+
+		if (ret) {
+			platform_device_put(vesafb_device);
+			platform_driver_unregister(&vesafb_driver);
+		}
+	}
+	return ret;
+}
+
+module_init(vesafb_init);
+
+#ifdef MODULE
+void __exit vesafb_exit(void)
+{
+	char entry[16];
+
+	if (vesafb_info)
+		unregister_framebuffer(vesafb_info);
+
+	platform_device_unregister(vesafb_device);
+	platform_driver_unregister(&vesafb_driver);
+
+	if (vesafb_info) {
+		struct vesafb_par *par = (struct vesafb_par*)vesafb_info->par;
+
+		sprintf(entry, "fb%d/modes", vesafb_info->node);
+		remove_proc_entry(entry, NULL);
+
+		sprintf(entry, "fb%d/vbe_info", vesafb_info->node);
+		remove_proc_entry(entry, NULL);
+
+		sprintf(entry, "fb%d", vesafb_info->node);
+		remove_proc_entry(entry, NULL);
+
+		iounmap(vesafb_info->screen_base);
+		release_mem_region(vesafb_info->fix.smem_start,
+				   par->mem_total);
+		fb_dealloc_cmap(&vesafb_info->cmap);
+		if (!list_empty(&vesafb_info->modelist))
+			fb_destroy_modelist(&vesafb_info->modelist);
+		fb_destroy_modedb(vesafb_info->monspecs.modedb);
+		framebuffer_release(vesafb_info);
+	}
+
+	if (vbe_modes != NULL)
+		kfree(vbe_modes);
+}
+
+module_exit(vesafb_exit);
+
+static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
+{
+	return 0;
+}
+static inline int param_set_scroll(const char *val, struct kernel_param *kp)
+{
+	ypan = 0;
+
+	if (! strcmp(val, "redraw"))
+		ypan = 0;
+	else if (! strcmp(val, "ypan"))
+		ypan = 1;
+	else if (! strcmp(val, "ywrap"))
+		ypan = 2;
+
+	return 0;
+}
+
+#define param_check_scroll(name, p) __param_check(name, p, void);
+
+module_param_named(scroll, ypan, scroll, 0);
+MODULE_PARM_DESC(scroll,"Scrolling mode, set to 'redraw', 'ypan' or 'ywrap'");
+module_param_named(vgapal, pmi_setpal, invbool, 0);
+MODULE_PARM_DESC(vgapal,"bool: set palette using VGA registers");
+module_param_named(pmipal, pmi_setpal, bool, 0);
+MODULE_PARM_DESC(pmipal,"bool: set palette using PMI calls");
+module_param_named(nomtrr, mtrr, invbool, 0);
+MODULE_PARM_DESC(nomtrr,"bool: disable use of MTRR registers");
+module_param(blank, bool, 1);
+MODULE_PARM_DESC(blank,"bool: enable hardware blanking");
+module_param(nocrtc, bool, 0);
+MODULE_PARM_DESC(nocrtc,"bool: ignore CRTC timings when setting modes");
+module_param(noedid, bool, 0);
+MODULE_PARM_DESC(noedid,"bool: ignore EDID-provided monitor limits "
+		        "when setting modes");
+module_param(gtf, bool, 0);
+MODULE_PARM_DESC(gtf,"bool: force use of VESA GTF to calculate mode timings");
+module_param(vram_remap, uint, 0);
+MODULE_PARM_DESC(vram_remap,"Set amount of video memory to be used [MiB]");
+module_param(vram_total, uint, 0);
+MODULE_PARM_DESC(vram_total,"Set total amount of video memoery [MiB]");
+module_param(maxclk, ushort, 0);
+MODULE_PARM_DESC(maxclk,"Maximum pixelclock [MHz], overrides EDID data");
+module_param(maxhf, ushort, 0);
+MODULE_PARM_DESC(maxhf,"Maximum horizontal frequency [kHz], "
+		       "overrides EDID data");
+module_param(maxvf, ushort, 0);
+MODULE_PARM_DESC(maxvf,"Maximum vertical frequency [Hz], "
+		       "overrides EDID data");
+module_param_named(mode, mode_option, charp, 0);
+MODULE_PARM_DESC(mode, "Specify resolution as "
+		       "\"<xres>x<yres>[-<bpp>][@<refresh>]\"");
+module_param(vbemode, ushort, 0);
+MODULE_PARM_DESC(vbemode,"VBE mode number to set, overrides 'mode' setting");
+
+#endif /* MODULE */
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal Januszewski");
+MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");
+
diff -urN newtree/include/linux/sched.h newtree.2/include/linux/sched.h
--- newtree/include/linux/sched.h	2006-08-04 09:29:20.000000000 -0700
+++ newtree.2/include/linux/sched.h	2006-08-04 14:07:26.000000000 -0700
@@ -1375,6 +1375,8 @@
 extern struct mm_struct *get_task_mm(struct task_struct *task);
 /* Remove the current tasks stale references to the old mm_struct */
 extern void mm_release(struct task_struct *, struct mm_struct *);
+/* Create a new mm for a kernel thread */
+extern int set_new_mm(void);
 
 extern int  copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
 extern void flush_thread(void);
diff -urN newtree/include/video/vesa.h newtree.2/include/video/vesa.h
--- newtree/include/video/vesa.h	1969-12-31 16:00:00.000000000 -0800
+++ newtree.2/include/video/vesa.h	2006-08-04 14:07:26.000000000 -0700
@@ -0,0 +1,150 @@
+#if 0
+#define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , \
+						  ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define p_crtc(arg) ((struct vesafb_crtc_ib*)(arg))
+#define p_vbe(arg)  ((struct vesafb_vbe_ib*)(arg))
+#define p_mode(arg) ((struct vesafb_mode_ib*)(arg))
+
+struct vesafb_task {
+	u8 flags;
+	void *buf;
+	int buf_len;
+	struct vm86_regs regs;
+	struct list_head node;
+	struct completion done;
+};
+
+/* Vesafb task flags and masks */
+#define TF_CALL		0x00
+#define TF_EXIT		0x01
+#define TF_GETVBEIB	0x02
+#define TF_BUF_DI	0x04
+#define TF_BUF_BX	0x08
+#define TF_RETURN_BUF	0x10
+
+/* Macros and functions for manipulating vesafb tasks */
+#define vesafb_create_task(task)				\
+do { 								\
+	task = kmalloc(sizeof(struct vesafb_task), GFP_ATOMIC); \
+	if (task) 						\
+		memset(task, 0, sizeof(struct vesafb_task));	\
+	init_completion(&task->done);				\
+} while (0)
+
+#define vesafb_wait_for_task(task) 	wait_for_completion(&task->done);
+#define vesafb_reset_task(task)		init_completion(&task->done);
+int vesafb_queue_task(struct vesafb_task *task);
+
+/* Functions for controlling the vesafb thread */
+int vesafb_wait_for_thread(void);
+
+#define VBE_CAP_CAN_SWITCH_DAC	0x01
+#define VBE_CAP_VGACOMPAT	0x02
+
+/* This struct is 512 bytes long */
+struct vesafb_vbe_ib {
+	char vbe_signature[4];
+	u16  vbe_version;
+	u32  oem_string_ptr;
+	u32  capabilities;
+	u32  mode_list_ptr;
+	u16  total_memory;
+	u16  oem_software_rev;
+	u32  oem_vendor_name_ptr;
+	u32  oem_product_name_ptr;
+	u32  oem_product_rev_ptr;
+	u8   reserved[222];
+	char oem_data[256];
+} __attribute__ ((packed));
+
+struct vesafb_crtc_ib {
+	u16 horiz_total;
+	u16 horiz_start;
+	u16 horiz_end;
+	u16 vert_total;
+	u16 vert_start;
+	u16 vert_end;
+	u8  flags;
+	u32 pixel_clock;
+	u16 refresh_rate;
+	u8  reserved[40];
+} __attribute__ ((packed));
+
+#define VBE_MODE_VGACOMPAT	0x20
+
+struct vesafb_mode_ib {
+	/* for all VBE revisions */
+	u16 mode_attr;
+	u8  winA_attr;
+	u8  winB_attr;
+	u16 win_granularity;
+	u16 win_size;
+	u16 winA_seg;
+	u16 winB_seg;
+	u32 win_func_ptr;
+	u16 bytes_per_scan_line;
+
+	/* for VBE 1.2+ */
+	u16 x_res;
+	u16 y_res;
+	u8  x_char_size;
+	u8  y_char_size;
+	u8  planes;
+	u8  bits_per_pixel;
+	u8  banks;
+	u8  memory_model;
+	u8  bank_size;
+	u8  image_pages;
+	u8  reserved1;
+
+	/* Direct color fields for direct/6 and YUV/7 memory models. */
+	/* Offsets are bit positions of lsb in the mask. */
+	u8  red_len;
+	u8  red_off;
+	u8  green_len;
+	u8  green_off;
+	u8  blue_len;
+	u8  blue_off;
+	u8  rsvd_len;
+	u8  rsvd_off;
+	u8  direct_color_info;	/* direct color mode attributes */
+
+	/* for VBE 2.0+ */
+	u32 phys_base_ptr;
+	u8  reserved2[6];
+
+	/* for VBE 3.0+ */
+	u16 lin_bytes_per_scan_line;
+	u8  bnk_image_pages;
+	u8  lin_image_pages;
+	u8  lin_red_len;
+	u8  lin_red_off;
+	u8  lin_green_len;
+	u8  lin_green_off;
+	u8  lin_blue_len;
+	u8  lin_blue_off;
+	u8  lin_rsvd_len;
+	u8  lin_rsvd_off;
+	u32 max_pixel_clock;
+	u16 mode_id;
+	u8  depth;
+} __attribute__ ((packed));
+
+struct vesafb_pal_entry {
+	u_char blue, green, red, pad;
+} __attribute__ ((packed));
+
+struct vesafb_par {
+	u8 *vbe_state;
+	int vbe_state_size;
+	atomic_t ref_count;
+	
+	u32 mem_total;
+	int mode_idx;
+	struct vesafb_crtc_ib crtc;
+};
+
diff -urN newtree/kernel/fork.c newtree.2/kernel/fork.c
--- newtree/kernel/fork.c	2006-08-04 09:29:20.000000000 -0700
+++ newtree.2/kernel/fork.c	2006-08-04 14:07:26.000000000 -0700
@@ -95,6 +95,7 @@
 
 /* SLAB cache for vm_area_struct structures */
 kmem_cache_t *vm_area_cachep;
+EXPORT_SYMBOL_GPL(vm_area_cachep);
 
 /* SLAB cache for mm_struct structures (tsk->mm) */
 static kmem_cache_t *mm_cachep;
@@ -387,6 +388,40 @@
 EXPORT_SYMBOL_GPL(mmput);
 
 /**
+ * set_new_mm - allocate, init and activate a new mm for a kernel thread
+ */
+int set_new_mm(void)
+{
+	struct mm_struct *mm;
+	struct task_struct *tsk = current;
+	struct mm_struct *active_mm;
+
+	mm = mm_alloc();
+	if (!mm)
+		goto fail_nomem;
+	if (init_new_context(current,mm))
+		goto fail_nocontext;
+
+	task_lock(tsk);
+	tsk->flags |= PF_BORROWED_MM;	
+	active_mm = tsk->active_mm;
+	current->mm = mm;
+	current->active_mm = mm;
+	activate_mm(active_mm, mm);
+	task_unlock(current);
+
+	/* Drop the previous active_mm */
+	mmdrop(active_mm);
+	return 0;
+	
+fail_nocontext:
+	mmdrop(mm);
+fail_nomem:
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(set_new_mm);
+
+/**
  * get_task_mm - acquire a reference to the task's mm
  *
  * Returns %NULL if the task has no mm.  Checks PF_BORROWED_MM (meaning
diff -urN newtree/lib/Kconfig.debug~ newtree.2/lib/Kconfig.debug~
--- newtree/lib/Kconfig.debug~	2006-08-02 07:14:23.000000000 -0700
+++ newtree.2/lib/Kconfig.debug~	1969-12-31 16:00:00.000000000 -0800
@@ -1,432 +0,0 @@
-
-config PRINTK_TIME
-	bool "Show timing information on printks"
-	help
-	  Selecting this option causes timing information to be
-	  included in printk output.  This allows you to measure
-	  the interval between kernel operations, including bootup
-	  operations.  This is useful for identifying long delays
-	  in kernel startup.
-
-config ENABLE_MUST_CHECK
-	bool "Enable __must_check logic"
-	default y
-	help
-	  Enable the __must_check logic in the kernel build.  Disable this to
-	  suppress the "warning: ignoring return value of 'foo', declared with
-	  attribute warn_unused_result" messages.
-
-config MAGIC_SYSRQ
-	bool "Magic SysRq key"
-	depends on !UML
-	help
-	  If you say Y here, you will have some control over the system even
-	  if the system crashes for example during kernel debugging (e.g., you
-	  will be able to flush the buffer cache to disk, reboot the system
-	  immediately or dump some status information). This is accomplished
-	  by pressing various keys while holding SysRq (Alt+PrintScreen). It
-	  also works on a serial console (on PC hardware at least), if you
-	  send a BREAK and then within 5 seconds a command keypress. The
-	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
-	  unless you really know what this hack does.
-
-config UNUSED_SYMBOLS
-	bool "Enable unused/obsolete exported symbols"
-	default y if X86
-	help
-	  Unused but exported symbols make the kernel needlessly bigger.  For
-	  that reason most of these unused exports will soon be removed.  This
-	  option is provided temporarily to provide a transition period in case
-	  some external kernel module needs one of these symbols anyway. If you
-	  encounter such a case in your module, consider if you are actually
-	  using the right API.  (rationale: since nobody in the kernel is using
-	  this in a module, there is a pretty good chance it's actually the
-	  wrong interface to use).  If you really need the symbol, please send a
-	  mail to the linux kernel mailing list mentioning the symbol and why
-	  you really need it, and what the merge plan to the mainline kernel for
-	  your module is.
-
-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_SHIRQ
-	bool "Debug shared IRQ handlers"
-	depends on DEBUG_KERNEL && GENERIC_HARDIRQS
-	help
-	  Enable this to generate a spurious interrupt as soon as a shared
-	  interrupt handler is registered, and just before one is deregistered.
-	  Drivers ought to be able to handle interrupts coming in at those
-	  points; some don't and need to be caught.
-
-config LOG_BUF_SHIFT
-	int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
-	range 12 21
-	default 17 if S390 || LOCKDEP
-	default 16 if X86_NUMAQ || IA64
-	default 15 if SMP
-	default 14
-	help
-	  Select kernel log buffer size as a power of 2.
-	  Defaults and Examples:
-	  	     17 => 128 KB for S/390
-		     16 => 64 KB for x86 NUMAQ or IA-64
-	             15 => 32 KB for SMP
-	             14 => 16 KB for uniprocessor
-		     13 =>  8 KB
-		     12 =>  4 KB
-
-config DETECT_SOFTLOCKUP
-	bool "Detect Soft Lockups"
-	depends on DEBUG_KERNEL
-	default y
-	help
-	  Say Y here to enable the kernel to detect "soft lockups",
-	  which are bugs that cause the kernel to loop in kernel
-	  mode for more than 10 seconds, without giving other tasks a
-	  chance to run.
-
-	  When a soft-lockup is detected, the kernel will print the
-	  current stack trace (which you should report), but the
-	  system will stay locked up. This feature has negligible
-	  overhead.
-
-	  (Note that "hard lockups" are separate type of bugs that
-	   can be detected via the NMI-watchdog, on platforms that
-	   support it.)
-
-config SCHEDSTATS
-	bool "Collect scheduler statistics"
-	depends on DEBUG_KERNEL && PROC_FS
-	help
-	  If you say Y here, additional code will be inserted into the
-	  scheduler and related routines to collect statistics about
-	  scheduler behavior and provide them in /proc/schedstat.  These
-	  stats may be useful for both tuning and debugging the scheduler
-	  If you aren't debugging the scheduler or trying to tune a specific
-	  application, you can say N to avoid the very slight overhead
-	  this adds.
-
-config DEBUG_SLAB
-	bool "Debug slab memory allocations"
-	depends on DEBUG_KERNEL && SLAB
-	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. This can make kmalloc/kfree-intensive workloads much slower.
-
-config DEBUG_SLAB_LEAK
-	bool "Slab memory leak debugging"
-	depends on DEBUG_SLAB
-	default y
-	help
-	  Enable /proc/slab_allocators - provides detailed information about
-	  which parts of the kernel are using slab objects.  May be used for
-	  tracking memory leaks and for instrumenting memory usage.
-
-config DEBUG_PREEMPT
-	bool "Debug preemptible kernel"
-	depends on DEBUG_KERNEL && PREEMPT && TRACE_IRQFLAGS_SUPPORT
-	default y
-	help
-	  If you say Y here then the kernel will use a debug variant of the
-	  commonly used smp_processor_id() function and will print warnings
-	  if kernel code uses it in a preemption-unsafe way. Also, the kernel
-	  will detect preemption count underflows.
-
-config DEBUG_RT_MUTEXES
-	bool "RT Mutex debugging, deadlock detection"
-	depends on DEBUG_KERNEL && RT_MUTEXES
-	help
-	 This allows rt mutex semantics violations and rt mutex related
-	 deadlocks (lockups) to be detected and reported automatically.
-
-config DEBUG_PI_LIST
-	bool
-	default y
-	depends on DEBUG_RT_MUTEXES
-
-config RT_MUTEX_TESTER
-	bool "Built-in scriptable tester for rt-mutexes"
-	depends on DEBUG_KERNEL && RT_MUTEXES
-	help
-	  This option enables a rt-mutex tester.
-
-config DEBUG_SPINLOCK
-	bool "Spinlock and rw-lock debugging: basic checks"
-	depends on DEBUG_KERNEL
-	help
-	  Say Y here and build SMP to catch missing spinlock initialization
-	  and certain other kinds of spinlock errors commonly made.  This is
-	  best used in conjunction with the NMI watchdog so that spinlock
-	  deadlocks are also debuggable.
-
-config DEBUG_MUTEXES
-	bool "Mutex debugging: basic checks"
-	depends on DEBUG_KERNEL
-	help
-	 This feature allows mutex semantics violations to be detected and
-	 reported.
-
-config DEBUG_RWSEMS
-	bool "RW-sem debugging: basic checks"
-	depends on DEBUG_KERNEL
-	help
-	 This feature allows read-write semaphore semantics violations to
-	 be detected and reported.
-
-config DEBUG_LOCK_ALLOC
-	bool "Lock debugging: detect incorrect freeing of live locks"
-	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
-	select DEBUG_SPINLOCK
-	select DEBUG_MUTEXES
-	select DEBUG_RWSEMS
-	select LOCKDEP
-	help
-	 This feature will check whether any held lock (spinlock, rwlock,
-	 mutex or rwsem) is incorrectly freed by the kernel, via any of the
-	 memory-freeing routines (kfree(), kmem_cache_free(), free_pages(),
-	 vfree(), etc.), whether a live lock is incorrectly reinitialized via
-	 spin_lock_init()/mutex_init()/etc., or whether there is any lock
-	 held during task exit.
-
-config PROVE_LOCKING
-	bool "Lock debugging: prove locking correctness"
-	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
-	select LOCKDEP
-	select DEBUG_SPINLOCK
-	select DEBUG_MUTEXES
-	select DEBUG_RWSEMS
-	select DEBUG_LOCK_ALLOC
-	default n
-	help
-	 This feature enables the kernel to prove that all locking
-	 that occurs in the kernel runtime is mathematically
-	 correct: that under no circumstance could an arbitrary (and
-	 not yet triggered) combination of observed locking
-	 sequences (on an arbitrary number of CPUs, running an
-	 arbitrary number of tasks and interrupt contexts) cause a
-	 deadlock.
-
-	 In short, this feature enables the kernel to report locking
-	 related deadlocks before they actually occur.
-
-	 The proof does not depend on how hard and complex a
-	 deadlock scenario would be to trigger: how many
-	 participant CPUs, tasks and irq-contexts would be needed
-	 for it to trigger. The proof also does not depend on
-	 timing: if a race and a resulting deadlock is possible
-	 theoretically (no matter how unlikely the race scenario
-	 is), it will be proven so and will immediately be
-	 reported by the kernel (once the event is observed that
-	 makes the deadlock theoretically possible).
-
-	 If a deadlock is impossible (i.e. the locking rules, as
-	 observed by the kernel, are mathematically correct), the
-	 kernel reports nothing.
-
-	 NOTE: this feature can also be enabled for rwlocks, mutexes
-	 and rwsems - in which case all dependencies between these
-	 different locking variants are observed and mapped too, and
-	 the proof of observed correctness is also maintained for an
-	 arbitrary combination of these separate locking variants.
-
-	 For more details, see Documentation/lockdep-design.txt.
-
-config LOCKDEP
-	bool
-	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
-	select STACKTRACE
-	select FRAME_POINTER
-	select KALLSYMS
-	select KALLSYMS_ALL
-
-config DEBUG_LOCKDEP
-	bool "Lock dependency engine debugging"
-	depends on DEBUG_KERNEL && LOCKDEP
-	help
-	  If you say Y here, the lock dependency engine will do
-	  additional runtime checks to debug itself, at the price
-	  of more runtime overhead.
-
-config TRACE_IRQFLAGS
-	depends on DEBUG_KERNEL
-	bool
-	default y
-	depends on TRACE_IRQFLAGS_SUPPORT
-	depends on PROVE_LOCKING
-
-config DEBUG_SPINLOCK_SLEEP
-	bool "Spinlock debugging: sleep-inside-spinlock checking"
-	depends on DEBUG_KERNEL
-	help
-	  If you say Y here, various routines which may sleep will become very
-	  noisy if they are called with a spinlock held.
-
-config DEBUG_LOCKING_API_SELFTESTS
-	bool "Locking API boot-time self-tests"
-	depends on DEBUG_KERNEL
-	help
-	  Say Y here if you want the kernel to run a short self-test during
-	  bootup. The self-test checks whether common types of locking bugs
-	  are detected by debugging mechanisms or not. (if you disable
-	  lock debugging then those bugs wont be detected of course.)
-	  The following locking APIs are covered: spinlocks, rwlocks,
-	  mutexes and rwsems.
-
-config STACKTRACE
-	bool
-	depends on DEBUG_KERNEL
-	depends on STACKTRACE_SUPPORT
-
-config DEBUG_KOBJECT
-	bool "kobject debugging"
-	depends on DEBUG_KERNEL
-	help
-	  If you say Y here, some extra kobject debugging messages will be sent
-	  to the syslog. 
-
-config DEBUG_HIGHMEM
-	bool "Highmem debugging"
-	depends on DEBUG_KERNEL && HIGHMEM
-	help
-	  This options enables addition error checking for high memory systems.
-	  Disable for production systems.
-
-config DEBUG_BUGVERBOSE
-	bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
-	depends on BUG
-	depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
-	default !EMBEDDED
-	help
-	  Say Y here to make BUG() panics output the file name and line number
-	  of the BUG call as well as the EIP and oops trace.  This aids
-	  debugging but costs about 70-100K of memory.
-
-config DEBUG_INFO
-	bool "Compile the kernel with debug info"
-	depends on DEBUG_KERNEL
-	help
-          If you say Y here the resulting kernel image will include
-	  debugging info resulting in a larger kernel image.
-	  Say Y here only if you plan to debug the kernel.
-
-	  If unsure, say N.
-
-config PAGE_OWNER
-	bool "Track page owner"
-	depends on DEBUG_KERNEL && X86
-	help
-	  This keeps track of what call chain is the owner of a page, may
-	  help to find bare alloc_page(s) leaks. Eats a fair amount of memory.
-	  See Documentation/page_owner.c for user-space helper.
-
-	  If unsure, say N.
-
-config DEBUG_FS
-	bool "Debug Filesystem"
-	depends on SYSFS
-	help
-	  debugfs is a virtual file system that kernel developers use to put
-	  debugging files into.  Enable this option to be able to read and
-	  write to these files.
-
-	  If unsure, say N.
-
-config DEBUG_VM
-	bool "Debug VM"
-	depends on DEBUG_KERNEL
-	help
-	  Enable this to turn on extended checks in the virtual-memory system
-          that may impact performance.
-
-	  If unsure, say N.
-
-config DEBUG_LIST
-	bool "Debug linked list manipulation"
-	depends on DEBUG_KERNEL
-	help
-	  Enable this to turn on extended checks in the linked-list
-	  walking routines.
-
-	  If unsure, say N.
-
-config FRAME_POINTER
-	bool "Compile the kernel with frame pointers"
-	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32)
-	default y
-	help
-	  If you say Y here the resulting kernel image will be slightly larger
-	  and slower, but it might give very useful debugging information on
-	  some architectures or if you use external debuggers.
-	  If you don't debug the kernel, you can say N.
-
-config UNWIND_INFO
-	bool "Compile the kernel with frame unwind information"
-	depends on !IA64 && !PARISC
-	depends on !MODULES || !(MIPS || PPC || SUPERH || V850)
-	help
-	  If you say Y here the resulting kernel image will be slightly larger
-	  but not slower, and it will give very useful debugging information.
-	  If you don't debug the kernel, you can say N, but we may not be able
-	  to solve problems without frame unwind information or frame pointers.
-
-config STACK_UNWIND
-	bool "Stack unwind support"
-	depends on UNWIND_INFO
-	depends on X86
-	help
-	  This enables more precise stack traces, omitting all unrelated
-	  occurrences of pointers into kernel code from the dump.
-
-config	PROFILE_LIKELY
-	bool "Record return values from likely/unlikely macros"
-	default n
-	help
-	  Adds profiling on likely/unlikly macros . To see the
-	  results of the profiling you can view the following,
-		/proc/likely_prof
-
-config FORCED_INLINING
-	bool "Force gcc to inline functions marked 'inline'"
-	depends on DEBUG_KERNEL
-	default y
-	help
-	  This option determines if the kernel forces gcc to inline the functions
-	  developers have marked 'inline'. Doing so takes away freedom from gcc to
-	  do what it thinks is best, which is desirable for the gcc 3.x series of
-	  compilers. The gcc 4.x series have a rewritten inlining algorithm and
-	  disabling this option will generate a smaller kernel there. Hopefully
-	  this algorithm is so good that allowing gcc4 to make the decision can
-	  become the default in the future, until then this option is there to
-	  test gcc for this.
-
-config DEBUG_SYNCHRO_TEST
-	tristate "Synchronisation primitive testing module"
-	depends on DEBUG_KERNEL
-	default n
-	help
-	  This option provides a kernel module that can thrash the sleepable
-	  synchronisation primitives (mutexes and semaphores).
-
-	  You should say N or M here. Whilst the module can be built in, it's
-	  not recommended as it requires module parameters supplying to get it
-	  to do anything.
-
-	  See Documentation/synchro-test.txt.
-
-config RCU_TORTURE_TEST
-	tristate "torture tests for RCU"
-	depends on DEBUG_KERNEL
-	default n
-	help
-	  This option provides a kernel module that runs torture tests
-	  on the RCU infrastructure.  The kernel module may be built
-	  after the fact on the running kernel to be tested, if desired.
-
-	  Say Y here if you want RCU torture tests to start automatically
-	  at boot time (you probably don't).
-	  Say M if you want the RCU torture tests to build as a module.
-	  Say N if you are unsure.
diff -urN newtree/mm/memory.c newtree.2/mm/memory.c
--- newtree/mm/memory.c	2006-08-02 07:14:23.000000000 -0700
+++ newtree.2/mm/memory.c	2006-08-04 14:07:26.000000000 -0700
@@ -1176,6 +1176,7 @@
 	} while (pgd++, addr = next, addr != end);
 	return err;
 }
+EXPORT_SYMBOL_GPL(zeromap_page_range);
 
 pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)
 {
diff -urN newtree/mm/mmap.c newtree.2/mm/mmap.c
--- newtree/mm/mmap.c	2006-08-02 07:14:23.000000000 -0700
+++ newtree.2/mm/mmap.c	2006-08-04 14:07:26.000000000 -0700
@@ -2009,6 +2009,7 @@
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(insert_vm_struct);
 
 /*
  * Copy the vma structure to a new location in the same mm,
