diff -urN oldtree/Documentation/fb/00-INDEX newtree/Documentation/fb/00-INDEX --- oldtree/Documentation/fb/00-INDEX 2006-01-03 03:21:10.000000000 +0000 +++ newtree/Documentation/fb/00-INDEX 2006-02-03 18:18:17.086732688 +0000 @@ -19,6 +19,8 @@ - info on the Matrox frame buffer driver pvr2fb.txt - info on the PowerVR 2 frame buffer driver +splash.txt + - info on the Framebuffer Splash tgafb.txt - info on the TGA (DECChip 21030) frame buffer driver vesafb.txt diff -urN oldtree/Documentation/fb/splash.txt newtree/Documentation/fb/splash.txt --- oldtree/Documentation/fb/splash.txt 1970-01-01 00:00:00.000000000 +0000 +++ newtree/Documentation/fb/splash.txt 2006-02-03 18:18:17.086732688 +0000 @@ -0,0 +1,207 @@ +What is it? +----------- + +The framebuffer splash is a kernel feature that allows displaying a background +picture on selected consoles. + +What do I need to get it to work? +--------------------------------- + +To get fb splash up-and-running you will have to: + 1) get a copy of splashutils [1] or a similar program + 2) get some splash themes + 3) build the kernel helper program + 4) build your kernel with the FB_SPLASH option enabled. + +To get fb splash operational right after fbcon initialization is finished, you +will have to include a theme and the kernel helper into your initramfs image. +Please refer to splashutils documentation for instructions on how to do that. + +[1] The splashutils package can be downloaded from: + http://dev.gentoo.org/~spock/projects/splashutils/ + +The userspace helper +-------------------- + +The userspace splash helper (by default: /sbin/splash_helper) is called by the +kernel whenever an important event occurs and the kernel needs some kind of +job to be carried out. Important events include console switches and graphic +mode switches (the kernel requests background images and configuration +parameters for the current console). The splash helper must be accessible at +all times. If it's not, fbsplash will be switched off automatically. + +It's possible to set path to the splash helper by writing it to +/proc/sys/kernel/fbsplash. + +***************************************************************************** + +The information below is mostly technical stuff. There's probably no need to +read it unless you plan to develop a userspace helper. + +The splash protocol +------------------- + +The splash protocol defines a communication interface between the kernel and +the userspace splash helper. + +The kernel side is responsible for: + + o rendering console text, using an image as a background (instead of a + standard solid color fbcon uses), + o accepting commands from the user via ioctls on the fbsplash device, + o calling the userspace helper to set things up as soon as the fb subsystem + is initialized. + +The userspace helper is responsible for everything else, including parsing +configuration files, decompressing the image files whenever the kernel needs +it, and communicating with the kernel if necessary. + +The splash protocol specifies how communication is done in both ways: +kernel->userspace and userspace->helper. + +Kernel -> Userspace +------------------- + +The kernel communicates with the userspace helper by calling it and specifying +the task to be done in a series of arguments. + +The arguments follow the pattern: + + +All commands defined in splash protocol v2 have the following parameters: + virtual console + framebuffer number + theme + +Splash protocol v1 specified an additional 'fbsplash mode' after the +framebuffer number. Splash protocol v1 is deprecated and should not be used. + +Splash protocol v2 specifies the following commands: + +getpic +------ + The kernel issues this command to request image data. It's up to the userspace + helper to find a background image appropriate for the specified theme and the + current resolution. The userspace helper should respond by issuing the + FBIOSPLASH_SETPIC ioctl. + +init +---- + The kernel issues this command after the fbsplash device is created and + the fbsplash interface is initialized. Upon receiving 'init', the userspace + helper should parse the kernel command line (/proc/cmdline) or otherwise + decide whether fbsplash is to be activated. + + To activate fbsplash on the first console the helper should issue the + FBIOSPLASH_SETCFG, FBIOSPLASH_SETPIC and FBIOSPLASH_SETSTATE commands, + in the above-mentioned order. + + When the userspace helper is called in an early phase of the boot process + (right after the initialization of fbcon), no filesystems will be mounted. + The helper program should mount sysfs and then create the appropriate + framebuffer, fbsplash and tty0 devices (if they don't already exist) to get + current display settings and to be able to communicate with the kernel side. + It should probably also mount the procfs to be able to parse the kernel + command line parameters. + + Note that the console sem is not held when the kernel calls splash_helper + with the 'init' command. The splash helper should perform all ioctls with + origin set to FB_SPLASH_IO_ORIG_USER. + +modechange +---------- + The kernel issues this command on a mode change. The helper's response should + be similar to the response to the 'init' command. Note that this time the + console sem is held and all ioctls must be performed with origin set to + FB_SPLASH_IO_ORIG_KERNEL. + + +Userspace -> Kernel +------------------- + +Userspace programs can communicate with fbsplash via ioctls on the fbsplash +device. These ioctls are to be used by both the userspace helper (called +only by the kernel) and userspace configuration tools (run by the users). + +The splash helper should set the origin field to FB_SPLASH_IO_ORIG_KERNEL +when doing the appropriate ioctls. All userspace configuration tools should +use FB_SPLASH_IO_ORIG_USER. Failure to set the appropriate value in the origin +field when performing ioctls from the kernel helper will most likely result +in a console deadlock. + +FB_SPLASH_IO_ORIG_KERNEL instructs fbsplash not to try to acquire the console +semaphore. Not surprisingly, FB_SPLASH_IO_ORIG_USER instructs it to acquire +the console sem. + +The framebuffer splash provides the following ioctls (all defined in +linux/fb.h): + +FBIOSPLASH_SETPIC +description: loads a background picture for a virtual console +argument: struct fb_splash_iowrapper*; data: struct fb_image* +notes: +If called for consoles other than the current foreground one, the picture data +will be ignored. + +If the current virtual console is running in a 8-bpp mode, the cmap substruct +of fb_image has to be filled appropriately: start should be set to 16 (first +16 colors are reserved for fbcon), len to a value <= 240 and red, green and +blue should point to valid cmap data. The transp field is ingored. The fields +dx, dy, bg_color, fg_color in fb_image are ignored as well. + +FBIOSPLASH_SETCFG +description: sets the fbsplash config for a virtual console +argument: struct fb_splash_iowrapper*; data: struct vc_splash* +notes: The structure has to be filled with valid data. + +FBIOSPLASH_GETCFG +description: gets the fbsplash config for a virtual console +argument: struct fb_splash_iowrapper*; data: struct vc_splash* + +FBIOSPLASH_SETSTATE +description: sets the fbsplash state for a virtual console +argument: struct fb_splash_iowrapper*; data: unsigned int* + values: 0 = disabled, 1 = enabled. + +FBIOSPLASH_GETSTATE +description: gets the fbsplash state for a virtual console +argument: struct fb_splash_iowrapper*; data: unsigned int* + values: as in FBIOSPLASH_SETSTATE + +Info on used structures: + +Definition of struct vc_splash can be found in linux/console_splash.h. It's +heavily commented. Note that the 'theme' field should point to a string +no longer than FB_SPLASH_THEME_LEN. When FBIOSPLASH_GETCFG call is +performed, the theme field should point to a char buffer of length +FB_SPLASH_THEME_LEN. + +Definition of struct fb_splash_iowrapper can be found in linux/fb.h. +The fields in this struct have the following meaning: + +vc: +Virtual console number. + +origin: +Specifies if the ioctl is performed as a response to a kernel request. The +splash helper should set this field to FB_SPLASH_IO_ORIG_KERNEL, userspace +programs should set it to FB_SPLASH_IO_ORIG_USER. This field is necessary to +avoid console semaphore deadlocks. + +data: +Pointer to a data structure appropriate for the performed ioctl. Type of +the data struct is specified in the ioctls description. + +***************************************************************************** + +Credit +------ + +Original 'bootsplash' project & implementation by: + Volker Poplawski , Stefan Reinauer , + Steffen Winterfeldt , Michael Schroeder , + Ken Wimer . + +Fbsplash, splash protocol design, current implementation & docs by: + Michael Januszewski + diff -urN oldtree/drivers/video/Kconfig newtree/drivers/video/Kconfig --- oldtree/drivers/video/Kconfig 2006-01-03 03:21:10.000000000 +0000 +++ newtree/drivers/video/Kconfig 2006-02-03 18:18:17.087732536 +0000 @@ -759,7 +759,6 @@ select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select FB_TILEBLITTING select FB_MACMODES if PPC_PMAC ---help--- Say Y here if you have a Matrox Millennium, Matrox Millennium II, @@ -1469,5 +1468,15 @@ source "drivers/video/backlight/Kconfig" endif -endmenu +config FB_SPLASH + bool "Support for the framebuffer splash" + depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING + default n + ---help--- + This option enables support for the Linux boot-up splash screen and + graphical backgrounds on consoles. Note that you will need userspace + splash utilities in order to take advantage of these features. Refer + to Documentation/fb/splash.txt for more information. + If unsure, say N. +endmenu diff -urN oldtree/drivers/video/Kconfig.orig newtree/drivers/video/Kconfig.orig --- oldtree/drivers/video/Kconfig.orig 1970-01-01 00:00:00.000000000 +0000 +++ newtree/drivers/video/Kconfig.orig 2006-01-03 03:21:10.000000000 +0000 @@ -0,0 +1,1473 @@ +# +# Video configuration +# + +menu "Graphics support" + +config FB + tristate "Support for frame buffer devices" + ---help--- + The frame buffer device provides an abstraction for the graphics + hardware. It represents the frame buffer of some video hardware and + allows application software to access the graphics hardware through + a well-defined interface, so the software doesn't need to know + anything about the low-level (hardware register) stuff. + + Frame buffer devices work identically across the different + architectures supported by Linux and make the implementation of + application programs easier and more portable; at this point, an X + server exists which uses the frame buffer device exclusively. + On several non-X86 architectures, the frame buffer device is the + only way to use the graphics hardware. + + The device is accessed through special device nodes, usually located + in the /dev directory, i.e. /dev/fb*. + + You need an utility program called fbset to make full use of frame + buffer devices. Please read + and the Framebuffer-HOWTO at + for more + information. + + Say Y here and to the driver for your graphics board below if you + are compiling a kernel for a non-x86 architecture. + + If you are compiling for the x86 architecture, you can say Y if you + want to play with it, but it is not essential. Please note that + running graphical applications that directly touch the hardware + (e.g. an accelerated X server) and that are not frame buffer + device-aware may cause unexpected results. If unsure, say N. + +config FB_CFB_FILLRECT + tristate + depends on FB + default n + ---help--- + Include the cfb_fillrect function for generic software rectangle + filling. This is used by drivers that don't provide their own + (accelerated) version. + +config FB_CFB_COPYAREA + tristate + depends on FB + default n + ---help--- + Include the cfb_copyarea function for generic software area copying. + This is used by drivers that don't provide their own (accelerated) + version. + +config FB_CFB_IMAGEBLIT + tristate + depends on FB + default n + ---help--- + Include the cfb_imageblit function for generic software image + blitting. This is used by drivers that don't provide their own + (accelerated) version. + +config FB_MACMODES + tristate + depends on FB + default n + +config FB_MODE_HELPERS + bool "Enable Video Mode Handling Helpers" + depends on FB + default n + ---help--- + This enables functions for handling video modes using the + Generalized Timing Formula and the EDID parser. A few drivers rely + on this feature such as the radeonfb, rivafb, and the i810fb. If + your driver does not take advantage of this feature, choosing Y will + just increase the kernel size by about 5K. + +config FB_TILEBLITTING + bool "Enable Tile Blitting Support" + depends on FB + default n + ---help--- + This enables tile blitting. Tile blitting is a drawing technique + where the screen is divided into rectangular sections (tiles), whereas + the standard blitting divides the screen into pixels. Because the + default drawing element is a tile, drawing functions will be passed + parameters in terms of number of tiles instead of number of pixels. + For example, to draw a single character, instead of using bitmaps, + an index to an array of bitmaps will be used. To clear or move a + rectangular section of a screen, the rectangle will be described in + terms of number of tiles in the x- and y-axis. + + This is particularly important to one driver, matroxfb. If + unsure, say N. + +config FB_CIRRUS + tristate "Cirrus Logic support" + depends on FB && (ZORRO || PCI) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + This enables support for Cirrus Logic GD542x/543x based boards on + Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. + + If you have a PCI-based system, this enables support for these + chips: GD-543x, GD-544x, GD-5480. + + Please read the file . + + Say N unless you have such a graphics board or plan to get one + before you next recompile the kernel. + +config FB_PM2 + tristate "Permedia2 support" + depends on FB && ((AMIGA && BROKEN) || PCI) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Permedia2 AGP frame + buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a + product page at + . + +config FB_PM2_FIFO_DISCONNECT + bool "enable FIFO disconnect feature" + depends on FB_PM2 && PCI + help + Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2). + +config FB_ARMCLCD + tristate "ARM PrimeCell PL110 support" + depends on FB && ARM && ARM_AMBA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This framebuffer device driver is for the ARM PrimeCell PL110 + Colour LCD controller. ARM PrimeCells provide the building + blocks for System on a Chip devices. + + If you want to compile this as a module (=code which can be + inserted into and removed from the running kernel), say M + here and read . The module + will be called amba-clcd. + +config FB_ACORN + bool "Acorn VIDC support" + depends on (FB = y) && ARM && (ARCH_ACORN || ARCH_CLPS7500) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Acorn VIDC graphics + hardware found in Acorn RISC PCs and other ARM-based machines. If + unsure, say N. + +config FB_CLPS711X + bool "CLPS711X LCD support" + depends on (FB = y) && ARM && ARCH_CLPS711X + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y to enable the Framebuffer driver for the CLPS7111 and + EP7212 processors. + +config FB_SA1100 + bool "SA-1100 LCD support" + depends on (FB = y) && ARM && ARCH_SA1100 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is a framebuffer device for the SA-1100 LCD Controller. + See for information on framebuffer + devices. + + If you plan to use the LCD display with your SA-1100 system, say + Y here. + +config FB_IMX + tristate "Motorola i.MX LCD support" + depends on FB && ARM && ARCH_IMX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + +config FB_CYBER2000 + tristate "CyberPro 2000/2010/5000 support" + depends on FB && PCI && (BROKEN || !SPARC64) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the Integraphics CyberPro 20x0 and 5000 + VGA chips used in the Rebel.com Netwinder and other machines. + Say Y if you have a NetWinder or a graphics card containing this + device, otherwise say N. + +config FB_APOLLO + bool + depends on (FB = y) && APOLLO + default y + select FB_CFB_FILLRECT + select FB_CFB_IMAGEBLIT + +config FB_Q40 + bool + depends on (FB = y) && Q40 + default y + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + +config FB_AMIGA + tristate "Amiga native chipset support" + depends on FB && AMIGA + help + This is the frame buffer device driver for the builtin graphics + chipset found in Amigas. + + To compile this driver as a module, choose M here: the + module will be called amifb. + +config FB_AMIGA_OCS + bool "Amiga OCS chipset support" + depends on FB_AMIGA + help + This enables support for the original Agnus and Denise video chips, + found in the Amiga 1000 and most A500's and A2000's. If you intend + to run Linux on any of these systems, say Y; otherwise say N. + +config FB_AMIGA_ECS + bool "Amiga ECS chipset support" + depends on FB_AMIGA + help + This enables support for the Enhanced Chip Set, found in later + A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If + you intend to run Linux on any of these systems, say Y; otherwise + say N. + +config FB_AMIGA_AGA + bool "Amiga AGA chipset support" + depends on FB_AMIGA + help + This enables support for the Advanced Graphics Architecture (also + known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T + and CD32. If you intend to run Linux on any of these systems, say Y; + otherwise say N. + +config FB_CYBER + tristate "Amiga CyberVision 64 support" + depends on FB && ZORRO && BROKEN + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the Cybervision 64 graphics card from + Phase5. Please note that its use is not all that intuitive (i.e. if + you have any questions, be sure to ask!). Say N unless you have a + Cybervision 64 or plan to get one before you next recompile the + kernel. Please note that this driver DOES NOT support the + Cybervision 64/3D card, as they use incompatible video chips. + +config FB_VIRGE + bool "Amiga CyberVision 64/3D support " + depends on (FB = y) && ZORRO && BROKEN + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the Cybervision 64/3D graphics card from + Phase5. Please note that its use is not all that intuitive (i.e. if + you have any questions, be sure to ask!). Say N unless you have a + Cybervision 64/3D or plan to get one before you next recompile the + kernel. Please note that this driver DOES NOT support the older + Cybervision 64 card, as they use incompatible video chips. + +config FB_RETINAZ3 + tristate "Amiga Retina Z3 support" + depends on (FB = y) && ZORRO && BROKEN + help + This enables support for the Retina Z3 graphics card. Say N unless + you have a Retina Z3 or plan to get one before you next recompile + the kernel. + +config FB_FM2 + bool "Amiga FrameMaster II/Rainbow II support" + depends on (FB = y) && ZORRO + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Amiga FrameMaster + card from BSC (exhibited 1992 but not shipped as a CBM product). + +config FB_ARC + tristate "Arc Monochrome LCD board support" + depends on FB && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the Arc Monochrome LCD board. The board + is based on the KS-108 lcd controller and is typically a matrix + of 2*n chips. This driver was tested with a 128x64 panel. This + driver supports it for use with x86 SBCs through a 16 bit GPIO + interface (8 bit data, 8 bit control). If you anticpate using + this driver, say Y or M; otherwise say N. You must specify the + GPIO IO address to be used for setting control and data. + +config FB_ATARI + bool "Atari native chipset support" + depends on (FB = y) && ATARI && BROKEN + help + This is the frame buffer device driver for the builtin graphics + chipset found in Ataris. + +config FB_OF + bool "Open Firmware frame buffer device support" + depends on (FB = y) && (PPC64 || PPC_OF) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + Say Y if you want support with Open Firmware for your graphics + board. + +config FB_CONTROL + bool "Apple \"control\" display support" + depends on (FB = y) && PPC_PMAC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + This driver supports a frame buffer for the graphics adapter in the + Power Macintosh 7300 and others. + +config FB_PLATINUM + bool "Apple \"platinum\" display support" + depends on (FB = y) && PPC_PMAC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + This driver supports a frame buffer for the "platinum" graphics + adapter in some Power Macintoshes. + +config FB_VALKYRIE + bool "Apple \"valkyrie\" display support" + depends on (FB = y) && (MAC || PPC_PMAC) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + This driver supports a frame buffer for the "valkyrie" graphics + adapter in some Power Macintoshes. + +config FB_CT65550 + bool "Chips 65550 display support" + depends on (FB = y) && PPC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Chips & Technologies + 65550 graphics chip in PowerBooks. + +config FB_ASILIANT + bool "Asiliant (Chips) 69000 display support" + depends on (FB = y) && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + +config FB_IMSTT + bool "IMS Twin Turbo display support" + depends on (FB = y) && PCI + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC + help + The IMS Twin Turbo is a PCI-based frame buffer card bundled with + many Macintosh and compatible computers. + +config FB_VGA16 + tristate "VGA 16-color graphics support" + depends on FB && (X86 || PPC) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for VGA 16 color graphic + cards. Say Y if you have such a card. + + To compile this driver as a module, choose M here: the + module will be called vga16fb. + +config FB_STI + tristate "HP STI frame buffer device support" + depends on FB && PARISC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + ---help--- + STI refers to the HP "Standard Text Interface" which is a set of + BIOS routines contained in a ROM chip in HP PA-RISC based machines. + Enabling this option will implement the linux framebuffer device + using calls to the STI BIOS routines for initialisation. + + If you enable this option, you will get a planar framebuffer device + /dev/fb which will work on the most common HP graphic cards of the + NGLE family, including the artist chips (in the 7xx and Bxxx series), + HCRX, HCRX24, CRX, CRX24 and VisEG series. + + It is safe to enable this option, so you should probably say "Y". + +config FB_MAC + bool "Generic Macintosh display support" + depends on (FB = y) && MAC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + +# bool ' Apple DAFB display support' CONFIG_FB_DAFB +config FB_HP300 + bool + depends on (FB = y) && HP300 + select FB_CFB_FILLRECT + select FB_CFB_IMAGEBLIT + default y + +config FB_TGA + tristate "TGA framebuffer support" + depends on FB && ALPHA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for generic TGA graphic + cards. Say Y if you have one of those. + +config FB_VESA + bool "VESA VGA graphics support" + depends on (FB = y) && X86 + 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. The older VESA 1.2 cards are not supported. + You will get a boot time penguin logo at no additional cost. Please + read . If unsure, say Y. + +config VIDEO_SELECT + bool + depends on FB_VESA + default y + +config FB_HGA + tristate "Hercules mono graphics support" + depends on FB && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y here if you have a Hercules mono graphics card. + + To compile this driver as a module, choose M here: the + module will be called hgafb. + + As this card technology is 15 years old, most people will answer N + here. + +config FB_HGA_ACCEL + bool "Hercules mono Acceleration functions (EXPERIMENTAL)" + depends on FB_HGA && EXPERIMENTAL + ---help--- + This will compile the Hercules mono graphics with + acceleration functions. + + +config VIDEO_SELECT + bool + depends on (FB = y) && X86 + default y + +config FB_SGIVW + tristate "SGI Visual Workstation framebuffer support" + depends on FB && X86_VISWS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + SGI Visual Workstation support for framebuffer graphics. + +config FB_GBE + bool "SGI Graphics Backend frame buffer support" + depends on (FB = y) && (SGI_IP32 || X86_VISWS) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for SGI Graphics Backend. + This chip is used in SGI O2 and Visual Workstation 320/540. + +config FB_GBE_MEM + int "Video memory size in MB" + depends on FB_GBE + default 8 + help + This is the amount of memory reserved for the framebuffer, + which can be any value between 1MB and 8MB. + +config BUS_I2C + bool + depends on (FB = y) && VISWS + default y + +config FB_SUN3 + bool "Sun3 framebuffer support" + depends on (FB = y) && (SUN3 || SUN3X) && BROKEN + +config FB_SBUS + bool "SBUS and UPA framebuffers" + depends on (FB = y) && SPARC + help + Say Y if you want support for SBUS or UPA based frame buffer device. + +config FB_BW2 + bool "BWtwo support" + depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the BWtwo frame buffer. + +config FB_CG3 + bool "CGthree support" + depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGthree frame buffer. + +config FB_CG6 + bool "CGsix (GX,TurboGX) support" + depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGsix (GX, TurboGX) + frame buffer. + +config FB_PVR2 + tristate "NEC PowerVR 2 display support" + depends on FB && SH_DREAMCAST + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Say Y here if you have a PowerVR 2 card in your box. If you plan to + run linux on your Dreamcast, you will have to say Y here. + This driver may or may not work on other PowerVR 2 cards, but is + totally untested. Use at your own risk. If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called pvr2fb. + + You can pass several parameters to the driver at boot time or at + module load time. The parameters look like "video=pvr2:XXX", where + the meaning of XXX can be found at the end of the main source file + (). Please see the file + . + +config FB_EPSON1355 + bool "Epson 1355 framebuffer support" + depends on (FB = y) && (SUPERH || ARCH_CEIVA) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Build in support for the SED1355 Epson Research Embedded RAMDAC + LCD/CRT Controller (since redesignated as the S1D13505) as a + framebuffer. Product specs at + . + +config FB_S1D13XXX + tristate "Epson S1D13XXX framebuffer support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for S1D13XXX framebuffer device family (currently only + working with S1D13806). Product specs at + + +config FB_NVIDIA + tristate "nVidia Framebuffer Support" + depends on FB && PCI + select I2C_ALGOBIT if FB_NVIDIA_I2C + select I2C if FB_NVIDIA_I2C + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports graphics boards with the nVidia chips, TNT + and newer. For very old chipsets, such as the RIVA128, then use + the rivafb. + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called nvidiafb. + +config FB_NVIDIA_I2C + bool "Enable DDC Support" + depends on FB_NVIDIA + help + This enables I2C support for nVidia Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. + +config FB_RIVA + tristate "nVidia Riva support" + depends on FB && PCI + select I2C_ALGOBIT if FB_RIVA_I2C + select I2C if FB_RIVA_I2C + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports graphics boards with the nVidia Riva/Geforce + chips. + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called rivafb. + +config FB_RIVA_I2C + bool "Enable DDC Support" + depends on FB_RIVA + help + This enables I2C support for nVidia Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. + +config FB_RIVA_DEBUG + bool "Lots of debug output from Riva(nVidia) driver" + depends on FB_RIVA + default n + help + Say Y here if you want the Riva driver to output all sorts + of debugging informations to provide to the maintainer when + something goes wrong. + +config FB_I810 + tristate "Intel 810/815 support (EXPERIMENTAL)" + depends on FB && EXPERIMENTAL && PCI && X86_32 + select AGP + select AGP_INTEL + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports the on-board graphics built in to the Intel 810 + and 815 chipsets. Say Y if you have and plan to use such a board. + + To compile this driver as a module, choose M here: the + module will be called i810fb. + + For more information, please read + + +config FB_I810_GTF + bool "use VESA Generalized Timing Formula" + depends on FB_I810 + help + If you say Y, then the VESA standard, Generalized Timing Formula + or GTF, will be used to calculate the required video timing values + per video mode. Since the GTF allows nondiscrete timings + (nondiscrete being a range of values as opposed to discrete being a + set of values), you'll be able to use any combination of horizontal + and vertical resolutions, and vertical refresh rates without having + to specify your own timing parameters. This is especially useful + to maximize the performance of an aging display, or if you just + have a display with nonstandard dimensions. A VESA compliant + monitor is recommended, but can still work with non-compliant ones. + If you need or want this, then select this option. The timings may + not be compliant with Intel's recommended values. Use at your own + risk. + + If you say N, the driver will revert to discrete video timings + using a set recommended by Intel in their documentation. + + If unsure, say N. + +config FB_I810_I2C + bool "Enable DDC Support" + depends on FB_I810 && FB_I810_GTF + select I2C + select I2C_ALGOBIT + help + +config FB_INTEL + tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" + depends on FB && EXPERIMENTAL && PCI && X86_32 + select AGP + select AGP_INTEL + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports the on-board graphics built in to the Intel + 830M/845G/852GM/855GM/865G chipsets. + Say Y if you have and plan to use such a board. + + To compile this driver as a module, choose M here: the + module will be called intelfb. + +config FB_INTEL_DEBUG + bool "Intel driver Debug Messages" + depends on FB_INTEL + ---help--- + Say Y here if you want the Intel driver to output all sorts + of debugging informations to provide to the maintainer when + something goes wrong. + +config FB_MATROX + tristate "Matrox acceleration" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_TILEBLITTING + select FB_MACMODES if PPC_PMAC + ---help--- + Say Y here if you have a Matrox Millennium, Matrox Millennium II, + Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox + Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video, + Matrox G400, G450 or G550 card in your box. + + To compile this driver as a module, choose M here: the + module will be called matroxfb. + + You can pass several parameters to the driver at boot time or at + module load time. The parameters look like "video=matrox:XXX", and + are described in . + +config FB_MATROX_MILLENIUM + bool "Millennium I/II support" + depends on FB_MATROX + help + Say Y here if you have a Matrox Millennium or Matrox Millennium II + video card. If you select "Advanced lowlevel driver options" below, + you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp + packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can + also use font widths different from 8. + +config FB_MATROX_MYSTIQUE + bool "Mystique support" + depends on FB_MATROX + help + Say Y here if you have a Matrox Mystique or Matrox Mystique 220 + video card. If you select "Advanced lowlevel driver options" below, + you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp + packed pixel and 32 bpp packed pixel. You can also use font widths + different from 8. + +config FB_MATROX_G + bool "G100/G200/G400/G450/G550 support" + depends on FB_MATROX + ---help--- + Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based + video card. If you select "Advanced lowlevel driver options", you + should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed + pixel and 32 bpp packed pixel. You can also use font widths + different from 8. + + If you need support for G400 secondary head, you must first say Y to + "I2C support" in the character devices section, and then to + "Matrox I2C support" and "G400 second head support" here in the + framebuffer section. G450/G550 secondary head and digital output + are supported without additional modules. + + The driver starts in monitor mode. You must use the matroxset tool + (available at ) to + swap primary and secondary head outputs, or to change output mode. + Secondary head driver always start in 640x480 resolution and you + must use fbset to change it. + + Do not forget that second head supports only 16 and 32 bpp + packed pixels, so it is a good idea to compile them into the kernel + too. You can use only some font widths, as the driver uses generic + painting procedures (the secondary head does not use acceleration + engine). + + G450/G550 hardware can display TV picture only from secondary CRTC, + and it performs no scaling, so picture must have 525 or 625 lines. + +config FB_MATROX_I2C + tristate "Matrox I2C support" + depends on FB_MATROX && I2C + select I2C_ALGOBIT + ---help--- + This drivers creates I2C buses which are needed for accessing the + DDC (I2C) bus present on all Matroxes, an I2C bus which + interconnects Matrox optional devices, like MGA-TVO on G200 and + G400, and the secondary head DDC bus, present on G400 only. + + You can say Y or M here if you want to experiment with monitor + detection code. You must say Y or M here if you want to use either + second head of G400 or MGA-TVO on G200 or G400. + + If you compile it as module, it will create a module named + i2c-matroxfb. + +config FB_MATROX_MAVEN + tristate "G400 second head support" + depends on FB_MATROX_G && FB_MATROX_I2C + ---help--- + WARNING !!! This support does not work with G450 !!! + + Say Y or M here if you want to use a secondary head (meaning two + monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary + head is not compatible with accelerated XFree 3.3.x SVGA servers - + secondary head output is blanked while you are in X. With XFree + 3.9.17 preview you can use both heads if you use SVGA over fbdev or + the fbdev driver on first head and the fbdev driver on second head. + + If you compile it as module, two modules are created, + matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for + both G200 and G400, matroxfb_crtc2 is needed only by G400. You must + also load i2c-matroxfb to get it to run. + + The driver starts in monitor mode and you must use the matroxset + tool (available at + ) to switch it to + PAL or NTSC or to swap primary and secondary head outputs. + Secondary head driver also always start in 640x480 resolution, you + must use fbset to change it. + + Also do not forget that second head supports only 16 and 32 bpp + packed pixels, so it is a good idea to compile them into the kernel + too. You can use only some font widths, as the driver uses generic + painting procedures (the secondary head does not use acceleration + engine). + +config FB_MATROX_MULTIHEAD + bool "Multihead support" + depends on FB_MATROX + ---help--- + Say Y here if you have more than one (supported) Matrox device in + your computer and you want to use all of them for different monitors + ("multihead"). If you have only one device, you should say N because + the driver compiled with Y is larger and a bit slower, especially on + ia32 (ix86). + + If you said M to "Matrox unified accelerated driver" and N here, you + will still be able to use several Matrox devices simultaneously: + insert several instances of the module matroxfb into the kernel + with insmod, supplying the parameter "dev=N" where N is 0, 1, etc. + for the different Matrox devices. This method is slightly faster but + uses 40 KB of kernel memory per Matrox card. + + There is no need for enabling 'Matrox multihead support' if you have + only one Matrox card in the box. + +config FB_RADEON_OLD + tristate "ATI Radeon display support (Old driver)" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC + help + Choose this option if you want to use an ATI Radeon graphics card as + a framebuffer device. There are both PCI and AGP versions. You + don't need to choose this to run the Radeon in plain VGA mode. + There is a product page at + . + +config FB_RADEON + tristate "ATI Radeon display support" + depends on FB && PCI + select I2C_ALGOBIT if FB_RADEON_I2C + select I2C if FB_RADEON_I2C + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC_OF + help + Choose this option if you want to use an ATI Radeon graphics card as + a framebuffer device. There are both PCI and AGP versions. You + don't need to choose this to run the Radeon in plain VGA mode. + + If you say Y here and want DDC/I2C support you must first say Y to + "I2C support" and "I2C bit-banging support" in the character devices + section. + + If you say M here then "I2C support" and "I2C bit-banging support" + can be build either as modules or built-in. + + There is a product page at + http://apps.ati.com/ATIcompare/ +config FB_RADEON_I2C + bool "DDC/I2C for ATI Radeon support" + depends on FB_RADEON + default y + help + Say Y here if you want DDC/I2C support for your Radeon board. + +config FB_RADEON_DEBUG + bool "Lots of debug output from Radeon driver" + depends on FB_RADEON + default n + help + Say Y here if you want the Radeon driver to output all sorts + of debugging informations to provide to the maintainer when + something goes wrong. + +config FB_ATY128 + tristate "ATI Rage128 display support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC_PMAC + help + This driver supports graphics boards with the ATI Rage128 chips. + Say Y if you have such a graphics board and read + . + + To compile this driver as a module, choose M here: the + module will be called aty128fb. + +config FB_ATY + tristate "ATI Mach64 display support" if PCI || ATARI + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC + help + This driver supports graphics boards with the ATI Mach64 chips. + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called atyfb. + +config FB_ATY_CT + bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" + depends on PCI && FB_ATY + default y if SPARC64 && FB_PCI + help + Say Y here to support use of ATI's 64-bit Rage boards (or other + boards based on the Mach64 CT, VT, GT, and LT chipsets) as a + framebuffer device. The ATI product support page for these boards + is at . + +config FB_ATY_GENERIC_LCD + bool "Mach64 generic LCD support (EXPERIMENTAL)" + depends on FB_ATY_CT + help + Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, + Rage XC, or Rage XL chipset. + +config FB_ATY_XL_INIT + bool "Rage XL No-BIOS Init support" + depends on FB_ATY_CT + help + Say Y here to support booting a Rage XL without BIOS support. + +config FB_ATY_GX + bool "Mach64 GX support" if PCI + depends on FB_ATY + default y if ATARI + help + Say Y here to support use of the ATI Mach64 Graphics Expression + board (or other boards based on the Mach64 GX chipset) as a + framebuffer device. The ATI product support page for these boards + is at + . + +config FB_S3TRIO + bool "S3 Trio display support" + depends on (FB = y) && PPC && BROKEN + help + If you have a S3 Trio say Y. Say N for S3 Virge. + +config FB_SAVAGE + tristate "S3 Savage support" + depends on FB && PCI && EXPERIMENTAL + select I2C_ALGOBIT if FB_SAVAGE_I2C + select I2C if FB_SAVAGE_I2C + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports notebooks and computers with S3 Savage PCI/AGP + chips. + + Say Y if you have such a graphics card. + + To compile this driver as a module, choose M here; the module + will be called savagefb. + +config FB_SAVAGE_I2C + bool "Enable DDC2 Support" + depends on FB_SAVAGE + help + This enables I2C support for S3 Savage Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. + +config FB_SAVAGE_ACCEL + bool "Enable Console Acceleration" + depends on FB_SAVAGE + default n + help + This option will compile in console acceleration support. If + the resulting framebuffer console has bothersome glitches, then + choose N here. + +config FB_SIS + tristate "SiS/XGI display support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the SiS 300, 315, 330 + and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. + Specs available at and . + + To compile this driver as a module, choose M here; the module + will be called sisfb. + +config FB_SIS_300 + bool "SiS 300 series support" + depends on FB_SIS + help + Say Y here to support use of the SiS 300/305, 540, 630 and 730. + +config FB_SIS_315 + bool "SiS 315/330/340 series and XGI support" + depends on FB_SIS + help + Say Y here to support use of the SiS 315, 330 and 340 series + (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well + as XGI V3XT, V5, V8 and Z7. + +config FB_NEOMAGIC + tristate "NeoMagic display support" + depends on FB && PCI + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports notebooks with NeoMagic PCI chips. + Say Y if you have such a graphics card. + + To compile this driver as a module, choose M here: the + module will be called neofb. + +config FB_KYRO + tristate "IMG Kyro support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y here if you have a STG4000 / Kyro / PowerVR 3 based + graphics board. + + To compile this driver as a module, choose M here: the + module will be called kyrofb. + +config FB_3DFX + tristate "3Dfx Banshee/Voodoo3 display support" + depends on FB && PCI + select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + help + This driver supports graphics boards with the 3Dfx Banshee/Voodoo3 + chips. Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called tdfxfb. + +config FB_3DFX_ACCEL + bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)" + depends on FB_3DFX && EXPERIMENTAL + ---help--- + This will compile the 3Dfx Banshee/Voodoo3 frame buffer device + with acceleration functions. + + +config FB_VOODOO1 + tristate "3Dfx Voodoo Graphics (sst1) support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or + Voodoo2 (cvg) based graphics card. + + To compile this driver as a module, choose M here: the + module will be called sstfb. + + WARNING: Do not use any application that uses the 3D engine + (namely glide) while using this driver. + Please read the for supported + options and other important info support. + +config FB_CYBLA + tristate "Cyberblade/i1 support" + depends on FB && PCI + select FB_CFB_IMAGEBLIT + select VIDEO_SELECT + ---help--- + This driver is supposed to support the Trident Cyberblade/i1 + graphics core integrated in the VIA VT8601A North Bridge, + also known as VIA Apollo PLE133. + + Status: + - Developed, tested and working on EPIA 5000 and EPIA 800. + - Does work reliable on all systems with CRT/LCD connected to + normal VGA ports. + - Should work on systems that do use the internal LCD port, but + this is absolutely not tested. + + Character imageblit, copyarea and rectangle fill are hw accelerated, + ypan scrolling is used by default. + + Please do read . + + To compile this driver as a module, choose M here: the + module will be called cyblafb. + +config FB_TRIDENT + tristate "Trident support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + This driver is supposed to support graphics boards with the + Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops + but also on some motherboards. For more information, read + + + Cyberblade/i1 support will be removed soon, use the cyblafb driver + instead. + + Say Y if you have such a graphics board. + + + To compile this driver as a module, choose M here: the + module will be called tridentfb. + +config FB_TRIDENT_ACCEL + bool "Trident Acceleration functions (EXPERIMENTAL)" + depends on FB_TRIDENT && EXPERIMENTAL + ---help--- + This will compile the Trident frame buffer device with + acceleration functions. + +config FB_PM3 + tristate "Permedia3 support" + depends on FB && PCI && BROKEN + help + This is the frame buffer device driver for the 3DLabs Permedia3 + chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & + similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 + and maybe other boards. + +config FB_AU1100 + bool "Au1100 LCD Driver" + depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y + +source "drivers/video/geode/Kconfig" + +config FB_FFB + bool "Creator/Creator3D/Elite3D support" + depends on FB_SBUS && SPARC64 + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Creator, Creator3D, + and Elite3D graphics boards. + +config FB_TCX + bool "TCX (SS4/SS5 only) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the TCX 24/8bit frame + buffer. + +config FB_CG14 + bool "CGfourteen (SX) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGfourteen frame + buffer on Desktop SPARCsystems with the SX graphics option. + +config FB_P9100 + bool "P9100 (Sparcbook 3 only) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the P9100 card + supported on Sparcbook 3 machines. + +config FB_LEO + bool "Leo (ZX) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the SBUS-based Sun ZX + (leo) frame buffer cards. + +config FB_PCI + bool "PCI framebuffers" + depends on (FB = y) && PCI && SPARC + +config FB_IGA + bool "IGA 168x display support" + depends on SPARC32 && FB_PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the INTERGRAPHICS 1680 and + successor frame buffer cards. + +config FB_HIT + tristate "HD64461 Frame Buffer support" + depends on FB && HD64461 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Hitachi HD64461 LCD + frame buffer card. + +config FB_PMAG_AA + bool "PMAG-AA TURBOchannel framebuffer support" + depends on (FB = y) && TC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) + used mainly in the MIPS-based DECstation series. + +config FB_PMAG_BA + bool "PMAG-BA TURBOchannel framebuffer support" + depends on (FB = y) && TC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) + used mainly in the MIPS-based DECstation series. + +config FB_PMAGB_B + bool "PMAGB-B TURBOchannel framebuffer support" + depends on (FB = y) && TC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the PMAGB-B TURBOchannel framebuffer card used mainly + in the MIPS-based DECstation series. The card is currently only + supported in 1280x1024x8 mode. + +config FB_MAXINE + bool "Maxine (Personal DECstation) onboard framebuffer support" + depends on (FB = y) && MACH_DECSTATION + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the onboard framebuffer (1024x768x8) in the Personal + DECstation series (Personal DECstation 5000/20, /25, /33, /50, + Codename "Maxine"). + +config FB_TX3912 + bool "TMPTX3912/PR31700 frame buffer support" + depends on (FB = y) && NINO + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core + see . + + Say Y here to enable kernel support for the on-board framebuffer. + +config FB_G364 + bool "G364 frame buffer support" + depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + The G364 driver is the framebuffer used in MIPS Magnum 4000 and + Olivetti M700-10 systems. + +config FB_68328 + bool "Motorola 68328 native frame buffer support" + depends on FB && (M68328 || M68EZ328 || M68VZ328) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y here if you want to support the built-in frame buffer of + the Motorola 68328 CPU family. + +config FB_PXA + tristate "PXA LCD framebuffer support" + depends on FB && ARCH_PXA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Intel + PXA2x0 processor. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called vfb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. + +config FB_PXA_PARAMETERS + bool "PXA LCD command line parameters" + default n + depends on FB_PXA + ---help--- + Enable the use of kernel command line or module parameters + to configure the physical properties of the LCD panel when + using the PXA LCD driver. + + This option allows you to override the panel parameters + supplied by the platform in order to support multiple + different models of flatpanel. If you will only be using a + single model of flatpanel then you can safely leave this + option disabled. + + describes the available parameters. + +config FB_W100 + tristate "W100 frame buffer support" + depends on FB && PXA_SHARPSL + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called vfb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. + +config FB_S3C2410 + tristate "S3C2410 LCD framebuffer support" + depends on FB && ARCH_S3C2410 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Samsung + S3C2410 processor. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called s3c2410fb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. +config FB_S3C2410_DEBUG + bool "S3C2410 lcd debug messages" + depends on FB_S3C2410 + help + Turn on debugging messages. Note that you can set/unset at run time + through sysfs + +config FB_VIRTUAL + tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + This is a `virtual' frame buffer device. It operates on a chunk of + unswappable kernel memory instead of on the memory of a graphics + board. This means you cannot see any output sent to this frame + buffer device, while it does consume precious memory. The main use + of this frame buffer device is testing and debugging the frame + buffer subsystem. Do NOT enable it for normal systems! To protect + the innocent, it has to be enabled explicitly at boot time using the + kernel option `video=vfb:'. + + To compile this driver as a module, choose M here: the + module will be called vfb. + + If unsure, say N. +if VT + source "drivers/video/console/Kconfig" +endif + +if FB || SGI_NEWPORT_CONSOLE + source "drivers/video/logo/Kconfig" +endif + +if FB && SYSFS + source "drivers/video/backlight/Kconfig" +endif + +endmenu + diff -urN oldtree/drivers/video/Makefile newtree/drivers/video/Makefile --- oldtree/drivers/video/Makefile 2006-01-03 03:21:10.000000000 +0000 +++ newtree/drivers/video/Makefile 2006-02-03 18:18:17.088732384 +0000 @@ -7,6 +7,7 @@ obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ obj-$(CONFIG_SYSFS) += backlight/ +obj-$(CONFIG_FB_SPLASH) += fbsplash.o cfbsplash.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ diff -urN oldtree/drivers/video/cfbsplash.c newtree/drivers/video/cfbsplash.c --- oldtree/drivers/video/cfbsplash.c 1970-01-01 00:00:00.000000000 +0000 +++ newtree/drivers/video/cfbsplash.c 2006-02-03 18:18:17.089732232 +0000 @@ -0,0 +1,472 @@ +/* + * linux/drivers/video/cfbsplash.c -- Framebuffer splash render functions + * + * Copyright (C) 2004 Michal Januszewski + * + * Code based upon "Bootsplash" (C) 2001-2003 + * Volker Poplawski , + * Stefan Reinauer , + * Steffen Winterfeldt , + * Michael Schroeder , + * Ken Wimer . + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "console/fbcon.h" +#include "fbsplash.h" + +#define parse_pixel(shift,bpp,type) \ + do { \ + if (d & (0x80 >> (shift))) \ + dd2[(shift)] = fgx; \ + else \ + dd2[(shift)] = transparent ? *(type *)splash_src : bgx; \ + splash_src += (bpp); \ + } while (0) \ + +extern int get_color(struct vc_data *vc, struct fb_info *info, + u16 c, int is_fg); + +void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) +{ + int i, j, k; + int minlen = min(min(info->var.red.length, info->var.green.length), + info->var.blue.length); + u32 col; + + for (j = i = 0; i < 16; i++) { + k = color_table[i]; + + col = ((vc->vc_palette[j++] >> (8-minlen)) + << info->var.red.offset); + col |= ((vc->vc_palette[j++] >> (8-minlen)) + << info->var.green.offset); + col |= ((vc->vc_palette[j++] >> (8-minlen)) + << info->var.blue.offset); + ((u32 *)info->pseudo_palette)[k] = col; + } +} + +void fbsplash_renderc(struct fb_info *info, int ypos, int xpos, int height, + int width, u8* src, u32 fgx, u32 bgx, u8 transparent) +{ + unsigned int x, y; + u32 dd; + int bytespp = ((info->var.bits_per_pixel + 7) >> 3); + unsigned int d = ypos * info->fix.line_length + xpos * bytespp; + unsigned int ds = (ypos * info->var.xres + xpos) * bytespp; + u16 dd2[4]; + + u8* splash_src = (u8 *)(info->splash.data + ds); + u8* dst = (u8 *)(info->screen_base + d); + + if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres) + return; + + for (y = 0; y < height; y++) { + switch (info->var.bits_per_pixel) { + + case 32: + for (x = 0; x < width; x++) { + + if ((x & 7) == 0) + d = *src++; + if (d & 0x80) + dd = fgx; + else + dd = transparent ? + *(u32 *)splash_src : bgx; + + d <<= 1; + splash_src += 4; + fb_writel(dd, dst); + dst += 4; + } + break; + case 24: + for (x = 0; x < width; x++) { + + if ((x & 7) == 0) + d = *src++; + if (d & 0x80) + dd = fgx; + else + dd = transparent ? + (*(u32 *)splash_src & 0xffffff) : bgx; + + d <<= 1; + splash_src += 3; +#ifdef __LITTLE_ENDIAN + fb_writew(dd & 0xffff, dst); + dst += 2; + fb_writeb((dd >> 16), dst); +#else + fb_writew(dd >> 8, dst); + dst += 2; + fb_writeb(dd & 0xff, dst); +#endif + dst++; + } + break; + case 16: + for (x = 0; x < width; x += 2) { + if ((x & 7) == 0) + d = *src++; + + parse_pixel(0, 2, u16); + parse_pixel(1, 2, u16); +#ifdef __LITTLE_ENDIAN + dd = dd2[0] | (dd2[1] << 16); +#else + dd = dd2[1] | (dd2[0] << 16); +#endif + d <<= 2; + fb_writel(dd, dst); + dst += 4; + } + break; + + case 8: + for (x = 0; x < width; x += 4) { + if ((x & 7) == 0) + d = *src++; + + parse_pixel(0, 1, u8); + parse_pixel(1, 1, u8); + parse_pixel(2, 1, u8); + parse_pixel(3, 1, u8); + +#ifdef __LITTLE_ENDIAN + dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24); +#else + dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24); +#endif + d <<= 4; + fb_writel(dd, dst); + dst += 4; + } + } + + dst += info->fix.line_length - width * bytespp; + splash_src += (info->var.xres - width) * bytespp; + } +} + +#define cc2cx(a) \ + ((info->fix.visual == FB_VISUAL_TRUECOLOR || \ + info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \ + ((u32*)info->pseudo_palette)[a] : a) + +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, + const unsigned short *s, int count, int yy, int xx) +{ + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + struct fbcon_ops *ops = info->fbcon_par; + int fg_color, bg_color, transparent; + u8 *src; + u32 bgx, fgx; + u16 c = scr_readw(s); + + fg_color = get_color(vc, info, c, 1); + bg_color = get_color(vc, info, c, 0); + + /* Don't paint the background image if console is blanked */ + transparent = ops->blank_state ? 0 : + (vc->vc_splash.bg_color == bg_color); + + xx = xx * vc->vc_font.width + vc->vc_splash.tx; + yy = yy * vc->vc_font.height + vc->vc_splash.ty; + + fgx = cc2cx(fg_color); + bgx = cc2cx(bg_color); + + while (count--) { + c = scr_readw(s++); + src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * + ((vc->vc_font.width + 7) >> 3); + + fbsplash_renderc(info, yy, xx, vc->vc_font.height, + vc->vc_font.width, src, fgx, bgx, transparent); + xx += vc->vc_font.width; + } +} + +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) +{ + int i; + unsigned int dsize, s_pitch; + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data* vc; + u8 *src; + + /* we really don't need any cursors while the console is blanked */ + if (info->state != FBINFO_STATE_RUNNING || ops->blank_state) + return; + + vc = vc_cons[ops->currcon].d; + + src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC); + if (!src) + return; + + s_pitch = (cursor->image.width + 7) >> 3; + dsize = s_pitch * cursor->image.height; + if (cursor->enable) { + switch (cursor->rop) { + case ROP_XOR: + for (i = 0; i < dsize; i++) + src[i] = cursor->image.data[i] ^ cursor->mask[i]; + break; + case ROP_COPY: + default: + for (i = 0; i < dsize; i++) + src[i] = cursor->image.data[i] & cursor->mask[i]; + break; + } + } else + memcpy(src, cursor->image.data, dsize); + + fbsplash_renderc(info, + cursor->image.dy + vc->vc_splash.ty, + cursor->image.dx + vc->vc_splash.tx, + cursor->image.height, + cursor->image.width, + (u8*)src, + cc2cx(cursor->image.fg_color), + cc2cx(cursor->image.bg_color), + cursor->image.bg_color == vc->vc_splash.bg_color); + + kfree(src); +} + +static void splashset(u8 *dst, int height, int width, int dstbytes, + u32 bgx, int bpp) +{ + int i; + + if (bpp == 8) + bgx |= bgx << 8; + if (bpp == 16 || bpp == 8) + bgx |= bgx << 16; + + while (height-- > 0) { + u8 *p = dst; + + switch (bpp) { + + case 32: + for (i=0; i < width; i++) { + fb_writel(bgx, p); p += 4; + } + break; + case 24: + for (i=0; i < width; i++) { +#ifdef __LITTLE_ENDIAN + fb_writew((bgx & 0xffff),(u16*)p); p += 2; + fb_writeb((bgx >> 16),p++); +#else + fb_writew((bgx >> 8),(u16*)p); p += 2; + fb_writeb((bgx & 0xff),p++); +#endif + } + case 16: + for (i=0; i < width/4; i++) { + fb_writel(bgx,p); p += 4; + fb_writel(bgx,p); p += 4; + } + if (width & 2) { + fb_writel(bgx,p); p += 4; + } + if (width & 1) + fb_writew(bgx,(u16*)p); + break; + case 8: + for (i=0; i < width/4; i++) { + fb_writel(bgx,p); p += 4; + } + + if (width & 2) { + fb_writew(bgx,p); p += 2; + } + if (width & 1) + fb_writeb(bgx,(u8*)p); + break; + + } + dst += dstbytes; + } +} + +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, + int srclinebytes, int bpp) +{ + int i; + + while (height-- > 0) { + u32 *p = (u32 *)dst; + u32 *q = (u32 *)src; + + switch (bpp) { + + case 32: + for (i=0; i < width; i++) + fb_writel(*q++, p++); + break; + case 24: + for (i=0; i < (width*3/4); i++) + fb_writel(*q++, p++); + if ((width*3) % 4) { + if (width & 2) { + fb_writeb(*(u8*)q, (u8*)p); + } else if (width & 1) { + fb_writew(*(u16*)q, (u16*)p); + fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2)); + } + } + break; + case 16: + for (i=0; i < width/4; i++) { + fb_writel(*q++, p++); + fb_writel(*q++, p++); + } + if (width & 2) + fb_writel(*q++, p++); + if (width & 1) + fb_writew(*(u16*)q, (u16*)p); + break; + case 8: + for (i=0; i < width/4; i++) + fb_writel(*q++, p++); + + if (width & 2) { + fb_writew(*(u16*)q, (u16*)p); + q = (u32*) ((u16*)q + 1); + p = (u32*) ((u16*)p + 1); + } + if (width & 1) + fb_writeb(*(u8*)q, (u8*)p); + break; + } + + dst += linebytes; + src += srclinebytes; + } +} + +static void splashfill(struct fb_info *info, int sy, int sx, int height, + int width) +{ + int bytespp = ((info->var.bits_per_pixel + 7) >> 3); + int d = sy * info->fix.line_length + sx * bytespp; + int ds = (sy * info->var.xres + sx) * bytespp; + + fbsplash_copy((u8 *)(info->screen_base + d), (u8 *)(info->splash.data + ds), + height, width, info->fix.line_length, info->var.xres * bytespp, + info->var.bits_per_pixel); +} + +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, + int height, int width) +{ + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + int bg_color = attr_bgcol_ec(bgshift, vc); + int transparent = vc->vc_splash.bg_color == bg_color; + struct fbcon_ops *ops = info->fbcon_par; + u8 *dst; + + sy = sy * vc->vc_font.height + vc->vc_splash.ty; + sx = sx * vc->vc_font.width + vc->vc_splash.tx; + height *= vc->vc_font.height; + width *= vc->vc_font.width; + + /* Don't paint the background image if console is blanked */ + if (transparent && !ops->blank_state) { + splashfill(info, sy, sx, height, width); + } else { + dst = (u8 *)(info->screen_base + sy * info->fix.line_length + + sx * ((info->var.bits_per_pixel + 7) >> 3)); + splashset(dst, height, width, info->fix.line_length, cc2cx(bg_color), + info->var.bits_per_pixel); + } +} + +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only) +{ + unsigned int tw = vc->vc_cols*vc->vc_font.width; + unsigned int th = vc->vc_rows*vc->vc_font.height; + + if (!bottom_only) { + /* top margin */ + splashfill(info, 0, 0, vc->vc_splash.ty, info->var.xres); + /* left margin */ + splashfill(info, vc->vc_splash.ty, 0, th, vc->vc_splash.tx); + /* right margin */ + splashfill(info, vc->vc_splash.ty, vc->vc_splash.tx + tw, th, + info->var.xres - vc->vc_splash.tx - tw); + } + splashfill(info, vc->vc_splash.ty + th, 0, + info->var.yres - vc->vc_splash.ty - th, info->var.xres); +} + +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, + int sx, int dx, int width) +{ + u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2); + u16 *s = d + (dx - sx); + u16 *start = d; + u16 *ls = d; + u16 *le = d + width; + u16 c; + int x = dx; + u16 attr = 1; + + do { + c = scr_readw(d); + if (attr != (c & 0xff00)) { + attr = c & 0xff00; + if (d > start) { + fbsplash_putcs(vc, info, start, d - start, y, x); + x += d - start; + start = d; + } + } + if (s >= ls && s < le && c == scr_readw(s)) { + if (d > start) { + fbsplash_putcs(vc, info, start, d - start, y, x); + x += d - start + 1; + start = d + 1; + } else { + x++; + start++; + } + } + s++; + d++; + } while (d < le); + if (d > start) + fbsplash_putcs(vc, info, start, d - start, y, x); +} + +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) +{ + if (blank) { + splashset((u8 *)info->screen_base, info->var.yres, info->var.xres, + info->fix.line_length, 0, info->var.bits_per_pixel); + } else { + update_screen(vc); + fbsplash_clear_margins(vc, info, 0); + } +} + diff -urN oldtree/drivers/video/console/bitblit.c newtree/drivers/video/console/bitblit.c --- oldtree/drivers/video/console/bitblit.c 2006-01-03 03:21:10.000000000 +0000 +++ newtree/drivers/video/console/bitblit.c 2006-02-03 18:18:17.089732232 +0000 @@ -18,6 +18,7 @@ #include #include #include "fbcon.h" +#include "../fbsplash.h" /* * Accelerated handlers. @@ -55,6 +56,13 @@ area.height = height * vc->vc_font.height; area.width = width * vc->vc_font.width; + if (fbsplash_active(info, vc)) { + area.sx += vc->vc_splash.tx; + area.sy += vc->vc_splash.ty; + area.dx += vc->vc_splash.tx; + area.dy += vc->vc_splash.ty; + } + info->fbops->fb_copyarea(info, &area); } @@ -380,11 +388,15 @@ cursor.image.depth = 1; cursor.rop = ROP_XOR; - if (info->fbops->fb_cursor) - err = info->fbops->fb_cursor(info, &cursor); + if (fbsplash_active(info, vc)) { + fbsplash_cursor(info, &cursor); + } else { + if (info->fbops->fb_cursor) + err = info->fbops->fb_cursor(info, &cursor); - if (err) - soft_cursor(info, &cursor); + if (err) + soft_cursor(info, &cursor); + } ops->cursor_reset = 0; } diff -urN oldtree/drivers/video/console/fbcon.c newtree/drivers/video/console/fbcon.c --- oldtree/drivers/video/console/fbcon.c 2006-01-03 03:21:10.000000000 +0000 +++ newtree/drivers/video/console/fbcon.c 2006-02-03 18:18:17.095731320 +0000 @@ -93,6 +93,7 @@ #endif #include "fbcon.h" +#include "../fbsplash.h" #ifdef FBCONDEBUG # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) @@ -108,7 +109,7 @@ static struct display fb_display[MAX_NR_CONSOLES]; -static signed char con2fb_map[MAX_NR_CONSOLES]; +signed char con2fb_map[MAX_NR_CONSOLES]; static signed char con2fb_map_boot[MAX_NR_CONSOLES]; static int logo_height; static int logo_lines; @@ -298,7 +299,7 @@ vc->vc_mode != KD_TEXT || ops->graphics); } -static inline int get_color(struct vc_data *vc, struct fb_info *info, +inline int get_color(struct vc_data *vc, struct fb_info *info, u16 c, int is_fg) { int depth = fb_get_color_depth(&info->var, &info->fix); @@ -404,6 +405,7 @@ CM_ERASE : CM_DRAW; ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1), get_color(vc, info, c, 0)); + release_console_sem(); } @@ -568,6 +570,8 @@ info_idx = -1; } + fbsplash_init(); + return err; } @@ -975,6 +979,12 @@ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; + + if (fbsplash_active(info, vc)) { + cols = vc->vc_splash.twidth / vc->vc_font.width; + rows = vc->vc_splash.theight / vc->vc_font.height; + } + vc_resize(vc, cols, rows); DPRINTK("mode: %s\n", info->fix.id); @@ -1057,7 +1067,7 @@ cap = info->flags; if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || - (info->fix.type == FB_TYPE_TEXT)) + (info->fix.type == FB_TYPE_TEXT) || fbsplash_active(info, vc)) logo = 0; if (var_to_display(p, &info->var, info)) @@ -1197,6 +1207,11 @@ if (!height || !width) return; + if (fbsplash_active(info, vc)) { + fbsplash_clear(vc, info, sy, sx, height, width); + return; + } + /* Split blits that cross physical y_wrap boundary */ y_break = p->vrows - p->yscroll; @@ -1216,10 +1231,15 @@ struct display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; - if (!fbcon_is_inactive(vc, info)) - ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, - get_color(vc, info, scr_readw(s), 1), - get_color(vc, info, scr_readw(s), 0)); + if (!fbcon_is_inactive(vc, info)) { + + if (fbsplash_active(info, vc)) + fbsplash_putcs(vc, info, s, count, ypos, xpos); + else + ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, + get_color(vc, info, scr_readw(s), 1), + get_color(vc, info, scr_readw(s), 0)); + } } static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) @@ -1235,8 +1255,13 @@ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - if (!fbcon_is_inactive(vc, info)) - ops->clear_margins(vc, info, bottom_only); + if (!fbcon_is_inactive(vc, info)) { + if (fbsplash_active(info, vc)) { + fbsplash_clear_margins(vc, info, bottom_only); + } else { + ops->clear_margins(vc, info, bottom_only); + } + } } static void fbcon_cursor(struct vc_data *vc, int mode) @@ -1716,7 +1741,7 @@ count = vc->vc_rows; if (softback_top) fbcon_softback_note(vc, t, count); - if (logo_shown >= 0) + if (logo_shown >= 0 || fbsplash_active(info, vc)) goto redraw_up; switch (p->scrollmode) { case SCROLL_MOVE: @@ -1804,6 +1829,8 @@ count = vc->vc_rows; if (logo_shown >= 0) goto redraw_down; + if (fbsplash_active(info, vc)) + goto redraw_down; switch (p->scrollmode) { case SCROLL_MOVE: ops->bmove(vc, info, t, 0, t + count, 0, @@ -1946,6 +1973,13 @@ } return; } + + if (fbsplash_active(info, vc) && sy == dy && height == 1) { + /* must use slower redraw bmove to keep background pic intact */ + fbsplash_bmove_redraw(vc, info, sy, sx, dx, width); + return; + } + ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx, height, width); } @@ -2015,8 +2049,9 @@ var.yres = virt_h * virt_fh; x_diff = info->var.xres - var.xres; y_diff = info->var.yres - var.yres; - if (x_diff < 0 || x_diff > virt_fw || - y_diff < 0 || y_diff > virt_fh) { + + if ((x_diff < 0 || x_diff > virt_fw || + y_diff < 0 || y_diff > virt_fh) && !vc->vc_splash.state) { struct fb_videomode *mode; DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); @@ -2052,7 +2087,26 @@ info = registered_fb[con2fb_map[vc->vc_num]]; ops = info->fbcon_par; - + prev_console = ops->currcon; + if (prev_console != -1) + old_info = registered_fb[con2fb_map[prev_console]]; + + if (fbsplash_active_vc(vc)) { + struct vc_data *vc_curr = vc_cons[prev_console].d; + if (!vc_curr->vc_splash.theme || strcmp(vc->vc_splash.theme, vc_curr->vc_splash.theme)) { + if (fbsplash_call_helper("getpic", vc->vc_num)) + fbsplash_disable(vc, 0); + } + } else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + struct vc_data *vc_curr = vc_cons[prev_console].d; + if (vc_curr && fbsplash_active_vc(vc_curr)) { + /* Clear the screen to avoid displaying funky colors during + * palette updates. */ + memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset, + 0, info->var.yres * info->fix.line_length); + } + } + if (softback_top) { if (softback_lines) fbcon_set_origin(vc); @@ -2070,9 +2124,6 @@ logo_shown = FBCON_LOGO_CANSHOW; } - prev_console = ops->currcon; - if (prev_console != -1) - old_info = registered_fb[con2fb_map[prev_console]]; /* * FIXME: If we have multiple fbdev's loaded, we need to * update all info->currcon. Perhaps, we can place this @@ -2111,6 +2162,11 @@ fbcon_add_cursor_timer(info); } + if (fbsplash_active_nores(info, vc) && !fbsplash_active(info, vc)) { + if (fbsplash_call_helper("modechange", vc->vc_num)) + fbsplash_disable(vc, 0); + } + set_blitting_type(vc, info, p); ops->cursor_reset = 1; @@ -2212,8 +2268,12 @@ fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); ops->cursor_flash = (!blank); - if (fb_blank(info, blank)) - fbcon_generic_blank(vc, info, blank); + if (fb_blank(info, blank)) { + if (fbsplash_active(info, vc)) + fbsplash_blank(vc, info, blank); + else + fbcon_generic_blank(vc, info, blank); + } } if (!blank) @@ -2371,13 +2431,22 @@ } if (resize) { + /* reset wrap/pan */ int cols, rows; cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + if (fbsplash_active(info, vc)) { + cols = vc->vc_splash.twidth; + rows = vc->vc_splash.theight; + } cols /= w; rows /= h; + vc_resize(vc, cols, rows); + if (CON_IS_VISIBLE(vc) && softback_buf) fbcon_update_softback(vc); } else if (CON_IS_VISIBLE(vc) @@ -2495,7 +2564,7 @@ int i, j, k, depth; u8 val; - if (fbcon_is_inactive(vc, info)) + if (fbcon_is_inactive(vc, info) || vc->vc_num != fg_console) return -EINVAL; if (!CON_IS_VISIBLE(vc)) @@ -2521,7 +2590,49 @@ } else fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); - return fb_set_cmap(&palette_cmap, info); + if (fbsplash_active(info, vc_cons[fg_console].d) && + info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + + u16 *red, *green, *blue; + int minlen = min(min(info->var.red.length, info->var.green.length), + info->var.blue.length); + int h; + + struct fb_cmap cmap = { + .start = 0, + .len = (1 << minlen), + .red = NULL, + .green = NULL, + .blue = NULL, + .transp = NULL + }; + + red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL); + + if (!red) + goto out; + + green = red + 256; + blue = green + 256; + cmap.red = red; + cmap.green = green; + cmap.blue = blue; + + for (i = 0; i < cmap.len; i++) { + red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1); + } + + h = fb_set_cmap(&cmap, info); + fbsplash_fix_pseudo_pal(info, vc_cons[fg_console].d); + kfree(red); + + return h; + + } else if (fbsplash_active(info, vc_cons[fg_console].d) && + info->var.bits_per_pixel == 8 && info->splash.cmap.red != NULL) + fb_set_cmap(&info->splash.cmap, info); + +out: return fb_set_cmap(&palette_cmap, info); } static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) @@ -2747,7 +2858,14 @@ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; - vc_resize(vc, cols, rows); + + if (!fbsplash_active_nores(info, vc)) { + vc_resize(vc, cols, rows); + } else { + if (fbsplash_call_helper("modechange", vc->vc_num)) + fbsplash_disable(vc, 0); + } + updatescrollmode(p, info, vc); scrollback_max = 0; scrollback_current = 0; diff -urN oldtree/drivers/video/console/fbcon.c.orig newtree/drivers/video/console/fbcon.c.orig --- oldtree/drivers/video/console/fbcon.c.orig 1970-01-01 00:00:00.000000000 +0000 +++ newtree/drivers/video/console/fbcon.c.orig 2006-01-03 03:21:10.000000000 +0000 @@ -0,0 +1,3039 @@ +/* + * linux/drivers/video/fbcon.c -- Low level frame buffer based console driver + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * + * This file is based on the original Amiga console driver (amicon.c): + * + * Copyright (C) 1993 Hamish Macdonald + * Greg Harp + * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk] + * + * with work by William Rucklidge (wjr@cs.cornell.edu) + * Geert Uytterhoeven + * Jes Sorensen (jds@kom.auc.dk) + * Martin Apel + * + * and on the original Atari console driver (atacon.c): + * + * Copyright (C) 1993 Bjoern Brauel + * Roman Hodek + * + * with work by Guenther Kelleter + * Martin Schaller + * Andreas Schwab + * + * Hardware cursor support added by Emmanuel Marty (core@ggi-project.org) + * Smart redraw scrolling, arbitrary font width support, 512char font support + * and software scrollback added by + * Jakub Jelinek (jj@ultra.linux.cz) + * + * Random hacking by Martin Mares + * + * 2001 - Documented with DocBook + * - Brad Douglas + * + * The low level operations for the various display memory organizations are + * now in separate source files. + * + * Currently the following organizations are supported: + * + * o afb Amiga bitplanes + * o cfb{2,4,8,16,24,32} Packed pixels + * o ilbm Amiga interleaved bitplanes + * o iplan2p[248] Atari interleaved bitplanes + * o mfb Monochrome + * o vga VGA characters/attributes + * + * To do: + * + * - Implement 16 plane mode (iplan2p16) + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#undef FBCONDEBUG + +#include +#include +#include +#include +#include +#include +#include /* MSch: for IRQ probe */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For counting font checksums */ +#include +#include +#include +#ifdef CONFIG_ATARI +#include +#endif +#ifdef CONFIG_MAC +#include +#endif +#if defined(__mc68000__) || defined(CONFIG_APUS) +#include +#include +#endif + +#include "fbcon.h" + +#ifdef FBCONDEBUG +# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) +#else +# define DPRINTK(fmt, args...) +#endif + +enum { + FBCON_LOGO_CANSHOW = -1, /* the logo can be shown */ + FBCON_LOGO_DRAW = -2, /* draw the logo to a console */ + FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */ +}; + +static struct display fb_display[MAX_NR_CONSOLES]; + +static signed char con2fb_map[MAX_NR_CONSOLES]; +static signed char con2fb_map_boot[MAX_NR_CONSOLES]; +static int logo_height; +static int logo_lines; +/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO + enums. */ +static int logo_shown = FBCON_LOGO_CANSHOW; +/* Software scrollback */ +static int fbcon_softback_size = 32768; +static unsigned long softback_buf, softback_curr; +static unsigned long softback_in; +static unsigned long softback_top, softback_end; +static int softback_lines; +/* console mappings */ +static int first_fb_vc; +static int last_fb_vc = MAX_NR_CONSOLES - 1; +static int fbcon_is_default = 1; +/* font data */ +static char fontname[40]; + +/* current fb_info */ +static int info_idx = -1; + +/* console rotation */ +static int rotate; + +static const struct consw fb_con; + +#define CM_SOFTBACK (8) + +#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) + +static void fbcon_free_font(struct display *); +static int fbcon_set_origin(struct vc_data *); + +#define CURSOR_DRAW_DELAY (1) + +/* # VBL ints between cursor state changes */ +#define ATARI_CURSOR_BLINK_RATE (42) +#define MAC_CURSOR_BLINK_RATE (32) +#define DEFAULT_CURSOR_BLINK_RATE (20) + +static int vbl_cursor_cnt; + +#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1) + +/* + * Interface used by the world + */ + +static const char *fbcon_startup(void); +static void fbcon_init(struct vc_data *vc, int init); +static void fbcon_deinit(struct vc_data *vc); +static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, + int width); +static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos); +static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, + int count, int ypos, int xpos); +static void fbcon_clear_margins(struct vc_data *vc, int bottom_only); +static void fbcon_cursor(struct vc_data *vc, int mode); +static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, + int count); +static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, + int height, int width); +static int fbcon_switch(struct vc_data *vc); +static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); +static int fbcon_set_palette(struct vc_data *vc, unsigned char *table); +static int fbcon_scrolldelta(struct vc_data *vc, int lines); + +/* + * Internal routines + */ +static __inline__ void ywrap_up(struct vc_data *vc, int count); +static __inline__ void ywrap_down(struct vc_data *vc, int count); +static __inline__ void ypan_up(struct vc_data *vc, int count); +static __inline__ void ypan_down(struct vc_data *vc, int count); +static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, + int dy, int dx, int height, int width, u_int y_break); +static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, + struct vc_data *vc); +static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var, + int unit); +static void fbcon_redraw_move(struct vc_data *vc, struct display *p, + int line, int count, int dy); +static void fbcon_modechanged(struct fb_info *info); +static void fbcon_set_all_vcs(struct fb_info *info); + +#ifdef CONFIG_MAC +/* + * On the Macintoy, there may or may not be a working VBL int. We need to probe + */ +static int vbl_detected; + +static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) +{ + vbl_detected++; + return IRQ_HANDLED; +} +#endif + +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION +static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + + if (!(info->flags & FBINFO_MISC_TILEBLITTING) && + p->con_rotate < 4) + ops->rotate = p->con_rotate; + else + ops->rotate = 0; +} + +static void fbcon_rotate(struct fb_info *info, u32 rotate) +{ + struct fbcon_ops *ops= info->fbcon_par; + struct fb_info *fb_info; + + if (!ops || ops->currcon == -1) + return; + + fb_info = registered_fb[con2fb_map[ops->currcon]]; + + if (info == fb_info) { + struct display *p = &fb_display[ops->currcon]; + + if (rotate < 4) + p->con_rotate = rotate; + else + p->con_rotate = 0; + + fbcon_modechanged(info); + } +} + +static void fbcon_rotate_all(struct fb_info *info, u32 rotate) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; + struct display *p; + int i; + + if (!ops || ops->currcon < 0 || rotate > 3) + return; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + vc = vc_cons[i].d; + if (!vc || vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[i]] != info) + continue; + + p = &fb_display[vc->vc_num]; + p->con_rotate = rotate; + } + + fbcon_set_all_vcs(info); +} +#else +static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + + ops->rotate = FB_ROTATE_UR; +} + +static void fbcon_rotate(struct fb_info *info, u32 rotate) +{ + return; +} + +static void fbcon_rotate_all(struct fb_info *info, u32 rotate) +{ + return; +} +#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */ + +static int fbcon_get_rotate(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + + return (ops) ? ops->rotate : 0; +} + +static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + + return (info->state != FBINFO_STATE_RUNNING || + vc->vc_mode != KD_TEXT || ops->graphics); +} + +static inline int get_color(struct vc_data *vc, struct fb_info *info, + u16 c, int is_fg) +{ + int depth = fb_get_color_depth(&info->var, &info->fix); + int color = 0; + + if (console_blanked) { + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + + c = vc->vc_video_erase_char & charmask; + } + + if (depth != 1) + color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c) + : attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c); + + switch (depth) { + case 1: + { + int col = ~(0xfff << (max(info->var.green.length, + max(info->var.red.length, + info->var.blue.length)))) & 0xff; + + /* 0 or 1 */ + int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0; + int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col; + + if (console_blanked) + fg = bg; + + color = (is_fg) ? fg : bg; + break; + } + case 2: + /* + * Scale down 16-colors to 4 colors. Default 4-color palette + * is grayscale. However, simply dividing the values by 4 + * will not work, as colors 1, 2 and 3 will be scaled-down + * to zero rendering them invisible. So empirically convert + * colors to a sane 4-level grayscale. + */ + switch (color) { + case 0: + color = 0; /* black */ + break; + case 1 ... 6: + color = 2; /* white */ + break; + case 7 ... 8: + color = 1; /* gray */ + break; + default: + color = 3; /* intense white */ + break; + } + break; + case 3: + /* + * Last 8 entries of default 16-color palette is a more intense + * version of the first 8 (i.e., same chrominance, different + * luminance). + */ + color &= 7; + break; + } + + + return color; +} + +static void fbcon_update_softback(struct vc_data *vc) +{ + int l = fbcon_softback_size / vc->vc_size_row; + + if (l > 5) + softback_end = softback_buf + l * vc->vc_size_row; + else + /* Smaller scrollback makes no sense, and 0 would screw + the operation totally */ + softback_top = 0; +} + +static void fb_flashcursor(void *private) +{ + struct fb_info *info = private; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p; + struct vc_data *vc = NULL; + int c; + int mode; + + if (ops->currcon != -1) + vc = vc_cons[ops->currcon].d; + + if (!vc || !CON_IS_VISIBLE(vc) || + fbcon_is_inactive(vc, info) || + registered_fb[con2fb_map[vc->vc_num]] != info || + vc_cons[ops->currcon].d->vc_deccm != 1) + return; + acquire_console_sem(); + p = &fb_display[vc->vc_num]; + c = scr_readw((u16 *) vc->vc_pos); + mode = (!ops->cursor_flash || ops->cursor_state.enable) ? + CM_ERASE : CM_DRAW; + ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1), + get_color(vc, info, c, 0)); + release_console_sem(); +} + +#if defined(CONFIG_ATARI) || defined(CONFIG_MAC) +static int cursor_blink_rate; +static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) +{ + struct fb_info *info = dev_id; + + if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) { + schedule_work(&info->queue); + vbl_cursor_cnt = cursor_blink_rate; + } + return IRQ_HANDLED; +} +#endif + +static void cursor_timer_handler(unsigned long dev_addr) +{ + struct fb_info *info = (struct fb_info *) dev_addr; + struct fbcon_ops *ops = info->fbcon_par; + + schedule_work(&info->queue); + mod_timer(&ops->cursor_timer, jiffies + HZ/5); +} + +static void fbcon_add_cursor_timer(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + + if ((!info->queue.func || info->queue.func == fb_flashcursor) && + !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) { + if (!info->queue.func) + INIT_WORK(&info->queue, fb_flashcursor, info); + + init_timer(&ops->cursor_timer); + ops->cursor_timer.function = cursor_timer_handler; + ops->cursor_timer.expires = jiffies + HZ / 5; + ops->cursor_timer.data = (unsigned long ) info; + add_timer(&ops->cursor_timer); + ops->flags |= FBCON_FLAGS_CURSOR_TIMER; + } +} + +static void fbcon_del_cursor_timer(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + + if (info->queue.func == fb_flashcursor && + ops->flags & FBCON_FLAGS_CURSOR_TIMER) { + del_timer_sync(&ops->cursor_timer); + ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER; + } +} + +#ifndef MODULE +static int __init fb_console_setup(char *this_opt) +{ + char *options; + int i, j; + + if (!this_opt || !*this_opt) + return 0; + + while ((options = strsep(&this_opt, ",")) != NULL) { + if (!strncmp(options, "font:", 5)) + strcpy(fontname, options + 5); + + if (!strncmp(options, "scrollback:", 11)) { + options += 11; + if (*options) { + fbcon_softback_size = simple_strtoul(options, &options, 0); + if (*options == 'k' || *options == 'K') { + fbcon_softback_size *= 1024; + options++; + } + if (*options != ',') + return 0; + options++; + } else + return 0; + } + + if (!strncmp(options, "map:", 4)) { + options += 4; + if (*options) + for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) { + if (!options[j]) + j = 0; + con2fb_map_boot[i] = + (options[j++]-'0') % FB_MAX; + } + return 0; + } + + if (!strncmp(options, "vc:", 3)) { + options += 3; + if (*options) + first_fb_vc = simple_strtoul(options, &options, 10) - 1; + if (first_fb_vc < 0) + first_fb_vc = 0; + if (*options++ == '-') + last_fb_vc = simple_strtoul(options, &options, 10) - 1; + fbcon_is_default = 0; + } + + if (!strncmp(options, "rotate:", 7)) { + options += 7; + if (*options) + rotate = simple_strtoul(options, &options, 0); + if (rotate > 3) + rotate = 0; + } + } + return 0; +} + +__setup("fbcon=", fb_console_setup); +#endif + +static int search_fb_in_map(int idx) +{ + int i, retval = 0; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map[i] == idx) + retval = 1; + } + return retval; +} + +static int search_for_mapped_con(void) +{ + int i, retval = 0; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map[i] != -1) + retval = 1; + } + return retval; +} + +static int fbcon_takeover(int show_logo) +{ + int err, i; + + if (!num_registered_fb) + return -ENODEV; + + if (!show_logo) + logo_shown = FBCON_LOGO_DONTSHOW; + + for (i = first_fb_vc; i <= last_fb_vc; i++) + con2fb_map[i] = info_idx; + + err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, + fbcon_is_default); + if (err) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + con2fb_map[i] = -1; + } + info_idx = -1; + } + + return err; +} + +static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, + int cols, int rows, int new_cols, int new_rows) +{ + /* Need to make room for the logo */ + struct fbcon_ops *ops = info->fbcon_par; + int cnt, erase = vc->vc_video_erase_char, step; + unsigned short *save = NULL, *r, *q; + + /* + * remove underline attribute from erase character + * if black and white framebuffer. + */ + if (fb_get_color_depth(&info->var, &info->fix) == 1) + erase &= ~0x400; + logo_height = fb_prepare_logo(info, ops->rotate); + logo_lines = (logo_height + vc->vc_font.height - 1) / + vc->vc_font.height; + q = (unsigned short *) (vc->vc_origin + + vc->vc_size_row * rows); + step = logo_lines * cols; + for (r = q - logo_lines * cols; r < q; r++) + if (scr_readw(r) != vc->vc_video_erase_char) + break; + if (r != q && new_rows >= rows + logo_lines) { + save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL); + if (save) { + int i = cols < new_cols ? cols : new_cols; + scr_memsetw(save, erase, logo_lines * new_cols * 2); + r = q - step; + for (cnt = 0; cnt < logo_lines; cnt++, r += i) + scr_memcpyw(save + cnt * new_cols, r, 2 * i); + r = q; + } + } + if (r == q) { + /* We can scroll screen down */ + r = q - step - cols; + for (cnt = rows - logo_lines; cnt > 0; cnt--) { + scr_memcpyw(r + step, r, vc->vc_size_row); + r -= cols; + } + if (!save) { + vc->vc_y += logo_lines; + vc->vc_pos += logo_lines * vc->vc_size_row; + } + } + scr_memsetw((unsigned short *) vc->vc_origin, + erase, + vc->vc_size_row * logo_lines); + + if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { + fbcon_clear_margins(vc, 0); + update_screen(vc); + } + + if (save) { + q = (unsigned short *) (vc->vc_origin + + vc->vc_size_row * + rows); + scr_memcpyw(q, save, logo_lines * new_cols * 2); + vc->vc_y += logo_lines; + vc->vc_pos += logo_lines * vc->vc_size_row; + kfree(save); + } + + if (logo_lines > vc->vc_bottom) { + logo_shown = FBCON_LOGO_CANSHOW; + printk(KERN_INFO + "fbcon_init: disable boot-logo (boot-logo bigger than screen).\n"); + } else if (logo_shown != FBCON_LOGO_DONTSHOW) { + logo_shown = FBCON_LOGO_DRAW; + vc->vc_top = logo_lines; + } +} + +#ifdef CONFIG_FB_TILEBLITTING +static void set_blitting_type(struct vc_data *vc, struct fb_info *info, + struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + + ops->p = (p) ? p : &fb_display[vc->vc_num]; + + if ((info->flags & FBINFO_MISC_TILEBLITTING)) + fbcon_set_tileops(vc, info, p, ops); + else { + fbcon_set_rotation(info, ops->p); + fbcon_set_bitops(ops); + } +} +#else +static void set_blitting_type(struct vc_data *vc, struct fb_info *info, + struct display *p) +{ + struct fbcon_ops *ops = info->fbcon_par; + + info->flags &= ~FBINFO_MISC_TILEBLITTING; + ops->p = (p) ? p : &fb_display[vc->vc_num]; + fbcon_set_rotation(info, ops->p); + fbcon_set_bitops(ops); +} +#endif /* CONFIG_MISC_TILEBLITTING */ + + +static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, + int unit, int oldidx) +{ + struct fbcon_ops *ops = NULL; + int err = 0; + + if (!try_module_get(info->fbops->owner)) + err = -ENODEV; + + if (!err && info->fbops->fb_open && + info->fbops->fb_open(info, 0)) + err = -ENODEV; + + if (!err) { + ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL); + if (!ops) + err = -ENOMEM; + } + + if (!err) { + memset(ops, 0, sizeof(struct fbcon_ops)); + info->fbcon_par = ops; + set_blitting_type(vc, info, NULL); + } + + if (err) { + con2fb_map[unit] = oldidx; + module_put(info->fbops->owner); + } + + return err; +} + +static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, + struct fb_info *newinfo, int unit, + int oldidx, int found) +{ + struct fbcon_ops *ops = oldinfo->fbcon_par; + int err = 0; + + if (oldinfo->fbops->fb_release && + oldinfo->fbops->fb_release(oldinfo, 0)) { + con2fb_map[unit] = oldidx; + if (!found && newinfo->fbops->fb_release) + newinfo->fbops->fb_release(newinfo, 0); + if (!found) + module_put(newinfo->fbops->owner); + err = -ENODEV; + } + + if (!err) { + fbcon_del_cursor_timer(oldinfo); + kfree(ops->cursor_state.mask); + kfree(ops->cursor_data); + kfree(ops->fontbuffer); + kfree(oldinfo->fbcon_par); + oldinfo->fbcon_par = NULL; + module_put(oldinfo->fbops->owner); + /* + If oldinfo and newinfo are driving the same hardware, + the fb_release() method of oldinfo may attempt to + restore the hardware state. This will leave the + newinfo in an undefined state. Thus, a call to + fb_set_par() may be needed for the newinfo. + */ + if (newinfo->fbops->fb_set_par) + newinfo->fbops->fb_set_par(newinfo); + } + + return err; +} + +static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, + int unit, int show_logo) +{ + struct fbcon_ops *ops = info->fbcon_par; + + ops->currcon = fg_console; + + if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT)) + info->fbops->fb_set_par(info); + + ops->flags |= FBCON_FLAGS_INIT; + ops->graphics = 0; + + if (vc) + fbcon_set_disp(info, &info->var, vc); + else + fbcon_preset_disp(info, &info->var, unit); + + if (show_logo) { + struct vc_data *fg_vc = vc_cons[fg_console].d; + struct fb_info *fg_info = + registered_fb[con2fb_map[fg_console]]; + + fbcon_prepare_logo(fg_vc, fg_info, fg_vc->vc_cols, + fg_vc->vc_rows, fg_vc->vc_cols, + fg_vc->vc_rows); + } + + update_screen(vc_cons[fg_console].d); +} + +/** + * set_con2fb_map - map console to frame buffer device + * @unit: virtual console number to map + * @newidx: frame buffer index to map virtual console to + * @user: user request + * + * Maps a virtual console @unit to a frame buffer device + * @newidx. + */ +static int set_con2fb_map(int unit, int newidx, int user) +{ + struct vc_data *vc = vc_cons[unit].d; + int oldidx = con2fb_map[unit]; + struct fb_info *info = registered_fb[newidx]; + struct fb_info *oldinfo = NULL; + int found, err = 0; + + if (oldidx == newidx) + return 0; + + if (!info) + err = -EINVAL; + + if (!err && !search_for_mapped_con()) { + info_idx = newidx; + return fbcon_takeover(0); + } + + if (oldidx != -1) + oldinfo = registered_fb[oldidx]; + + found = search_fb_in_map(newidx); + + acquire_console_sem(); + con2fb_map[unit] = newidx; + if (!err && !found) + err = con2fb_acquire_newinfo(vc, info, unit, oldidx); + + + /* + * If old fb is not mapped to any of the consoles, + * fbcon should release it. + */ + if (!err && oldinfo && !search_fb_in_map(oldidx)) + err = con2fb_release_oldinfo(vc, oldinfo, info, unit, oldidx, + found); + + if (!err) { + int show_logo = (fg_console == 0 && !user && + logo_shown != FBCON_LOGO_DONTSHOW); + + if (!found) + fbcon_add_cursor_timer(info); + con2fb_map_boot[unit] = newidx; + con2fb_init_display(vc, info, unit, show_logo); + } + + release_console_sem(); + return err; +} + +/* + * Low Level Operations + */ +/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */ +static int var_to_display(struct display *disp, + struct fb_var_screeninfo *var, + struct fb_info *info) +{ + disp->xres_virtual = var->xres_virtual; + disp->yres_virtual = var->yres_virtual; + disp->bits_per_pixel = var->bits_per_pixel; + disp->grayscale = var->grayscale; + disp->nonstd = var->nonstd; + disp->accel_flags = var->accel_flags; + disp->height = var->height; + disp->width = var->width; + disp->red = var->red; + disp->green = var->green; + disp->blue = var->blue; + disp->transp = var->transp; + disp->rotate = var->rotate; + disp->mode = fb_match_mode(var, &info->modelist); + if (disp->mode == NULL) + /* This should not happen */ + return -EINVAL; + return 0; +} + +static void display_to_var(struct fb_var_screeninfo *var, + struct display *disp) +{ + fb_videomode_to_var(var, disp->mode); + var->xres_virtual = disp->xres_virtual; + var->yres_virtual = disp->yres_virtual; + var->bits_per_pixel = disp->bits_per_pixel; + var->grayscale = disp->grayscale; + var->nonstd = disp->nonstd; + var->accel_flags = disp->accel_flags; + var->height = disp->height; + var->width = disp->width; + var->red = disp->red; + var->green = disp->green; + var->blue = disp->blue; + var->transp = disp->transp; + var->rotate = disp->rotate; +} + +static const char *fbcon_startup(void) +{ + const char *display_desc = "frame buffer device"; + struct display *p = &fb_display[fg_console]; + struct vc_data *vc = vc_cons[fg_console].d; + const struct font_desc *font = NULL; + struct module *owner; + struct fb_info *info = NULL; + struct fbcon_ops *ops; + int rows, cols; + int irqres; + + irqres = 1; + /* + * If num_registered_fb is zero, this is a call for the dummy part. + * The frame buffer devices weren't initialized yet. + */ + if (!num_registered_fb || info_idx == -1) + return display_desc; + /* + * Instead of blindly using registered_fb[0], we use info_idx, set by + * fb_console_init(); + */ + info = registered_fb[info_idx]; + if (!info) + return NULL; + + owner = info->fbops->owner; + if (!try_module_get(owner)) + return NULL; + if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { + module_put(owner); + return NULL; + } + + ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL); + if (!ops) { + module_put(owner); + return NULL; + } + + memset(ops, 0, sizeof(struct fbcon_ops)); + ops->currcon = -1; + ops->graphics = 1; + ops->cur_rotate = -1; + info->fbcon_par = ops; + p->con_rotate = rotate; + set_blitting_type(vc, info, NULL); + + if (info->fix.type != FB_TYPE_TEXT) { + if (fbcon_softback_size) { + if (!softback_buf) { + softback_buf = + (unsigned long) + kmalloc(fbcon_softback_size, + GFP_KERNEL); + if (!softback_buf) { + fbcon_softback_size = 0; + softback_top = 0; + } + } + } else { + if (softback_buf) { + kfree((void *) softback_buf); + softback_buf = 0; + softback_top = 0; + } + } + if (softback_buf) + softback_in = softback_top = softback_curr = + softback_buf; + softback_lines = 0; + } + + /* Setup default font */ + if (!p->fontdata) { + if (!fontname[0] || !(font = find_font(fontname))) + font = get_default_font(info->var.xres, + info->var.yres); + vc->vc_font.width = font->width; + vc->vc_font.height = font->height; + vc->vc_font.data = (void *)(p->fontdata = font->data); + vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ + } + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; + vc_resize(vc, cols, rows); + + DPRINTK("mode: %s\n", info->fix.id); + DPRINTK("visual: %d\n", info->fix.visual); + DPRINTK("res: %dx%d-%d\n", info->var.xres, + info->var.yres, + info->var.bits_per_pixel); + +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + cursor_blink_rate = ATARI_CURSOR_BLINK_RATE; + irqres = + request_irq(IRQ_AUTO_4, fb_vbl_handler, + IRQ_TYPE_PRIO, "framebuffer vbl", + info); + } +#endif /* CONFIG_ATARI */ + +#ifdef CONFIG_MAC + /* + * On a Macintoy, the VBL interrupt may or may not be active. + * As interrupt based cursor is more reliable and race free, we + * probe for VBL interrupts. + */ + if (MACH_IS_MAC) { + int ct = 0; + /* + * Probe for VBL: set temp. handler ... + */ + irqres = request_irq(IRQ_MAC_VBL, fb_vbl_detect, 0, + "framebuffer vbl", info); + vbl_detected = 0; + + /* + * ... and spin for 20 ms ... + */ + while (!vbl_detected && ++ct < 1000) + udelay(20); + + if (ct == 1000) + printk + ("fbcon_startup: No VBL detected, using timer based cursor.\n"); + + free_irq(IRQ_MAC_VBL, fb_vbl_detect); + + if (vbl_detected) { + /* + * interrupt based cursor ok + */ + cursor_blink_rate = MAC_CURSOR_BLINK_RATE; + irqres = + request_irq(IRQ_MAC_VBL, fb_vbl_handler, 0, + "framebuffer vbl", info); + } else { + /* + * VBL not detected: fall through, use timer based cursor + */ + irqres = 1; + } + } +#endif /* CONFIG_MAC */ + + fbcon_add_cursor_timer(info); + return display_desc; +} + +static void fbcon_init(struct vc_data *vc, int init) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops; + struct vc_data **default_mode = vc->vc_display_fg; + struct vc_data *svc = *default_mode; + struct display *t, *p = &fb_display[vc->vc_num]; + int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; + int cap; + + if (info_idx == -1 || info == NULL) + return; + + cap = info->flags; + + if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || + (info->fix.type == FB_TYPE_TEXT)) + logo = 0; + + if (var_to_display(p, &info->var, info)) + return; + + /* If we are not the first console on this + fb, copy the font from that console */ + t = &fb_display[svc->vc_num]; + if (!vc->vc_font.data) { + vc->vc_font.data = (void *)(p->fontdata = t->fontdata); + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; + } + if (p->userfont) + charcnt = FNTCHARCNT(p->fontdata); + vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + if (charcnt == 256) { + vc->vc_hi_font_mask = 0; + } else { + vc->vc_hi_font_mask = 0x100; + if (vc->vc_can_do_color) + vc->vc_complement_mask <<= 1; + } + + if (!*svc->vc_uni_pagedir_loc) + con_set_default_unimap(svc); + if (!*vc->vc_uni_pagedir_loc) + con_copy_unimap(vc, svc); + + ops = info->fbcon_par; + p->con_rotate = rotate; + set_blitting_type(vc, info, NULL); + + cols = vc->vc_cols; + rows = vc->vc_rows; + new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + new_cols /= vc->vc_font.width; + new_rows /= vc->vc_font.height; + vc_resize(vc, new_cols, new_rows); + + /* + * We must always set the mode. The mode of the previous console + * driver could be in the same resolution but we are using different + * hardware so we have to initialize the hardware. + * + * We need to do it in fbcon_init() to prevent screen corruption. + */ + if (CON_IS_VISIBLE(vc)) { + if (info->fbops->fb_set_par && + !(ops->flags & FBCON_FLAGS_INIT)) + info->fbops->fb_set_par(info); + ops->flags |= FBCON_FLAGS_INIT; + } + + ops->graphics = 0; + + if ((cap & FBINFO_HWACCEL_COPYAREA) && + !(cap & FBINFO_HWACCEL_DISABLED)) + p->scrollmode = SCROLL_MOVE; + else /* default to something safe */ + p->scrollmode = SCROLL_REDRAW; + + /* + * ++guenther: console.c:vc_allocate() relies on initializing + * vc_{cols,rows}, but we must not set those if we are only + * resizing the console. + */ + if (!init) { + vc->vc_cols = new_cols; + vc->vc_rows = new_rows; + } + + if (logo) + fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); + + if (vc == svc && softback_buf) + fbcon_update_softback(vc); + + if (ops->rotate_font && ops->rotate_font(info, vc, p)) { + ops->rotate = FB_ROTATE_UR; + set_blitting_type(vc, info, p); + } + +} + +static void fbcon_deinit(struct vc_data *vc) +{ + struct display *p = &fb_display[vc->vc_num]; + + if (info_idx != -1) + return; + fbcon_free_font(p); +} + +/* ====================================================================== */ + +/* fbcon_XXX routines - interface used by the world + * + * This system is now divided into two levels because of complications + * caused by hardware scrolling. Top level functions: + * + * fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins() + * + * handles y values in range [0, scr_height-1] that correspond to real + * screen positions. y_wrap shift means that first line of bitmap may be + * anywhere on this display. These functions convert lineoffsets to + * bitmap offsets and deal with the wrap-around case by splitting blits. + * + * fbcon_bmove_physical_8() -- These functions fast implementations + * fbcon_clear_physical_8() -- of original fbcon_XXX fns. + * fbcon_putc_physical_8() -- (font width != 8) may be added later + * + * WARNING: + * + * At the moment fbcon_putc() cannot blit across vertical wrap boundary + * Implies should only really hardware scroll in rows. Only reason for + * restriction is simplicity & efficiency at the moment. + */ + +static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, + int width) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + + struct display *p = &fb_display[vc->vc_num]; + u_int y_break; + + if (fbcon_is_inactive(vc, info)) + return; + + if (!height || !width) + return; + + /* Split blits that cross physical y_wrap boundary */ + + y_break = p->vrows - p->yscroll; + if (sy < y_break && sy + height - 1 >= y_break) { + u_int b = y_break - sy; + ops->clear(vc, info, real_y(p, sy), sx, b, width); + ops->clear(vc, info, real_y(p, sy + b), sx, height - b, + width); + } else + ops->clear(vc, info, real_y(p, sy), sx, height, width); +} + +static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, + int count, int ypos, int xpos) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + + if (!fbcon_is_inactive(vc, info)) + ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, + get_color(vc, info, scr_readw(s), 1), + get_color(vc, info, scr_readw(s), 0)); +} + +static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) +{ + unsigned short chr; + + scr_writew(c, &chr); + fbcon_putcs(vc, &chr, 1, ypos, xpos); +} + +static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + + if (!fbcon_is_inactive(vc, info)) + ops->clear_margins(vc, info, bottom_only); +} + +static void fbcon_cursor(struct vc_data *vc, int mode) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + int y; + int c = scr_readw((u16 *) vc->vc_pos); + + if (fbcon_is_inactive(vc, info)) + return; + + ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; + if (mode & CM_SOFTBACK) { + mode &= ~CM_SOFTBACK; + y = softback_lines; + } else { + if (softback_lines) + fbcon_set_origin(vc); + y = 0; + } + + ops->cursor(vc, info, p, mode, y, get_color(vc, info, c, 1), + get_color(vc, info, c, 0)); + vbl_cursor_cnt = CURSOR_DRAW_DELAY; +} + +static int scrollback_phys_max = 0; +static int scrollback_max = 0; +static int scrollback_current = 0; + +/* + * If no vc is existent yet, just set struct display + */ +static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var, + int unit) +{ + struct display *p = &fb_display[unit]; + struct display *t = &fb_display[fg_console]; + + if (var_to_display(p, var, info)) + return; + + p->fontdata = t->fontdata; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; +} + +static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, + struct vc_data *vc) +{ + struct display *p = &fb_display[vc->vc_num], *t; + struct vc_data **default_mode = vc->vc_display_fg; + struct vc_data *svc = *default_mode; + struct fbcon_ops *ops = info->fbcon_par; + int rows, cols, charcnt = 256; + + if (var_to_display(p, var, info)) + return; + t = &fb_display[svc->vc_num]; + if (!vc->vc_font.data) { + vc->vc_font.data = (void *)(p->fontdata = t->fontdata); + vc->vc_font.width = (*default_mode)->vc_font.width; + vc->vc_font.height = (*default_mode)->vc_font.height; + p->userfont = t->userfont; + if (p->userfont) + REFCOUNT(p->fontdata)++; + } + if (p->userfont) + charcnt = FNTCHARCNT(p->fontdata); + + var->activate = FB_ACTIVATE_NOW; + info->var.activate = var->activate; + var->yoffset = info->var.yoffset; + var->xoffset = info->var.xoffset; + fb_set_var(info, var); + ops->var = info->var; + vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + if (charcnt == 256) { + vc->vc_hi_font_mask = 0; + } else { + vc->vc_hi_font_mask = 0x100; + if (vc->vc_can_do_color) + vc->vc_complement_mask <<= 1; + } + + if (!*svc->vc_uni_pagedir_loc) + con_set_default_unimap(svc); + if (!*vc->vc_uni_pagedir_loc) + con_copy_unimap(vc, svc); + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; + vc_resize(vc, cols, rows); + + if (CON_IS_VISIBLE(vc)) { + update_screen(vc); + if (softback_buf) + fbcon_update_softback(vc); + } +} + +static __inline__ void ywrap_up(struct vc_data *vc, int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + + p->yscroll += count; + if (p->yscroll >= p->vrows) /* Deal with wrap */ + p->yscroll -= p->vrows; + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode |= FB_VMODE_YWRAP; + ops->update_start(info); + scrollback_max += count; + if (scrollback_max > scrollback_phys_max) + scrollback_max = scrollback_phys_max; + scrollback_current = 0; +} + +static __inline__ void ywrap_down(struct vc_data *vc, int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + + p->yscroll -= count; + if (p->yscroll < 0) /* Deal with wrap */ + p->yscroll += p->vrows; + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode |= FB_VMODE_YWRAP; + ops->update_start(info); + scrollback_max -= count; + if (scrollback_max < 0) + scrollback_max = 0; + scrollback_current = 0; +} + +static __inline__ void ypan_up(struct vc_data *vc, int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + + p->yscroll += count; + if (p->yscroll > p->vrows - vc->vc_rows) { + ops->bmove(vc, info, p->vrows - vc->vc_rows, + 0, 0, 0, vc->vc_rows, vc->vc_cols); + p->yscroll -= p->vrows - vc->vc_rows; + } + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); + fbcon_clear_margins(vc, 1); + scrollback_max += count; + if (scrollback_max > scrollback_phys_max) + scrollback_max = scrollback_phys_max; + scrollback_current = 0; +} + +static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + int redraw = 0; + + p->yscroll += count; + if (p->yscroll > p->vrows - vc->vc_rows) { + p->yscroll -= p->vrows - vc->vc_rows; + redraw = 1; + } + + if (redraw) + fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); + fbcon_clear_margins(vc, 1); + scrollback_max += count; + if (scrollback_max > scrollback_phys_max) + scrollback_max = scrollback_phys_max; + scrollback_current = 0; +} + +static __inline__ void ypan_down(struct vc_data *vc, int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + + p->yscroll -= count; + if (p->yscroll < 0) { + ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows, + 0, vc->vc_rows, vc->vc_cols); + p->yscroll += p->vrows - vc->vc_rows; + } + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); + fbcon_clear_margins(vc, 1); + scrollback_max -= count; + if (scrollback_max < 0) + scrollback_max = 0; + scrollback_current = 0; +} + +static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + int redraw = 0; + + p->yscroll -= count; + if (p->yscroll < 0) { + p->yscroll += p->vrows - vc->vc_rows; + redraw = 1; + } + + if (redraw) + fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); + + ops->var.xoffset = 0; + ops->var.yoffset = p->yscroll * vc->vc_font.height; + ops->var.vmode &= ~FB_VMODE_YWRAP; + ops->update_start(info); + fbcon_clear_margins(vc, 1); + scrollback_max -= count; + if (scrollback_max < 0) + scrollback_max = 0; + scrollback_current = 0; +} + +static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, + long delta) +{ + int count = vc->vc_rows; + unsigned short *d, *s; + unsigned long n; + int line = 0; + + d = (u16 *) softback_curr; + if (d == (u16 *) softback_in) + d = (u16 *) vc->vc_origin; + n = softback_curr + delta * vc->vc_size_row; + softback_lines -= delta; + if (delta < 0) { + if (softback_curr < softback_top && n < softback_buf) { + n += softback_end - softback_buf; + if (n < softback_top) { + softback_lines -= + (softback_top - n) / vc->vc_size_row; + n = softback_top; + } + } else if (softback_curr >= softback_top + && n < softback_top) { + softback_lines -= + (softback_top - n) / vc->vc_size_row; + n = softback_top; + } + } else { + if (softback_curr > softback_in && n >= softback_end) { + n += softback_buf - softback_end; + if (n > softback_in) { + n = softback_in; + softback_lines = 0; + } + } else if (softback_curr <= softback_in && n > softback_in) { + n = softback_in; + softback_lines = 0; + } + } + if (n == softback_curr) + return; + softback_curr = n; + s = (u16 *) softback_curr; + if (s == (u16 *) softback_in) + s = (u16 *) vc->vc_origin; + while (count--) { + unsigned short *start; + unsigned short *le; + unsigned short c; + int x = 0; + unsigned short attr = 1; + + start = s; + le = advance_row(s, 1); + do { + c = scr_readw(s); + if (attr != (c & 0xff00)) { + attr = c & 0xff00; + if (s > start) { + fbcon_putcs(vc, start, s - start, + line, x); + x += s - start; + start = s; + } + } + if (c == scr_readw(d)) { + if (s > start) { + fbcon_putcs(vc, start, s - start, + line, x); + x += s - start + 1; + start = s + 1; + } else { + x++; + start++; + } + } + s++; + d++; + } while (s < le); + if (s > start) + fbcon_putcs(vc, start, s - start, line, x); + line++; + if (d == (u16 *) softback_end) + d = (u16 *) softback_buf; + if (d == (u16 *) softback_in) + d = (u16 *) vc->vc_origin; + if (s == (u16 *) softback_end) + s = (u16 *) softback_buf; + if (s == (u16 *) softback_in) + s = (u16 *) vc->vc_origin; + } +} + +static void fbcon_redraw_move(struct vc_data *vc, struct display *p, + int line, int count, int dy) +{ + unsigned short *s = (unsigned short *) + (vc->vc_origin + vc->vc_size_row * line); + + while (count--) { + unsigned short *start = s; + unsigned short *le = advance_row(s, 1); + unsigned short c; + int x = 0; + unsigned short attr = 1; + + do { + c = scr_readw(s); + if (attr != (c & 0xff00)) { + attr = c & 0xff00; + if (s > start) { + fbcon_putcs(vc, start, s - start, + dy, x); + x += s - start; + start = s; + } + } + console_conditional_schedule(); + s++; + } while (s < le); + if (s > start) + fbcon_putcs(vc, start, s - start, dy, x); + console_conditional_schedule(); + dy++; + } +} + +static void fbcon_redraw(struct vc_data *vc, struct display *p, + int line, int count, int offset) +{ + unsigned short *d = (unsigned short *) + (vc->vc_origin + vc->vc_size_row * line); + unsigned short *s = d + offset; + + while (count--) { + unsigned short *start = s; + unsigned short *le = advance_row(s, 1); + unsigned short c; + int x = 0; + unsigned short attr = 1; + + do { + c = scr_readw(s); + if (attr != (c & 0xff00)) { + attr = c & 0xff00; + if (s > start) { + fbcon_putcs(vc, start, s - start, + line, x); + x += s - start; + start = s; + } + } + if (c == scr_readw(d)) { + if (s > start) { + fbcon_putcs(vc, start, s - start, + line, x); + x += s - start + 1; + start = s + 1; + } else { + x++; + start++; + } + } + scr_writew(c, d); + console_conditional_schedule(); + s++; + d++; + } while (s < le); + if (s > start) + fbcon_putcs(vc, start, s - start, line, x); + console_conditional_schedule(); + if (offset > 0) + line++; + else { + line--; + /* NOTE: We subtract two lines from these pointers */ + s -= vc->vc_size_row; + d -= vc->vc_size_row; + } + } +} + +static inline void fbcon_softback_note(struct vc_data *vc, int t, + int count) +{ + unsigned short *p; + + if (vc->vc_num != fg_console) + return; + p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row); + + while (count) { + scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row); + count--; + p = advance_row(p, 1); + softback_in += vc->vc_size_row; + if (softback_in == softback_end) + softback_in = softback_buf; + if (softback_in == softback_top) { + softback_top += vc->vc_size_row; + if (softback_top == softback_end) + softback_top = softback_buf; + } + } + softback_curr = softback_in; +} + +static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, + int count) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; + + if (fbcon_is_inactive(vc, info)) + return -EINVAL; + + fbcon_cursor(vc, CM_ERASE); + + /* + * ++Geert: Only use ywrap/ypan if the console is in text mode + * ++Andrew: Only use ypan on hardware text mode when scrolling the + * whole screen (prevents flicker). + */ + + switch (dir) { + case SM_UP: + if (count > vc->vc_rows) /* Maximum realistic size */ + count = vc->vc_rows; + if (softback_top) + fbcon_softback_note(vc, t, count); + if (logo_shown >= 0) + goto redraw_up; + switch (p->scrollmode) { + case SCROLL_MOVE: + ops->bmove(vc, info, t + count, 0, t, 0, + b - t - count, vc->vc_cols); + ops->clear(vc, info, b - count, 0, count, + vc->vc_cols); + break; + + case SCROLL_WRAP_MOVE: + if (b - t - count > 3 * vc->vc_rows >> 2) { + if (t > 0) + fbcon_bmove(vc, 0, 0, count, 0, t, + vc->vc_cols); + ywrap_up(vc, count); + if (vc->vc_rows - b > 0) + fbcon_bmove(vc, b - count, 0, b, 0, + vc->vc_rows - b, + vc->vc_cols); + } else if (info->flags & FBINFO_READS_FAST) + fbcon_bmove(vc, t + count, 0, t, 0, + b - t - count, vc->vc_cols); + else + goto redraw_up; + fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_REDRAW: + if ((p->yscroll + count <= + 2 * (p->vrows - vc->vc_rows)) + && ((!scroll_partial && (b - t == vc->vc_rows)) + || (scroll_partial + && (b - t - count > + 3 * vc->vc_rows >> 2)))) { + if (t > 0) + fbcon_redraw_move(vc, p, 0, t, count); + ypan_up_redraw(vc, t, count); + if (vc->vc_rows - b > 0) + fbcon_redraw_move(vc, p, b - count, + vc->vc_rows - b, b); + } else + fbcon_redraw_move(vc, p, t + count, b - t - count, t); + fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_MOVE: + if ((p->yscroll + count <= + 2 * (p->vrows - vc->vc_rows)) + && ((!scroll_partial && (b - t == vc->vc_rows)) + || (scroll_partial + && (b - t - count > + 3 * vc->vc_rows >> 2)))) { + if (t > 0) + fbcon_bmove(vc, 0, 0, count, 0, t, + vc->vc_cols); + ypan_up(vc, count); + if (vc->vc_rows - b > 0) + fbcon_bmove(vc, b - count, 0, b, 0, + vc->vc_rows - b, + vc->vc_cols); + } else if (info->flags & FBINFO_READS_FAST) + fbcon_bmove(vc, t + count, 0, t, 0, + b - t - count, vc->vc_cols); + else + goto redraw_up; + fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + break; + + case SCROLL_REDRAW: + redraw_up: + fbcon_redraw(vc, p, t, b - t - count, + count * vc->vc_cols); + fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + (b - count)), + vc->vc_video_erase_char, + vc->vc_size_row * count); + return 1; + } + break; + + case SM_DOWN: + if (count > vc->vc_rows) /* Maximum realistic size */ + count = vc->vc_rows; + if (logo_shown >= 0) + goto redraw_down; + switch (p->scrollmode) { + case SCROLL_MOVE: + ops->bmove(vc, info, t, 0, t + count, 0, + b - t - count, vc->vc_cols); + ops->clear(vc, info, t, 0, count, vc->vc_cols); + break; + + case SCROLL_WRAP_MOVE: + if (b - t - count > 3 * vc->vc_rows >> 2) { + if (vc->vc_rows - b > 0) + fbcon_bmove(vc, b, 0, b - count, 0, + vc->vc_rows - b, + vc->vc_cols); + ywrap_down(vc, count); + if (t > 0) + fbcon_bmove(vc, count, 0, 0, 0, t, + vc->vc_cols); + } else if (info->flags & FBINFO_READS_FAST) + fbcon_bmove(vc, t, 0, t + count, 0, + b - t - count, vc->vc_cols); + else + goto redraw_down; + fbcon_clear(vc, t, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_MOVE: + if ((count - p->yscroll <= p->vrows - vc->vc_rows) + && ((!scroll_partial && (b - t == vc->vc_rows)) + || (scroll_partial + && (b - t - count > + 3 * vc->vc_rows >> 2)))) { + if (vc->vc_rows - b > 0) + fbcon_bmove(vc, b, 0, b - count, 0, + vc->vc_rows - b, + vc->vc_cols); + ypan_down(vc, count); + if (t > 0) + fbcon_bmove(vc, count, 0, 0, 0, t, + vc->vc_cols); + } else if (info->flags & FBINFO_READS_FAST) + fbcon_bmove(vc, t, 0, t + count, 0, + b - t - count, vc->vc_cols); + else + goto redraw_down; + fbcon_clear(vc, t, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_REDRAW: + if ((count - p->yscroll <= p->vrows - vc->vc_rows) + && ((!scroll_partial && (b - t == vc->vc_rows)) + || (scroll_partial + && (b - t - count > + 3 * vc->vc_rows >> 2)))) { + if (vc->vc_rows - b > 0) + fbcon_redraw_move(vc, p, b, vc->vc_rows - b, + b - count); + ypan_down_redraw(vc, t, count); + if (t > 0) + fbcon_redraw_move(vc, p, count, t, 0); + } else + fbcon_redraw_move(vc, p, t, b - t - count, t + count); + fbcon_clear(vc, t, 0, count, vc->vc_cols); + break; + + case SCROLL_REDRAW: + redraw_down: + fbcon_redraw(vc, p, b - 1, b - t - count, + -count * vc->vc_cols); + fbcon_clear(vc, t, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + t), + vc->vc_video_erase_char, + vc->vc_size_row * count); + return 1; + } + } + return 0; +} + + +static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, + int height, int width) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct display *p = &fb_display[vc->vc_num]; + + if (fbcon_is_inactive(vc, info)) + return; + + if (!width || !height) + return; + + /* Split blits that cross physical y_wrap case. + * Pathological case involves 4 blits, better to use recursive + * code rather than unrolled case + * + * Recursive invocations don't need to erase the cursor over and + * over again, so we use fbcon_bmove_rec() + */ + fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width, + p->vrows - p->yscroll); +} + +static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, + int dy, int dx, int height, int width, u_int y_break) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + u_int b; + + if (sy < y_break && sy + height > y_break) { + b = y_break - sy; + if (dy < sy) { /* Avoid trashing self */ + fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width, + y_break); + fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx, + height - b, width, y_break); + } else { + fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx, + height - b, width, y_break); + fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width, + y_break); + } + return; + } + + if (dy < y_break && dy + height > y_break) { + b = y_break - dy; + if (dy < sy) { /* Avoid trashing self */ + fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width, + y_break); + fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx, + height - b, width, y_break); + } else { + fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx, + height - b, width, y_break); + fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width, + y_break); + } + return; + } + ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx, + height, width); +} + +static __inline__ void updatescrollmode(struct display *p, + struct fb_info *info, + struct vc_data *vc) +{ + struct fbcon_ops *ops = info->fbcon_par; + int fh = vc->vc_font.height; + int cap = info->flags; + u16 t = 0; + int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep, + info->fix.xpanstep); + int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t); + int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual, + info->var.xres_virtual); + int good_pan = (cap & FBINFO_HWACCEL_YPAN) && + divides(ypan, vc->vc_font.height) && vyres > yres; + int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) && + divides(ywrap, vc->vc_font.height) && + divides(vc->vc_font.height, vyres); + int reading_fast = cap & FBINFO_READS_FAST; + int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && + !(cap & FBINFO_HWACCEL_DISABLED); + int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && + !(cap & FBINFO_HWACCEL_DISABLED); + + p->vrows = vyres/fh; + if (yres > (fh * (vc->vc_rows + 1))) + p->vrows -= (yres - (fh * vc->vc_rows)) / fh; + if ((yres % fh) && (vyres % fh < yres % fh)) + p->vrows--; + + if (good_wrap || good_pan) { + if (reading_fast || fast_copyarea) + p->scrollmode = good_wrap ? + SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; + else + p->scrollmode = good_wrap ? SCROLL_REDRAW : + SCROLL_PAN_REDRAW; + } else { + if (reading_fast || (fast_copyarea && !fast_imageblit)) + p->scrollmode = SCROLL_MOVE; + else + p->scrollmode = SCROLL_REDRAW; + } +} + +static int fbcon_resize(struct vc_data *vc, unsigned int width, + unsigned int height) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + struct fb_var_screeninfo var = info->var; + int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh; + + virt_w = FBCON_SWAP(ops->rotate, width, height); + virt_h = FBCON_SWAP(ops->rotate, height, width); + virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width, + vc->vc_font.height); + virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height, + vc->vc_font.width); + var.xres = virt_w * virt_fw; + var.yres = virt_h * virt_fh; + x_diff = info->var.xres - var.xres; + y_diff = info->var.yres - var.yres; + if (x_diff < 0 || x_diff > virt_fw || + y_diff < 0 || y_diff > virt_fh) { + struct fb_videomode *mode; + + DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); + mode = fb_find_best_mode(&var, &info->modelist); + if (mode == NULL) + return -EINVAL; + display_to_var(&var, p); + fb_videomode_to_var(&var, mode); + + if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh) + return -EINVAL; + + DPRINTK("resize now %ix%i\n", var.xres, var.yres); + if (CON_IS_VISIBLE(vc)) { + var.activate = FB_ACTIVATE_NOW | + FB_ACTIVATE_FORCE; + fb_set_var(info, &var); + } + var_to_display(p, &info->var, info); + ops->var = info->var; + } + updatescrollmode(p, info, vc); + return 0; +} + +static int fbcon_switch(struct vc_data *vc) +{ + struct fb_info *info, *old_info = NULL; + struct fbcon_ops *ops; + struct display *p = &fb_display[vc->vc_num]; + struct fb_var_screeninfo var; + int i, prev_console, charcnt = 256; + + info = registered_fb[con2fb_map[vc->vc_num]]; + ops = info->fbcon_par; + + if (softback_top) { + if (softback_lines) + fbcon_set_origin(vc); + softback_top = softback_curr = softback_in = softback_buf; + softback_lines = 0; + fbcon_update_softback(vc); + } + + if (logo_shown >= 0) { + struct vc_data *conp2 = vc_cons[logo_shown].d; + + if (conp2->vc_top == logo_lines + && conp2->vc_bottom == conp2->vc_rows) + conp2->vc_top = 0; + logo_shown = FBCON_LOGO_CANSHOW; + } + + prev_console = ops->currcon; + if (prev_console != -1) + old_info = registered_fb[con2fb_map[prev_console]]; + /* + * FIXME: If we have multiple fbdev's loaded, we need to + * update all info->currcon. Perhaps, we can place this + * in a centralized structure, but this might break some + * drivers. + * + * info->currcon = vc->vc_num; + */ + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { + struct fbcon_ops *o = registered_fb[i]->fbcon_par; + + o->currcon = vc->vc_num; + } + } + memset(&var, 0, sizeof(struct fb_var_screeninfo)); + display_to_var(&var, p); + var.activate = FB_ACTIVATE_NOW; + + /* + * make sure we don't unnecessarily trip the memcmp() + * in fb_set_var() + */ + info->var.activate = var.activate; + var.yoffset = info->var.yoffset; + var.xoffset = info->var.xoffset; + var.vmode = info->var.vmode; + fb_set_var(info, &var); + ops->var = info->var; + + if (old_info != NULL && (old_info != info || + info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { + if (info->fbops->fb_set_par) + info->fbops->fb_set_par(info); + fbcon_del_cursor_timer(old_info); + fbcon_add_cursor_timer(info); + } + + set_blitting_type(vc, info, p); + ops->cursor_reset = 1; + + if (ops->rotate_font && ops->rotate_font(info, vc, p)) { + ops->rotate = FB_ROTATE_UR; + set_blitting_type(vc, info, p); + } + + vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); + vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + + if (p->userfont) + charcnt = FNTCHARCNT(vc->vc_font.data); + + if (charcnt > 256) + vc->vc_complement_mask <<= 1; + + updatescrollmode(p, info, vc); + + switch (p->scrollmode) { + case SCROLL_WRAP_MOVE: + scrollback_phys_max = p->vrows - vc->vc_rows; + break; + case SCROLL_PAN_MOVE: + case SCROLL_PAN_REDRAW: + scrollback_phys_max = p->vrows - 2 * vc->vc_rows; + if (scrollback_phys_max < 0) + scrollback_phys_max = 0; + break; + default: + scrollback_phys_max = 0; + break; + } + + scrollback_max = 0; + scrollback_current = 0; + + if (!fbcon_is_inactive(vc, info)) { + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); + } + + fbcon_set_palette(vc, color_table); + fbcon_clear_margins(vc, 0); + + if (logo_shown == FBCON_LOGO_DRAW) { + + logo_shown = fg_console; + /* This is protected above by initmem_freed */ + fb_show_logo(info, ops->rotate); + update_region(vc, + vc->vc_origin + vc->vc_size_row * vc->vc_top, + vc->vc_size_row * (vc->vc_bottom - + vc->vc_top) / 2); + return 0; + } + return 1; +} + +static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, + int blank) +{ + if (blank) { + unsigned short charmask = vc->vc_hi_font_mask ? + 0x1ff : 0xff; + unsigned short oldc; + + oldc = vc->vc_video_erase_char; + vc->vc_video_erase_char &= charmask; + fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols); + vc->vc_video_erase_char = oldc; + } +} + +static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + + if (mode_switch) { + struct fb_var_screeninfo var = info->var; + + ops->graphics = 1; + + if (!blank) { + if (info->fbops->fb_save_state) + info->fbops->fb_save_state(info); + var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; + fb_set_var(info, &var); + ops->graphics = 0; + ops->var = info->var; + } else if (info->fbops->fb_restore_state) + info->fbops->fb_restore_state(info); + } + + if (!fbcon_is_inactive(vc, info)) { + if (ops->blank_state != blank) { + ops->blank_state = blank; + fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); + ops->cursor_flash = (!blank); + + if (fb_blank(info, blank)) + fbcon_generic_blank(vc, info, blank); + } + + if (!blank) + update_screen(vc); + } + + if (!blank) + fbcon_add_cursor_timer(info); + else + fbcon_del_cursor_timer(info); + + return 0; +} + +static void fbcon_free_font(struct display *p) +{ + if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); + p->fontdata = NULL; + p->userfont = 0; +} + +static int fbcon_get_font(struct vc_data *vc, struct console_font *font) +{ + u8 *fontdata = vc->vc_font.data; + u8 *data = font->data; + int i, j; + + font->width = vc->vc_font.width; + font->height = vc->vc_font.height; + font->charcount = vc->vc_hi_font_mask ? 512 : 256; + if (!font->data) + return 0; + + if (font->width <= 8) { + j = vc->vc_font.height; + for (i = 0; i < font->charcount; i++) { + memcpy(data, fontdata, j); + memset(data + j, 0, 32 - j); + data += 32; + fontdata += j; + } + } else if (font->width <= 16) { + j = vc->vc_font.height * 2; + for (i = 0; i < font->charcount; i++) { + memcpy(data, fontdata, j); + memset(data + j, 0, 64 - j); + data += 64; + fontdata += j; + } + } else if (font->width <= 24) { + for (i = 0; i < font->charcount; i++) { + for (j = 0; j < vc->vc_font.height; j++) { + *data++ = fontdata[0]; + *data++ = fontdata[1]; + *data++ = fontdata[2]; + fontdata += sizeof(u32); + } + memset(data, 0, 3 * (32 - j)); + data += 3 * (32 - j); + } + } else { + j = vc->vc_font.height * 4; + for (i = 0; i < font->charcount; i++) { + memcpy(data, fontdata, j); + memset(data + j, 0, 128 - j); + data += 128; + fontdata += j; + } + } + return 0; +} + +static int fbcon_do_set_font(struct vc_data *vc, int w, int h, + const u8 * data, int userfont) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[vc->vc_num]; + int resize; + int cnt; + char *old_data = NULL; + + if (CON_IS_VISIBLE(vc) && softback_lines) + fbcon_set_origin(vc); + + resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); + if (p->userfont) + old_data = vc->vc_font.data; + if (userfont) + cnt = FNTCHARCNT(data); + else + cnt = 256; + vc->vc_font.data = (void *)(p->fontdata = data); + if ((p->userfont = userfont)) + REFCOUNT(data)++; + vc->vc_font.width = w; + vc->vc_font.height = h; + if (vc->vc_hi_font_mask && cnt == 256) { + vc->vc_hi_font_mask = 0; + if (vc->vc_can_do_color) { + vc->vc_complement_mask >>= 1; + vc->vc_s_complement_mask >>= 1; + } + + /* ++Edmund: reorder the attribute bits */ + if (vc->vc_can_do_color) { + unsigned short *cp = + (unsigned short *) vc->vc_origin; + int count = vc->vc_screenbuf_size / 2; + unsigned short c; + for (; count > 0; count--, cp++) { + c = scr_readw(cp); + scr_writew(((c & 0xfe00) >> 1) | + (c & 0xff), cp); + } + c = vc->vc_video_erase_char; + vc->vc_video_erase_char = + ((c & 0xfe00) >> 1) | (c & 0xff); + vc->vc_attr >>= 1; + } + } else if (!vc->vc_hi_font_mask && cnt == 512) { + vc->vc_hi_font_mask = 0x100; + if (vc->vc_can_do_color) { + vc->vc_complement_mask <<= 1; + vc->vc_s_complement_mask <<= 1; + } + + /* ++Edmund: reorder the attribute bits */ + { + unsigned short *cp = + (unsigned short *) vc->vc_origin; + int count = vc->vc_screenbuf_size / 2; + unsigned short c; + for (; count > 0; count--, cp++) { + unsigned short newc; + c = scr_readw(cp); + if (vc->vc_can_do_color) + newc = + ((c & 0xff00) << 1) | (c & + 0xff); + else + newc = c & ~0x100; + scr_writew(newc, cp); + } + c = vc->vc_video_erase_char; + if (vc->vc_can_do_color) { + vc->vc_video_erase_char = + ((c & 0xff00) << 1) | (c & 0xff); + vc->vc_attr <<= 1; + } else + vc->vc_video_erase_char = c & ~0x100; + } + + } + + if (resize) { + int cols, rows; + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= w; + rows /= h; + vc_resize(vc, cols, rows); + if (CON_IS_VISIBLE(vc) && softback_buf) + fbcon_update_softback(vc); + } else if (CON_IS_VISIBLE(vc) + && vc->vc_mode == KD_TEXT) { + fbcon_clear_margins(vc, 0); + update_screen(vc); + } + + if (old_data && (--REFCOUNT(old_data) == 0)) + kfree(old_data - FONT_EXTRA_WORDS * sizeof(int)); + return 0; +} + +static int fbcon_copy_font(struct vc_data *vc, int con) +{ + struct display *od = &fb_display[con]; + struct console_font *f = &vc->vc_font; + + if (od->fontdata == f->data) + return 0; /* already the same font... */ + return fbcon_do_set_font(vc, f->width, f->height, od->fontdata, od->userfont); +} + +/* + * User asked to set font; we are guaranteed that + * a) width and height are in range 1..32 + * b) charcount does not exceed 512 + * but lets not assume that, since someone might someday want to use larger + * fonts. And charcount of 512 is small for unicode support. + * + * However, user space gives the font in 32 rows , regardless of + * actual font height. So a new API is needed if support for larger fonts + * is ever implemented. + */ + +static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags) +{ + unsigned charcount = font->charcount; + int w = font->width; + int h = font->height; + int size; + int i, csum; + u8 *new_data, *data = font->data; + int pitch = (font->width+7) >> 3; + + /* Is there a reason why fbconsole couldn't handle any charcount >256? + * If not this check should be changed to charcount < 256 */ + if (charcount != 256 && charcount != 512) + return -EINVAL; + + size = h * pitch * charcount; + + new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER); + + if (!new_data) + return -ENOMEM; + + new_data += FONT_EXTRA_WORDS * sizeof(int); + FNTSIZE(new_data) = size; + FNTCHARCNT(new_data) = charcount; + REFCOUNT(new_data) = 0; /* usage counter */ + for (i=0; i< charcount; i++) { + memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch); + } + + /* Since linux has a nice crc32 function use it for counting font + * checksums. */ + csum = crc32(0, new_data, size); + + FNTSUM(new_data) = csum; + /* Check if the same font is on some other console already */ + for (i = 0; i < MAX_NR_CONSOLES; i++) { + struct vc_data *tmp = vc_cons[i].d; + + if (fb_display[i].userfont && + fb_display[i].fontdata && + FNTSUM(fb_display[i].fontdata) == csum && + FNTSIZE(fb_display[i].fontdata) == size && + tmp->vc_font.width == w && + !memcmp(fb_display[i].fontdata, new_data, size)) { + kfree(new_data - FONT_EXTRA_WORDS * sizeof(int)); + new_data = (u8 *)fb_display[i].fontdata; + break; + } + } + return fbcon_do_set_font(vc, font->width, font->height, new_data, 1); +} + +static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + const struct font_desc *f; + + if (!name) + f = get_default_font(info->var.xres, info->var.yres); + else if (!(f = find_font(name))) + return -ENOENT; + + font->width = f->width; + font->height = f->height; + return fbcon_do_set_font(vc, f->width, f->height, f->data, 0); +} + +static u16 palette_red[16]; +static u16 palette_green[16]; +static u16 palette_blue[16]; + +static struct fb_cmap palette_cmap = { + 0, 16, palette_red, palette_green, palette_blue, NULL +}; + +static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) +{ + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + int i, j, k, depth; + u8 val; + + if (fbcon_is_inactive(vc, info)) + return -EINVAL; + + if (!CON_IS_VISIBLE(vc)) + return 0; + + depth = fb_get_color_depth(&info->var, &info->fix); + if (depth > 3) { + for (i = j = 0; i < 16; i++) { + k = table[i]; + val = vc->vc_palette[j++]; + palette_red[k] = (val << 8) | val; + val = vc->vc_palette[j++]; + palette_green[k] = (val << 8) | val; + val = vc->vc_palette[j++]; + palette_blue[k] = (val << 8) | val; + } + palette_cmap.len = 16; + palette_cmap.start = 0; + /* + * If framebuffer is capable of less than 16 colors, + * use default palette of fbcon. + */ + } else + fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); + + return fb_set_cmap(&palette_cmap, info); +} + +static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) +{ + unsigned long p; + int line; + + if (vc->vc_num != fg_console || !softback_lines) + return (u16 *) (vc->vc_origin + offset); + line = offset / vc->vc_size_row; + if (line >= softback_lines) + return (u16 *) (vc->vc_origin + offset - + softback_lines * vc->vc_size_row); + p = softback_curr + offset; + if (p >= softback_end) + p += softback_buf - softback_end; + return (u16 *) p; +} + +static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos, + int *px, int *py) +{ + unsigned long ret; + int x, y; + + if (pos >= vc->vc_origin && pos < vc->vc_scr_end) { + unsigned long offset = (pos - vc->vc_origin) / 2; + + x = offset % vc->vc_cols; + y = offset / vc->vc_cols; + if (vc->vc_num == fg_console) + y += softback_lines; + ret = pos + (vc->vc_cols - x) * 2; + } else if (vc->vc_num == fg_console && softback_lines) { + unsigned long offset = pos - softback_curr; + + if (pos < softback_curr) + offset += softback_end - softback_buf; + offset /= 2; + x = offset % vc->vc_cols; + y = offset / vc->vc_cols; + ret = pos + (vc->vc_cols - x) * 2; + if (ret == softback_end) + ret = softback_buf; + if (ret == softback_in) + ret = vc->vc_origin; + } else { + /* Should not happen */ + x = y = 0; + ret = vc->vc_origin; + } + if (px) + *px = x; + if (py) + *py = y; + return ret; +} + +/* As we might be inside of softback, we may work with non-contiguous buffer, + that's why we have to use a separate routine. */ +static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt) +{ + while (cnt--) { + u16 a = scr_readw(p); + if (!vc->vc_can_do_color) + a ^= 0x0800; + else if (vc->vc_hi_font_mask == 0x100) + a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | + (((a) & 0x0e00) << 4); + else + a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | + (((a) & 0x0700) << 4); + scr_writew(a, p++); + if (p == (u16 *) softback_end) + p = (u16 *) softback_buf; + if (p == (u16 *) softback_in) + p = (u16 *) vc->vc_origin; + } +} + +static int fbcon_scrolldelta(struct vc_data *vc, int lines) +{ + struct fb_info *info = registered_fb[con2fb_map[fg_console]]; + struct fbcon_ops *ops = info->fbcon_par; + struct display *p = &fb_display[fg_console]; + int offset, limit, scrollback_old; + + if (softback_top) { + if (vc->vc_num != fg_console) + return 0; + if (vc->vc_mode != KD_TEXT || !lines) + return 0; + if (logo_shown >= 0) { + struct vc_data *conp2 = vc_cons[logo_shown].d; + + if (conp2->vc_top == logo_lines + && conp2->vc_bottom == conp2->vc_rows) + conp2->vc_top = 0; + if (logo_shown == vc->vc_num) { + unsigned long p, q; + int i; + + p = softback_in; + q = vc->vc_origin + + logo_lines * vc->vc_size_row; + for (i = 0; i < logo_lines; i++) { + if (p == softback_top) + break; + if (p == softback_buf) + p = softback_end; + p -= vc->vc_size_row; + q -= vc->vc_size_row; + scr_memcpyw((u16 *) q, (u16 *) p, + vc->vc_size_row); + } + softback_in = p; + update_region(vc, vc->vc_origin, + logo_lines * vc->vc_cols); + } + logo_shown = FBCON_LOGO_CANSHOW; + } + fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); + fbcon_redraw_softback(vc, p, lines); + fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); + return 0; + } + + if (!scrollback_phys_max) + return -ENOSYS; + + scrollback_old = scrollback_current; + scrollback_current -= lines; + if (scrollback_current < 0) + scrollback_current = 0; + else if (scrollback_current > scrollback_max) + scrollback_current = scrollback_max; + if (scrollback_current == scrollback_old) + return 0; + + if (fbcon_is_inactive(vc, info)) + return 0; + + fbcon_cursor(vc, CM_ERASE); + + offset = p->yscroll - scrollback_current; + limit = p->vrows; + switch (p->scrollmode) { + case SCROLL_WRAP_MOVE: + info->var.vmode |= FB_VMODE_YWRAP; + break; + case SCROLL_PAN_MOVE: + case SCROLL_PAN_REDRAW: + limit -= vc->vc_rows; + info->var.vmode &= ~FB_VMODE_YWRAP; + break; + } + if (offset < 0) + offset += limit; + else if (offset >= limit) + offset -= limit; + + ops->var.xoffset = 0; + ops->var.yoffset = offset * vc->vc_font.height; + ops->update_start(info); + + if (!scrollback_current) + fbcon_cursor(vc, CM_DRAW); + return 0; +} + +static int fbcon_set_origin(struct vc_data *vc) +{ + if (softback_lines) + fbcon_scrolldelta(vc, softback_lines); + return 0; +} + +static void fbcon_suspended(struct fb_info *info) +{ + struct vc_data *vc = NULL; + struct fbcon_ops *ops = info->fbcon_par; + + if (!ops || ops->currcon < 0) + return; + vc = vc_cons[ops->currcon].d; + + /* Clear cursor, restore saved data */ + fbcon_cursor(vc, CM_ERASE); +} + +static void fbcon_resumed(struct fb_info *info) +{ + struct vc_data *vc; + struct fbcon_ops *ops = info->fbcon_par; + + if (!ops || ops->currcon < 0) + return; + vc = vc_cons[ops->currcon].d; + + update_screen(vc); +} + +static void fbcon_modechanged(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; + struct display *p; + int rows, cols; + + if (!ops || ops->currcon < 0) + return; + vc = vc_cons[ops->currcon].d; + if (vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[ops->currcon]] != info) + return; + + p = &fb_display[vc->vc_num]; + set_blitting_type(vc, info, p); + + if (CON_IS_VISIBLE(vc)) { + var_to_display(p, &info->var, info); + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; + vc_resize(vc, cols, rows); + updatescrollmode(p, info, vc); + scrollback_max = 0; + scrollback_current = 0; + + if (!fbcon_is_inactive(vc, info)) { + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); + } + + fbcon_set_palette(vc, color_table); + update_screen(vc); + if (softback_buf) + fbcon_update_softback(vc); + } +} + +static void fbcon_set_all_vcs(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; + struct display *p; + int i, rows, cols; + + if (!ops || ops->currcon < 0) + return; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + vc = vc_cons[i].d; + if (!vc || vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[i]] != info) + continue; + + p = &fb_display[vc->vc_num]; + set_blitting_type(vc, info, p); + var_to_display(p, &info->var, info); + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; + vc_resize(vc, cols, rows); + + if (CON_IS_VISIBLE(vc)) { + updatescrollmode(p, info, vc); + scrollback_max = 0; + scrollback_current = 0; + + if (!fbcon_is_inactive(vc, info)) { + ops->var.xoffset = ops->var.yoffset = + p->yscroll = 0; + ops->update_start(info); + } + + fbcon_set_palette(vc, color_table); + update_screen(vc); + if (softback_buf) + fbcon_update_softback(vc); + } + } +} + +static int fbcon_mode_deleted(struct fb_info *info, + struct fb_videomode *mode) +{ + struct fb_info *fb_info; + struct display *p; + int i, j, found = 0; + + /* before deletion, ensure that mode is not in use */ + for (i = first_fb_vc; i <= last_fb_vc; i++) { + j = con2fb_map[i]; + if (j == -1) + continue; + fb_info = registered_fb[j]; + if (fb_info != info) + continue; + p = &fb_display[i]; + if (!p || !p->mode) + continue; + if (fb_mode_is_equal(p->mode, mode)) { + found = 1; + break; + } + } + return found; +} + +static int fbcon_fb_registered(int idx) +{ + int ret = 0, i; + + if (info_idx == -1) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map_boot[i] == idx) { + info_idx = idx; + break; + } + } + if (info_idx != -1) + ret = fbcon_takeover(1); + } else { + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (con2fb_map_boot[i] == idx) + set_con2fb_map(i, idx, 0); + } + } + + return ret; +} + +static void fbcon_fb_blanked(struct fb_info *info, int blank) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; + + if (!ops || ops->currcon < 0) + return; + + vc = vc_cons[ops->currcon].d; + if (vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[ops->currcon]] != info) + return; + + if (CON_IS_VISIBLE(vc)) { + if (blank) + do_blank_screen(0); + else + do_unblank_screen(0); + } + ops->blank_state = blank; +} + +static void fbcon_new_modelist(struct fb_info *info) +{ + int i; + struct vc_data *vc; + struct fb_var_screeninfo var; + struct fb_videomode *mode; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (registered_fb[con2fb_map[i]] != info) + continue; + if (!fb_display[i].mode) + continue; + vc = vc_cons[i].d; + display_to_var(&var, &fb_display[i]); + mode = fb_find_nearest_mode(fb_display[i].mode, + &info->modelist); + fb_videomode_to_var(&var, mode); + + if (vc) + fbcon_set_disp(info, &var, vc); + else + fbcon_preset_disp(info, &var, i); + + } +} + +static int fbcon_event_notify(struct notifier_block *self, + unsigned long action, void *data) +{ + struct fb_event *event = data; + struct fb_info *info = event->info; + struct fb_videomode *mode; + struct fb_con2fbmap *con2fb; + int ret = 0; + + switch(action) { + case FB_EVENT_SUSPEND: + fbcon_suspended(info); + break; + case FB_EVENT_RESUME: + fbcon_resumed(info); + break; + case FB_EVENT_MODE_CHANGE: + fbcon_modechanged(info); + break; + case FB_EVENT_MODE_CHANGE_ALL: + fbcon_set_all_vcs(info); + break; + case FB_EVENT_MODE_DELETE: + mode = event->data; + ret = fbcon_mode_deleted(info, mode); + break; + case FB_EVENT_FB_REGISTERED: + ret = fbcon_fb_registered(info->node); + break; + case FB_EVENT_SET_CONSOLE_MAP: + con2fb = event->data; + ret = set_con2fb_map(con2fb->console - 1, + con2fb->framebuffer, 1); + break; + case FB_EVENT_GET_CONSOLE_MAP: + con2fb = event->data; + con2fb->framebuffer = con2fb_map[con2fb->console - 1]; + break; + case FB_EVENT_BLANK: + fbcon_fb_blanked(info, *(int *)event->data); + break; + case FB_EVENT_NEW_MODELIST: + fbcon_new_modelist(info); + break; + case FB_EVENT_SET_CON_ROTATE: + fbcon_rotate(info, *(int *)event->data); + break; + case FB_EVENT_GET_CON_ROTATE: + ret = fbcon_get_rotate(info); + break; + case FB_EVENT_SET_CON_ROTATE_ALL: + fbcon_rotate_all(info, *(int *)event->data); + } + + return ret; +} + +/* + * The console `switch' structure for the frame buffer based console + */ + +static const struct consw fb_con = { + .owner = THIS_MODULE, + .con_startup = fbcon_startup, + .con_init = fbcon_init, + .con_deinit = fbcon_deinit, + .con_clear = fbcon_clear, + .con_putc = fbcon_putc, + .con_putcs = fbcon_putcs, + .con_cursor = fbcon_cursor, + .con_scroll = fbcon_scroll, + .con_bmove = fbcon_bmove, + .con_switch = fbcon_switch, + .con_blank = fbcon_blank, + .con_font_set = fbcon_set_font, + .con_font_get = fbcon_get_font, + .con_font_default = fbcon_set_def_font, + .con_font_copy = fbcon_copy_font, + .con_set_palette = fbcon_set_palette, + .con_scrolldelta = fbcon_scrolldelta, + .con_set_origin = fbcon_set_origin, + .con_invert_region = fbcon_invert_region, + .con_screen_pos = fbcon_screen_pos, + .con_getxy = fbcon_getxy, + .con_resize = fbcon_resize, +}; + +static struct notifier_block fbcon_event_notifier = { + .notifier_call = fbcon_event_notify, +}; + +static int __init fb_console_init(void) +{ + int i; + + acquire_console_sem(); + fb_register_client(&fbcon_event_notifier); + release_console_sem(); + + for (i = 0; i < MAX_NR_CONSOLES; i++) + con2fb_map[i] = -1; + + if (num_registered_fb) { + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) { + info_idx = i; + break; + } + } + fbcon_takeover(0); + } + + return 0; +} + +module_init(fb_console_init); + +#ifdef MODULE + +static void __exit fb_console_exit(void) +{ + acquire_console_sem(); + fb_unregister_client(&fbcon_event_notifier); + release_console_sem(); + give_up_console(&fb_con); +} + +module_exit(fb_console_exit); + +#endif + +MODULE_LICENSE("GPL"); diff -urN oldtree/drivers/video/fbcmap.c newtree/drivers/video/fbcmap.c --- oldtree/drivers/video/fbcmap.c 2006-01-03 03:21:10.000000000 +0000 +++ newtree/drivers/video/fbcmap.c 2006-02-03 18:18:17.095731320 +0000 @@ -16,6 +16,7 @@ #include #include #include +#include "fbsplash.h" #include @@ -235,14 +236,17 @@ if (transp) htransp = *transp++; if (info->fbops->fb_setcolreg(start++, - hred, hgreen, hblue, + hred, hgreen, hblue, htransp, info)) break; } } - if (rc == 0) + if (rc == 0) { fb_copy_cmap(cmap, &info->cmap); - + if (fbsplash_active(info, vc_cons[fg_console].d) && + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + fbsplash_fix_pseudo_pal(info, vc_cons[fg_console].d); + } return rc; } @@ -250,7 +254,7 @@ { int rc, size = cmap->len * sizeof(u16); struct fb_cmap umap; - + if (cmap->start < 0 || (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)) return -EINVAL; diff -urN oldtree/drivers/video/fbsplash.c newtree/drivers/video/fbsplash.c --- oldtree/drivers/video/fbsplash.c 1970-01-01 00:00:00.000000000 +0000 +++ newtree/drivers/video/fbsplash.c 2006-02-03 18:18:17.096731168 +0000 @@ -0,0 +1,406 @@ +/* + * linux/drivers/video/fbsplash.c -- Framebuffer splash routines + * + * Copyright (C) 2004 Michal Januszewski + * + * Code based upon "Bootsplash" (C) 2001-2003 + * Volker Poplawski , + * Stefan Reinauer , + * Steffen Winterfeldt , + * Michael Schroeder , + * Ken Wimer . + * + * Splash render routines are located in /linux/drivers/video/cfbsplash.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "console/fbcon.h" +#include "fbsplash.h" + +#define SPLASH_VERSION "0.9.2" + +extern signed char con2fb_map[]; +static int fbsplash_enable(struct vc_data *vc); +char fbsplash_path[KMOD_PATH_LEN] = "/sbin/splash_helper"; + +int fbsplash_call_helper(char* cmd, unsigned short vc) +{ + char *envp[] = { + "HOME=/", + "PATH=/sbin:/bin", + NULL + }; + + char tfb[5]; + char tcons[5]; + unsigned char fb = (int) con2fb_map[vc]; + + char *argv[] = { + fbsplash_path, + "2", + cmd, + tcons, + tfb, + vc_cons[vc].d->vc_splash.theme, + NULL + }; + + snprintf(tfb,5,"%d",fb); + snprintf(tcons,5,"%d",vc); + + return call_usermodehelper(fbsplash_path, argv, envp, 1); +} + +/* Disables fbsplash on a virtual console; called with console sem held. */ +int fbsplash_disable(struct vc_data *vc, unsigned char redraw) +{ + struct fb_info* info; + + if (!vc->vc_splash.state) + return -EINVAL; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (info == NULL) + return -EINVAL; + + vc->vc_splash.state = 0; + vc_resize(vc, info->var.xres / vc->vc_font.width, + info->var.yres / vc->vc_font.height); + + if (fg_console == vc->vc_num && redraw) { + redraw_screen(vc, 0); + update_region(vc, vc->vc_origin + + vc->vc_size_row * vc->vc_top, + vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); + } + + printk(KERN_INFO "fbsplash: switched splash state to 'off' on console %d\n", + vc->vc_num); + + return 0; +} + +/* Enables fbsplash on a virtual console; called with console sem held. */ +static int fbsplash_enable(struct vc_data *vc) +{ + struct fb_info* info; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (vc->vc_splash.twidth == 0 || vc->vc_splash.theight == 0 || + info == NULL || vc->vc_splash.state || (!info->splash.data && + vc->vc_num == fg_console)) + return -EINVAL; + + vc->vc_splash.state = 1; + vc_resize(vc, vc->vc_splash.twidth / vc->vc_font.width, + vc->vc_splash.theight / vc->vc_font.height); + + if (fg_console == vc->vc_num) { + redraw_screen(vc, 0); + update_region(vc, vc->vc_origin + + vc->vc_size_row * vc->vc_top, + vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); + fbsplash_clear_margins(vc, info, 0); + } + + printk(KERN_INFO "fbsplash: switched splash state to 'on' on console %d\n", + vc->vc_num); + + return 0; +} + +static inline int fbsplash_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin) +{ + int tmp, ret; + + if (get_user(tmp, state)) + return -EFAULT; + + if (origin == FB_SPLASH_IO_ORIG_USER) + acquire_console_sem(); + if (!tmp) + ret = fbsplash_disable(vc, 1); + else + ret = fbsplash_enable(vc); + if (origin == FB_SPLASH_IO_ORIG_USER) + release_console_sem(); + + return ret; +} + +static inline int fbsplash_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state) +{ + return put_user(vc->vc_splash.state, (unsigned int __user*) state); +} + +static int fbsplash_ioctl_dosetcfg(struct vc_data *vc, struct vc_splash __user *arg, unsigned char origin) +{ + struct vc_splash cfg; + struct fb_info *info; + int len; + char *tmp; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (copy_from_user(&cfg, arg, sizeof(struct vc_splash))) + return -EFAULT; + if (info == NULL || !cfg.twidth || !cfg.theight || + cfg.tx + cfg.twidth > info->var.xres || + cfg.ty + cfg.theight > info->var.yres) + return -EINVAL; + + len = strlen_user(cfg.theme); + if (!len || len > FB_SPLASH_THEME_LEN) + return -EINVAL; + tmp = kmalloc(len, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + if (copy_from_user(tmp, (void __user *)cfg.theme, len)) + return -EFAULT; + cfg.theme = tmp; + cfg.state = 0; + + /* If this ioctl is a response to a request from kernel, the console sem + * is already held; we also don't need to disable splash because either the + * new config and background picture will be successfully loaded, and the + * splash will stay on, or in case of a failure it'll be turned off in fbcon. */ + if (origin == FB_SPLASH_IO_ORIG_USER) { + acquire_console_sem(); + if (vc->vc_splash.state) + fbsplash_disable(vc, 1); + } + + if (vc->vc_splash.theme) + kfree(vc->vc_splash.theme); + + vc->vc_splash = cfg; + + if (origin == FB_SPLASH_IO_ORIG_USER) + release_console_sem(); + + printk(KERN_INFO "fbsplash: console %d using theme '%s'\n", + vc->vc_num, vc->vc_splash.theme); + return 0; +} + +static int fbsplash_ioctl_dogetcfg(struct vc_data *vc, struct vc_splash __user *arg) +{ + struct vc_splash splash; + char __user *tmp; + + if (get_user(tmp, &arg->theme)) + return -EFAULT; + + splash = vc->vc_splash; + splash.theme = tmp; + + if (vc->vc_splash.theme) { + if (copy_to_user(tmp, vc->vc_splash.theme, strlen(vc->vc_splash.theme) + 1)) + return -EFAULT; + } else + if (put_user(0, tmp)) + return -EFAULT; + + if (copy_to_user(arg, &splash, sizeof(struct vc_splash))) + return -EFAULT; + + return 0; +} + +static int fbsplash_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin) +{ + struct fb_image img; + struct fb_info *info; + int len; + u8 *tmp; + + if (vc->vc_num != fg_console) + return -EINVAL; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (info == NULL) + return -EINVAL; + + if (copy_from_user(&img, arg, sizeof(struct fb_image))) + return -EFAULT; + + if (img.width != info->var.xres || img.height != info->var.yres) { + printk(KERN_ERR "fbsplash: picture dimensions mismatch\n"); + return -EINVAL; + } + + if (img.depth != info->var.bits_per_pixel) { + printk(KERN_ERR "fbsplash: picture depth mismatch\n"); + return -EINVAL; + } + + if (img.depth == 8) { + if (!img.cmap.len || !img.cmap.red || !img.cmap.green || + !img.cmap.blue) + return -EINVAL; + + tmp = vmalloc(img.cmap.len * 3 * 2); + if (!tmp) + return -ENOMEM; + + if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) || + copy_from_user(tmp + (img.cmap.len << 1), + (void __user*)img.cmap.green, (img.cmap.len << 1)) || + copy_from_user(tmp + (img.cmap.len << 2), + (void __user*)img.cmap.blue, (img.cmap.len << 1))) { + vfree(tmp); + return -EFAULT; + } + + img.cmap.transp = NULL; + img.cmap.red = (u16*)tmp; + img.cmap.green = img.cmap.red + img.cmap.len; + img.cmap.blue = img.cmap.green + img.cmap.len; + } else { + img.cmap.red = NULL; + } + + len = ((img.depth + 7) >> 3) * img.width * img.height; + tmp = vmalloc(len); + + if (!tmp) + goto out; + + if (copy_from_user(tmp, (void __user*)img.data, len)) + goto out; + + img.data = tmp; + + /* If this ioctl is a response to a request from kernel, the console sem + * is already held. */ + if (origin == FB_SPLASH_IO_ORIG_USER) + acquire_console_sem(); + + if (info->splash.data) + vfree((u8*)info->splash.data); + if (info->splash.cmap.red) + vfree(info->splash.cmap.red); + + info->splash = img; + + if (origin == FB_SPLASH_IO_ORIG_USER) + release_console_sem(); + + return 0; + +out: if (img.cmap.red) + vfree(img.cmap.red); + if (tmp) + vfree(tmp); + return -ENOMEM; +} + +static int splash_ioctl(struct inode * inode, struct file *filp, u_int cmd, + u_long arg) +{ + struct fb_splash_iowrapper __user *wrapper = (void __user*) arg; + struct vc_data *vc = NULL; + unsigned short vc_num = 0; + unsigned char origin = 0; + void __user *data = NULL; + + if (!access_ok(VERIFY_READ, wrapper, + sizeof(struct fb_splash_iowrapper))) + return -EFAULT; + + __get_user(vc_num, &wrapper->vc); + __get_user(origin, &wrapper->origin); + __get_user(data, &wrapper->data); + + if (!vc_cons_allocated(vc_num)) + return -EINVAL; + + vc = vc_cons[vc_num].d; + + switch (cmd) { + case FBIOSPLASH_SETPIC: + return fbsplash_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin); + case FBIOSPLASH_SETCFG: + return fbsplash_ioctl_dosetcfg(vc, (struct vc_splash*)data, origin); + case FBIOSPLASH_GETCFG: + return fbsplash_ioctl_dogetcfg(vc, (struct vc_splash*)data); + case FBIOSPLASH_SETSTATE: + return fbsplash_ioctl_dosetstate(vc, (unsigned int *)data, origin); + case FBIOSPLASH_GETSTATE: + return fbsplash_ioctl_dogetstate(vc, (unsigned int *)data); + default: + return -ENOIOCTLCMD; + } +} + +static struct file_operations splash_ops = { + .owner = THIS_MODULE, + .ioctl = splash_ioctl +}; + +static struct miscdevice splash_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "fbsplash", + .fops = &splash_ops +}; + +int fbsplash_init(void) +{ + struct fb_info *info; + struct vc_data *vc; + int i; + + vc = vc_cons[0].d; + info = registered_fb[0]; + + for (i = 0; i < num_registered_fb; i++) { + registered_fb[i]->splash.data = NULL; + registered_fb[i]->splash.cmap.red = NULL; + } + + for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) { + vc_cons[i].d->vc_splash.state = vc_cons[i].d->vc_splash.twidth = + vc_cons[i].d->vc_splash.theight = 0; + vc_cons[i].d->vc_splash.theme = NULL; + } + + i = misc_register(&splash_dev); + if (i) { + printk(KERN_ERR "fbsplash: failed to register device\n"); + return i; + } + + fbsplash_call_helper("init", 0); + + return 0; +} + +EXPORT_SYMBOL(fbsplash_path); diff -urN oldtree/drivers/video/fbsplash.h newtree/drivers/video/fbsplash.h --- oldtree/drivers/video/fbsplash.h 1970-01-01 00:00:00.000000000 +0000 +++ newtree/drivers/video/fbsplash.h 2006-02-03 18:18:17.096731168 +0000 @@ -0,0 +1,76 @@ +/* + * linux/drivers/video/fbsplash.h -- Framebuffer splash headers + * + * Copyright (C) 2004 Michal Januszewski + * + */ + +#ifndef __FB_SPLASH_H +#define __FB_SPLASH_H + +#ifndef _LINUX_FB_H +#include +#endif + +/* This is needed for vc_cons in fbcmap.c */ +#include + +struct fb_cursor; +struct fb_info; +struct vc_data; + +#ifdef CONFIG_FB_SPLASH +/* fbsplash.c */ +int fbsplash_init(void); +int fbsplash_call_helper(char* cmd, unsigned short cons); +int fbsplash_disable(struct vc_data *vc, unsigned char redraw); + +/* cfbsplash.c */ +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx); +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor); +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width); +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only); +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank); +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width); +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp); +void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc); + +/* vt.c */ +void acquire_console_sem(void); +void release_console_sem(void); +void do_unblank_screen(int entering_gfx); + +/* struct vc_data *y */ +#define fbsplash_active_vc(y) (y->vc_splash.state && y->vc_splash.theme) + +/* struct fb_info *x, struct vc_data *y */ +#define fbsplash_active_nores(x,y) (x->splash.data && fbsplash_active_vc(y)) + +/* struct fb_info *x, struct vc_data *y */ +#define fbsplash_active(x,y) (fbsplash_active_nores(x,y) && \ + x->splash.width == x->var.xres && \ + x->splash.height == x->var.yres && \ + x->splash.depth == x->var.bits_per_pixel) + + +#else /* CONFIG_FB_SPLASH */ + +static inline void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {} +static inline void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {} +static inline void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) {} +static inline void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {} +static inline void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {} +static inline void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) {} +static inline void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {} +static inline void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {} +static inline int fbsplash_call_helper(char* cmd, unsigned short cons) { return 0; } +static inline int fbsplash_init(void) { return 0; } +static inline int fbsplash_disable(struct vc_data *vc, unsigned char redraw) { return 0; } + +#define fbsplash_active_vc(y) (0) +#define fbsplash_active_nores(x,y) (0) +#define fbsplash_active(x,y) (0) + +#endif /* CONFIG_FB_SPLASH */ + +#endif /* __FB_SPLASH_H */ diff -urN oldtree/include/linux/console_splash.h newtree/include/linux/console_splash.h --- oldtree/include/linux/console_splash.h 1970-01-01 00:00:00.000000000 +0000 +++ newtree/include/linux/console_splash.h 2006-02-03 18:18:17.097731016 +0000 @@ -0,0 +1,13 @@ +#ifndef _LINUX_CONSOLE_SPLASH_H_ +#define _LINUX_CONSOLE_SPLASH_H_ 1 + +/* A structure used by the framebuffer splash code (drivers/video/fbsplash.c) */ +struct vc_splash { + __u8 bg_color; /* The color that is to be treated as transparent */ + __u8 state; /* Current splash state: 0 = off, 1 = on */ + __u16 tx, ty; /* Top left corner coordinates of the text field */ + __u16 twidth, theight; /* Width and height of the text field */ + char* theme; +}; + +#endif diff -urN oldtree/include/linux/console_struct.h newtree/include/linux/console_struct.h --- oldtree/include/linux/console_struct.h 2006-01-03 03:21:10.000000000 +0000 +++ newtree/include/linux/console_struct.h 2006-02-03 18:18:17.097731016 +0000 @@ -14,6 +14,7 @@ struct vt_struct; #define NPAR 16 +#include struct vc_data { unsigned short vc_num; /* Console number */ @@ -97,6 +98,8 @@ struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ unsigned long vc_uni_pagedir; unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ + + struct vc_splash vc_splash; /* additional information is in vt_kern.h */ }; diff -urN oldtree/include/linux/fb.h newtree/include/linux/fb.h --- oldtree/include/linux/fb.h 2006-01-03 03:21:10.000000000 +0000 +++ newtree/include/linux/fb.h 2006-02-03 18:18:17.098730864 +0000 @@ -8,6 +8,13 @@ #define FB_MAJOR 29 #define FB_MAX 32 /* sufficient for now */ +struct fb_splash_iowrapper +{ + unsigned short vc; /* Virtual console */ + unsigned char origin; /* Point of origin of the request */ + void *data; +}; + /* ioctls 0x46 is 'F' */ #define FBIOGET_VSCREENINFO 0x4600 @@ -35,7 +42,15 @@ #define FBIOGET_HWCINFO 0x4616 #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 - +#define FBIOSPLASH_SETCFG _IOWR('F', 0x19, struct fb_splash_iowrapper) +#define FBIOSPLASH_GETCFG _IOR('F', 0x1A, struct fb_splash_iowrapper) +#define FBIOSPLASH_SETSTATE _IOWR('F', 0x1B, struct fb_splash_iowrapper) +#define FBIOSPLASH_GETSTATE _IOR('F', 0x1C, struct fb_splash_iowrapper) +#define FBIOSPLASH_SETPIC _IOWR('F', 0x1D, struct fb_splash_iowrapper) + +#define FB_SPLASH_THEME_LEN 128 /* Maximum lenght of a theme name */ +#define FB_SPLASH_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */ +#define FB_SPLASH_IO_ORIG_USER 1 /* User ioctl origin */ #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ @@ -769,6 +784,9 @@ #define FBINFO_STATE_SUSPENDED 1 u32 state; /* Hardware state i.e suspend */ void *fbcon_par; /* fbcon use-only private area */ + + struct fb_image splash; + /* From here on everything is device dependent */ void *par; }; diff -urN oldtree/include/linux/fb.h.orig newtree/include/linux/fb.h.orig --- oldtree/include/linux/fb.h.orig 1970-01-01 00:00:00.000000000 +0000 +++ newtree/include/linux/fb.h.orig 2006-01-03 03:21:10.000000000 +0000 @@ -0,0 +1,996 @@ +#ifndef _LINUX_FB_H +#define _LINUX_FB_H + +#include + +/* Definitions of frame buffers */ + +#define FB_MAJOR 29 +#define FB_MAX 32 /* sufficient for now */ + +/* ioctls + 0x46 is 'F' */ +#define FBIOGET_VSCREENINFO 0x4600 +#define FBIOPUT_VSCREENINFO 0x4601 +#define FBIOGET_FSCREENINFO 0x4602 +#define FBIOGETCMAP 0x4604 +#define FBIOPUTCMAP 0x4605 +#define FBIOPAN_DISPLAY 0x4606 +#ifdef __KERNEL__ +#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor_user) +#else +#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor) +#endif +/* 0x4607-0x460B are defined below */ +/* #define FBIOGET_MONITORSPEC 0x460C */ +/* #define FBIOPUT_MONITORSPEC 0x460D */ +/* #define FBIOSWITCH_MONIBIT 0x460E */ +#define FBIOGET_CON2FBMAP 0x460F +#define FBIOPUT_CON2FBMAP 0x4610 +#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */ +#define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank) +#define FBIO_ALLOC 0x4613 +#define FBIO_FREE 0x4614 +#define FBIOGET_GLYPH 0x4615 +#define FBIOGET_HWCINFO 0x4616 +#define FBIOPUT_MODEINFO 0x4617 +#define FBIOGET_DISPINFO 0x4618 + + +#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ +#define FB_TYPE_PLANES 1 /* Non interleaved planes */ +#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */ +#define FB_TYPE_TEXT 3 /* Text/attributes */ +#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */ + +#define FB_AUX_TEXT_MDA 0 /* Monochrome text */ +#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */ +#define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */ +#define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */ +#define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */ + +#define FB_AUX_VGA_PLANES_VGA4 0 /* 16 color planes (EGA/VGA) */ +#define FB_AUX_VGA_PLANES_CFB4 1 /* CFB4 in planes (VGA) */ +#define FB_AUX_VGA_PLANES_CFB8 2 /* CFB8 in planes (VGA) */ + +#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */ +#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */ +#define FB_VISUAL_TRUECOLOR 2 /* True color */ +#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */ +#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */ +#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */ + +#define FB_ACCEL_NONE 0 /* no hardware accelerator */ +#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */ +#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */ +#define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */ +#define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */ +#define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */ +#define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */ +#define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */ +#define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */ +#define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */ +#define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */ +#define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */ +#define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */ +#define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */ +#define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */ +#define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */ +#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */ +#define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */ +#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */ +#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */ +#define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */ +#define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */ +#define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */ +#define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */ +#define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */ +#define FB_ACCEL_SUN_TCX 25 /* Sun tcx */ +#define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */ +#define FB_ACCEL_NV3 27 /* nVidia RIVA 128 */ +#define FB_ACCEL_NV4 28 /* nVidia RIVA TNT */ +#define FB_ACCEL_NV5 29 /* nVidia RIVA TNT2 */ +#define FB_ACCEL_CT_6555x 30 /* C&T 6555x */ +#define FB_ACCEL_3DFX_BANSHEE 31 /* 3Dfx Banshee */ +#define FB_ACCEL_ATI_RAGE128 32 /* ATI Rage128 family */ +#define FB_ACCEL_IGS_CYBER2000 33 /* CyberPro 2000 */ +#define FB_ACCEL_IGS_CYBER2010 34 /* CyberPro 2010 */ +#define FB_ACCEL_IGS_CYBER5000 35 /* CyberPro 5000 */ +#define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */ +#define FB_ACCEL_3DLABS_PERMEDIA3 37 /* 3Dlabs Permedia 3 */ +#define FB_ACCEL_ATI_RADEON 38 /* ATI Radeon family */ +#define FB_ACCEL_I810 39 /* Intel 810/815 */ +#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 650, 740 */ +#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre") */ +#define FB_ACCEL_I830 42 /* Intel 830M/845G/85x/865G */ +#define FB_ACCEL_NV_10 43 /* nVidia Arch 10 */ +#define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */ +#define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */ +#define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */ +#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */ +#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */ +#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ +#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ +#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */ +#define FB_ACCEL_NEOMAGIC_NM2097 93 /* NeoMagic NM2097 */ +#define FB_ACCEL_NEOMAGIC_NM2160 94 /* NeoMagic NM2160 */ +#define FB_ACCEL_NEOMAGIC_NM2200 95 /* NeoMagic NM2200 */ +#define FB_ACCEL_NEOMAGIC_NM2230 96 /* NeoMagic NM2230 */ +#define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */ +#define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */ + +#define FB_ACCEL_SAVAGE4 0x80 /* S3 Savage4 */ +#define FB_ACCEL_SAVAGE3D 0x81 /* S3 Savage3D */ +#define FB_ACCEL_SAVAGE3D_MV 0x82 /* S3 Savage3D-MV */ +#define FB_ACCEL_SAVAGE2000 0x83 /* S3 Savage2000 */ +#define FB_ACCEL_SAVAGE_MX_MV 0x84 /* S3 Savage/MX-MV */ +#define FB_ACCEL_SAVAGE_MX 0x85 /* S3 Savage/MX */ +#define FB_ACCEL_SAVAGE_IX_MV 0x86 /* S3 Savage/IX-MV */ +#define FB_ACCEL_SAVAGE_IX 0x87 /* S3 Savage/IX */ +#define FB_ACCEL_PROSAVAGE_PM 0x88 /* S3 ProSavage PM133 */ +#define FB_ACCEL_PROSAVAGE_KM 0x89 /* S3 ProSavage KM133 */ +#define FB_ACCEL_S3TWISTER_P 0x8a /* S3 Twister */ +#define FB_ACCEL_S3TWISTER_K 0x8b /* S3 TwisterK */ +#define FB_ACCEL_SUPERSAVAGE 0x8c /* S3 Supersavage */ +#define FB_ACCEL_PROSAVAGE_DDR 0x8d /* S3 ProSavage DDR */ +#define FB_ACCEL_PROSAVAGE_DDRK 0x8e /* S3 ProSavage DDR-K */ + +struct fb_fix_screeninfo { + char id[16]; /* identification string eg "TT Builtin" */ + unsigned long smem_start; /* Start of frame buffer mem */ + /* (physical address) */ + __u32 smem_len; /* Length of frame buffer mem */ + __u32 type; /* see FB_TYPE_* */ + __u32 type_aux; /* Interleave for interleaved Planes */ + __u32 visual; /* see FB_VISUAL_* */ + __u16 xpanstep; /* zero if no hardware panning */ + __u16 ypanstep; /* zero if no hardware panning */ + __u16 ywrapstep; /* zero if no hardware ywrap */ + __u32 line_length; /* length of a line in bytes */ + unsigned long mmio_start; /* Start of Memory Mapped I/O */ + /* (physical address) */ + __u32 mmio_len; /* Length of Memory Mapped I/O */ + __u32 accel; /* Indicate to driver which */ + /* specific chip/card we have */ + __u16 reserved[3]; /* Reserved for future compatibility */ +}; + +/* Interpretation of offset for color fields: All offsets are from the right, + * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you + * can use the offset as right argument to <<). A pixel afterwards is a bit + * stream and is written to video memory as that unmodified. This implies + * big-endian byte order if bits_per_pixel is greater than 8. + */ +struct fb_bitfield { + __u32 offset; /* beginning of bitfield */ + __u32 length; /* length of bitfield */ + __u32 msb_right; /* != 0 : Most significant bit is */ + /* right */ +}; + +#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */ + +#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/ +#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */ +#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */ +#define FB_ACTIVATE_MASK 15 + /* values */ +#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */ +#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */ +#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */ +#define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/ +#define FB_ACTIVATE_INV_MODE 256 /* invalidate videomode */ + +#define FB_ACCELF_TEXT 1 /* (OBSOLETE) see fb_info.flags and vc_mode */ + +#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ +#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ +#define FB_SYNC_EXT 4 /* external sync */ +#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ +#define FB_SYNC_BROADCAST 16 /* broadcast video timings */ + /* vtotal = 144d/288n/576i => PAL */ + /* vtotal = 121d/242n/484i => NTSC */ +#define FB_SYNC_ON_GREEN 32 /* sync on green */ + +#define FB_VMODE_NONINTERLACED 0 /* non interlaced */ +#define FB_VMODE_INTERLACED 1 /* interlaced */ +#define FB_VMODE_DOUBLE 2 /* double scan */ +#define FB_VMODE_MASK 255 + +#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */ +#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ +#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ + +/* + * Display rotation support + */ +#define FB_ROTATE_UR 0 +#define FB_ROTATE_CW 1 +#define FB_ROTATE_UD 2 +#define FB_ROTATE_CCW 3 + +#define PICOS2KHZ(a) (1000000000UL/(a)) +#define KHZ2PICOS(a) (1000000000UL/(a)) + +struct fb_var_screeninfo { + __u32 xres; /* visible resolution */ + __u32 yres; + __u32 xres_virtual; /* virtual resolution */ + __u32 yres_virtual; + __u32 xoffset; /* offset from virtual to visible */ + __u32 yoffset; /* resolution */ + + __u32 bits_per_pixel; /* guess what */ + __u32 grayscale; /* != 0 Graylevels instead of colors */ + + struct fb_bitfield red; /* bitfield in fb mem if true color, */ + struct fb_bitfield green; /* else only length is significant */ + struct fb_bitfield blue; + struct fb_bitfield transp; /* transparency */ + + __u32 nonstd; /* != 0 Non standard pixel format */ + + __u32 activate; /* see FB_ACTIVATE_* */ + + __u32 height; /* height of picture in mm */ + __u32 width; /* width of picture in mm */ + + __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */ + + /* Timing: All values in pixclocks, except pixclock (of course) */ + __u32 pixclock; /* pixel clock in ps (pico seconds) */ + __u32 left_margin; /* time from sync to picture */ + __u32 right_margin; /* time from picture to sync */ + __u32 upper_margin; /* time from sync to picture */ + __u32 lower_margin; + __u32 hsync_len; /* length of horizontal sync */ + __u32 vsync_len; /* length of vertical sync */ + __u32 sync; /* see FB_SYNC_* */ + __u32 vmode; /* see FB_VMODE_* */ + __u32 rotate; /* angle we rotate counter clockwise */ + __u32 reserved[5]; /* Reserved for future compatibility */ +}; + +struct fb_cmap { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ + __u16 *red; /* Red values */ + __u16 *green; + __u16 *blue; + __u16 *transp; /* transparency, can be NULL */ +}; + +struct fb_con2fbmap { + __u32 console; + __u32 framebuffer; +}; + +/* VESA Blanking Levels */ +#define VESA_NO_BLANKING 0 +#define VESA_VSYNC_SUSPEND 1 +#define VESA_HSYNC_SUSPEND 2 +#define VESA_POWERDOWN 3 + + +enum { + /* screen: unblanked, hsync: on, vsync: on */ + FB_BLANK_UNBLANK = VESA_NO_BLANKING, + + /* screen: blanked, hsync: on, vsync: on */ + FB_BLANK_NORMAL = VESA_NO_BLANKING + 1, + + /* screen: blanked, hsync: on, vsync: off */ + FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1, + + /* screen: blanked, hsync: off, vsync: on */ + FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1, + + /* screen: blanked, hsync: off, vsync: off */ + FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1 +}; + +#define FB_VBLANK_VBLANKING 0x001 /* currently in a vertical blank */ +#define FB_VBLANK_HBLANKING 0x002 /* currently in a horizontal blank */ +#define FB_VBLANK_HAVE_VBLANK 0x004 /* vertical blanks can be detected */ +#define FB_VBLANK_HAVE_HBLANK 0x008 /* horizontal blanks can be detected */ +#define FB_VBLANK_HAVE_COUNT 0x010 /* global retrace counter is available */ +#define FB_VBLANK_HAVE_VCOUNT 0x020 /* the vcount field is valid */ +#define FB_VBLANK_HAVE_HCOUNT 0x040 /* the hcount field is valid */ +#define FB_VBLANK_VSYNCING 0x080 /* currently in a vsync */ +#define FB_VBLANK_HAVE_VSYNC 0x100 /* verical syncs can be detected */ + +struct fb_vblank { + __u32 flags; /* FB_VBLANK flags */ + __u32 count; /* counter of retraces since boot */ + __u32 vcount; /* current scanline position */ + __u32 hcount; /* current scandot position */ + __u32 reserved[4]; /* reserved for future compatibility */ +}; + +/* Internal HW accel */ +#define ROP_COPY 0 +#define ROP_XOR 1 + +struct fb_copyarea { + __u32 dx; + __u32 dy; + __u32 width; + __u32 height; + __u32 sx; + __u32 sy; +}; + +struct fb_fillrect { + __u32 dx; /* screen-relative */ + __u32 dy; + __u32 width; + __u32 height; + __u32 color; + __u32 rop; +}; + +struct fb_image { + __u32 dx; /* Where to place image */ + __u32 dy; + __u32 width; /* Size of image */ + __u32 height; + __u32 fg_color; /* Only used when a mono bitmap */ + __u32 bg_color; + __u8 depth; /* Depth of the image */ + const char *data; /* Pointer to image data */ + struct fb_cmap cmap; /* color map info */ +}; + +/* + * hardware cursor control + */ + +#define FB_CUR_SETIMAGE 0x01 +#define FB_CUR_SETPOS 0x02 +#define FB_CUR_SETHOT 0x04 +#define FB_CUR_SETCMAP 0x08 +#define FB_CUR_SETSHAPE 0x10 +#define FB_CUR_SETSIZE 0x20 +#define FB_CUR_SETALL 0xFF + +struct fbcurpos { + __u16 x, y; +}; + +struct fb_cursor { + __u16 set; /* what to set */ + __u16 enable; /* cursor on/off */ + __u16 rop; /* bitop operation */ + const char *mask; /* cursor mask bits */ + struct fbcurpos hot; /* cursor hot spot */ + struct fb_image image; /* Cursor image */ +}; + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct vm_area_struct; +struct fb_info; +struct device; +struct file; + +/* Definitions below are used in the parsed monitor specs */ +#define FB_DPMS_ACTIVE_OFF 1 +#define FB_DPMS_SUSPEND 2 +#define FB_DPMS_STANDBY 4 + +#define FB_DISP_DDI 1 +#define FB_DISP_ANA_700_300 2 +#define FB_DISP_ANA_714_286 4 +#define FB_DISP_ANA_1000_400 8 +#define FB_DISP_ANA_700_000 16 + +#define FB_DISP_MONO 32 +#define FB_DISP_RGB 64 +#define FB_DISP_MULTI 128 +#define FB_DISP_UNKNOWN 256 + +#define FB_SIGNAL_NONE 0 +#define FB_SIGNAL_BLANK_BLANK 1 +#define FB_SIGNAL_SEPARATE 2 +#define FB_SIGNAL_COMPOSITE 4 +#define FB_SIGNAL_SYNC_ON_GREEN 8 +#define FB_SIGNAL_SERRATION_ON 16 + +#define FB_MISC_PRIM_COLOR 1 +#define FB_MISC_1ST_DETAIL 2 /* First Detailed Timing is preferred */ +struct fb_chroma { + __u32 redx; /* in fraction of 1024 */ + __u32 greenx; + __u32 bluex; + __u32 whitex; + __u32 redy; + __u32 greeny; + __u32 bluey; + __u32 whitey; +}; + +struct fb_monspecs { + struct fb_chroma chroma; + struct fb_videomode *modedb; /* mode database */ + __u8 manufacturer[4]; /* Manufacturer */ + __u8 monitor[14]; /* Monitor String */ + __u8 serial_no[14]; /* Serial Number */ + __u8 ascii[14]; /* ? */ + __u32 modedb_len; /* mode database length */ + __u32 model; /* Monitor Model */ + __u32 serial; /* Serial Number - Integer */ + __u32 year; /* Year manufactured */ + __u32 week; /* Week Manufactured */ + __u32 hfmin; /* hfreq lower limit (Hz) */ + __u32 hfmax; /* hfreq upper limit (Hz) */ + __u32 dclkmin; /* pixelclock lower limit (Hz) */ + __u32 dclkmax; /* pixelclock upper limit (Hz) */ + __u16 input; /* display type - see FB_DISP_* */ + __u16 dpms; /* DPMS support - see FB_DPMS_ */ + __u16 signal; /* Signal Type - see FB_SIGNAL_* */ + __u16 vfmin; /* vfreq lower limit (Hz) */ + __u16 vfmax; /* vfreq upper limit (Hz) */ + __u16 gamma; /* Gamma - in fractions of 100 */ + __u16 gtf : 1; /* supports GTF */ + __u16 misc; /* Misc flags - see FB_MISC_* */ + __u8 version; /* EDID version... */ + __u8 revision; /* ...and revision */ + __u8 max_x; /* Maximum horizontal size (cm) */ + __u8 max_y; /* Maximum vertical size (cm) */ +}; + +struct fb_cmap_user { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ + __u16 __user *red; /* Red values */ + __u16 __user *green; + __u16 __user *blue; + __u16 __user *transp; /* transparency, can be NULL */ +}; + +struct fb_image_user { + __u32 dx; /* Where to place image */ + __u32 dy; + __u32 width; /* Size of image */ + __u32 height; + __u32 fg_color; /* Only used when a mono bitmap */ + __u32 bg_color; + __u8 depth; /* Depth of the image */ + const char __user *data; /* Pointer to image data */ + struct fb_cmap_user cmap; /* color map info */ +}; + +struct fb_cursor_user { + __u16 set; /* what to set */ + __u16 enable; /* cursor on/off */ + __u16 rop; /* bitop operation */ + const char __user *mask; /* cursor mask bits */ + struct fbcurpos hot; /* cursor hot spot */ + struct fb_image_user image; /* Cursor image */ +}; + +/* + * Register/unregister for framebuffer events + */ + +/* The resolution of the passed in fb_info about to change */ +#define FB_EVENT_MODE_CHANGE 0x01 +/* The display on this fb_info is beeing suspended, no access to the + * framebuffer is allowed any more after that call returns + */ +#define FB_EVENT_SUSPEND 0x02 +/* The display on this fb_info was resumed, you can restore the display + * if you own it + */ +#define FB_EVENT_RESUME 0x03 +/* An entry from the modelist was removed */ +#define FB_EVENT_MODE_DELETE 0x04 +/* A driver registered itself */ +#define FB_EVENT_FB_REGISTERED 0x05 +/* CONSOLE-SPECIFIC: get console to framebuffer mapping */ +#define FB_EVENT_GET_CONSOLE_MAP 0x06 +/* CONSOLE-SPECIFIC: set console to framebuffer mapping */ +#define FB_EVENT_SET_CONSOLE_MAP 0x07 +/* A display blank is requested */ +#define FB_EVENT_BLANK 0x08 +/* Private modelist is to be replaced */ +#define FB_EVENT_NEW_MODELIST 0x09 +/* The resolution of the passed in fb_info about to change and + all vc's should be changed */ +#define FB_EVENT_MODE_CHANGE_ALL 0x0A +/* CONSOLE-SPECIFIC: set console rotation */ +#define FB_EVENT_SET_CON_ROTATE 0x0B +/* CONSOLE-SPECIFIC: get console rotation */ +#define FB_EVENT_GET_CON_ROTATE 0x0C +/* CONSOLE-SPECIFIC: rotate all consoles */ +#define FB_EVENT_SET_CON_ROTATE_ALL 0x0D + +struct fb_event { + struct fb_info *info; + void *data; +}; + + +extern int fb_register_client(struct notifier_block *nb); +extern int fb_unregister_client(struct notifier_block *nb); + +/* + * Pixmap structure definition + * + * The purpose of this structure is to translate data + * from the hardware independent format of fbdev to what + * format the hardware needs. + */ + +#define FB_PIXMAP_DEFAULT 1 /* used internally by fbcon */ +#define FB_PIXMAP_SYSTEM 2 /* memory is in system RAM */ +#define FB_PIXMAP_IO 4 /* memory is iomapped */ +#define FB_PIXMAP_SYNC 256 /* set if GPU can DMA */ + +struct fb_pixmap { + u8 *addr; /* pointer to memory */ + u32 size; /* size of buffer in bytes */ + u32 offset; /* current offset to buffer */ + u32 buf_align; /* byte alignment of each bitmap */ + u32 scan_align; /* alignment per scanline */ + u32 access_align; /* alignment per read/write (bits) */ + u32 flags; /* see FB_PIXMAP_* */ + /* access methods */ + void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size); + void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size); +}; + + +/* + * Frame buffer operations + * + * LOCKING NOTE: those functions must _ALL_ be called with the console + * semaphore held, this is the only suitable locking mecanism we have + * in 2.6. Some may be called at interrupt time at this point though. + */ + +struct fb_ops { + /* open/release and usage marking */ + struct module *owner; + int (*fb_open)(struct fb_info *info, int user); + int (*fb_release)(struct fb_info *info, int user); + + /* For framebuffers with strange non linear layouts or that do not + * work with normal memory mapped access + */ + ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos); + ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos); + + /* checks var and eventually tweaks it to something supported, + * DO NOT MODIFY PAR */ + int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info); + + /* set the video mode according to info->var */ + int (*fb_set_par)(struct fb_info *info); + + /* set color register */ + int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info); + + /* set color registers in batch */ + int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info); + + /* blank display */ + int (*fb_blank)(int blank, struct fb_info *info); + + /* pan display */ + int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info); + + /* Draws a rectangle */ + void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect); + /* Copy data from area to another */ + void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region); + /* Draws a image to the display */ + void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image); + + /* Draws cursor */ + int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor); + + /* Rotates the display */ + void (*fb_rotate)(struct fb_info *info, int angle); + + /* wait for blit idle, optional */ + int (*fb_sync)(struct fb_info *info); + + /* perform fb specific ioctl (optional) */ + int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg, struct fb_info *info); + + /* Handle 32bit compat ioctl (optional) */ + long (*fb_compat_ioctl)(struct file *f, unsigned cmd, unsigned long arg, + struct fb_info *info); + + /* perform fb specific mmap */ + int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma); + + /* save current hardware state */ + void (*fb_save_state)(struct fb_info *info); + + /* restore saved state */ + void (*fb_restore_state)(struct fb_info *info); +}; + +#ifdef CONFIG_FB_TILEBLITTING + +#define FB_TILE_CURSOR_NONE 0 +#define FB_TILE_CURSOR_UNDERLINE 1 +#define FB_TILE_CURSOR_LOWER_THIRD 2 +#define FB_TILE_CURSOR_LOWER_HALF 3 +#define FB_TILE_CURSOR_TWO_THIRDS 4 +#define FB_TILE_CURSOR_BLOCK 5 + +struct fb_tilemap { + __u32 width; /* width of each tile in pixels */ + __u32 height; /* height of each tile in scanlines */ + __u32 depth; /* color depth of each tile */ + __u32 length; /* number of tiles in the map */ + const __u8 *data; /* actual tile map: a bitmap array, packed + to the nearest byte */ +}; + +struct fb_tilerect { + __u32 sx; /* origin in the x-axis */ + __u32 sy; /* origin in the y-axis */ + __u32 width; /* number of tiles in the x-axis */ + __u32 height; /* number of tiles in the y-axis */ + __u32 index; /* what tile to use: index to tile map */ + __u32 fg; /* foreground color */ + __u32 bg; /* background color */ + __u32 rop; /* raster operation */ +}; + +struct fb_tilearea { + __u32 sx; /* source origin in the x-axis */ + __u32 sy; /* source origin in the y-axis */ + __u32 dx; /* destination origin in the x-axis */ + __u32 dy; /* destination origin in the y-axis */ + __u32 width; /* number of tiles in the x-axis */ + __u32 height; /* number of tiles in the y-axis */ +}; + +struct fb_tileblit { + __u32 sx; /* origin in the x-axis */ + __u32 sy; /* origin in the y-axis */ + __u32 width; /* number of tiles in the x-axis */ + __u32 height; /* number of tiles in the y-axis */ + __u32 fg; /* foreground color */ + __u32 bg; /* background color */ + __u32 length; /* number of tiles to draw */ + __u32 *indices; /* array of indices to tile map */ +}; + +struct fb_tilecursor { + __u32 sx; /* cursor position in the x-axis */ + __u32 sy; /* cursor position in the y-axis */ + __u32 mode; /* 0 = erase, 1 = draw */ + __u32 shape; /* see FB_TILE_CURSOR_* */ + __u32 fg; /* foreground color */ + __u32 bg; /* background color */ +}; + +struct fb_tile_ops { + /* set tile characteristics */ + void (*fb_settile)(struct fb_info *info, struct fb_tilemap *map); + + /* all dimensions from hereon are in terms of tiles */ + + /* move a rectangular region of tiles from one area to another*/ + void (*fb_tilecopy)(struct fb_info *info, struct fb_tilearea *area); + /* fill a rectangular region with a tile */ + void (*fb_tilefill)(struct fb_info *info, struct fb_tilerect *rect); + /* copy an array of tiles */ + void (*fb_tileblit)(struct fb_info *info, struct fb_tileblit *blit); + /* cursor */ + void (*fb_tilecursor)(struct fb_info *info, + struct fb_tilecursor *cursor); +}; +#endif /* CONFIG_FB_TILEBLITTING */ + +/* FBINFO_* = fb_info.flags bit flags */ +#define FBINFO_MODULE 0x0001 /* Low-level driver is a module */ +#define FBINFO_HWACCEL_DISABLED 0x0002 + /* When FBINFO_HWACCEL_DISABLED is set: + * Hardware acceleration is turned off. Software implementations + * of required functions (copyarea(), fillrect(), and imageblit()) + * takes over; acceleration engine should be in a quiescent state */ + +/* hints */ +#define FBINFO_PARTIAL_PAN_OK 0x0040 /* otw use pan only for double-buffering */ +#define FBINFO_READS_FAST 0x0080 /* soft-copy faster than rendering */ + +/* hardware supported ops */ +/* semantics: when a bit is set, it indicates that the operation is + * accelerated by hardware. + * required functions will still work even if the bit is not set. + * optional functions may not even exist if the flag bit is not set. + */ +#define FBINFO_HWACCEL_NONE 0x0000 +#define FBINFO_HWACCEL_COPYAREA 0x0100 /* required */ +#define FBINFO_HWACCEL_FILLRECT 0x0200 /* required */ +#define FBINFO_HWACCEL_IMAGEBLIT 0x0400 /* required */ +#define FBINFO_HWACCEL_ROTATE 0x0800 /* optional */ +#define FBINFO_HWACCEL_XPAN 0x1000 /* optional */ +#define FBINFO_HWACCEL_YPAN 0x2000 /* optional */ +#define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */ + +#define FBINFO_MISC_USEREVENT 0x10000 /* event request + from userspace */ +#define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ + +/* A driver may set this flag to indicate that it does want a set_par to be + * called every time when fbcon_switch is executed. The advantage is that with + * this flag set you can really be shure that set_par is always called before + * any of the functions dependant on the correct hardware state or altering + * that state, even if you are using some broken X releases. The disadvantage + * is that it introduces unwanted delays to every console switch if set_par + * is slow. It is a good idea to try this flag in the drivers initialization + * code whenever there is a bug report related to switching between X and the + * framebuffer console. + */ +#define FBINFO_MISC_ALWAYS_SETPAR 0x40000 + +struct fb_info { + int node; + int flags; + struct fb_var_screeninfo var; /* Current var */ + struct fb_fix_screeninfo fix; /* Current fix */ + struct fb_monspecs monspecs; /* Current Monitor specs */ + struct work_struct queue; /* Framebuffer event queue */ + struct fb_pixmap pixmap; /* Image hardware mapper */ + struct fb_pixmap sprite; /* Cursor hardware mapper */ + struct fb_cmap cmap; /* Current cmap */ + struct list_head modelist; /* mode list */ + struct fb_videomode *mode; /* current mode */ + struct fb_ops *fbops; + struct device *device; + struct class_device *class_device; /* sysfs per device attrs */ +#ifdef CONFIG_FB_TILEBLITTING + struct fb_tile_ops *tileops; /* Tile Blitting */ +#endif + char __iomem *screen_base; /* Virtual address */ + unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ + void *pseudo_palette; /* Fake palette of 16 colors */ +#define FBINFO_STATE_RUNNING 0 +#define FBINFO_STATE_SUSPENDED 1 + u32 state; /* Hardware state i.e suspend */ + void *fbcon_par; /* fbcon use-only private area */ + /* From here on everything is device dependent */ + void *par; +}; + +#ifdef MODULE +#define FBINFO_DEFAULT FBINFO_MODULE +#else +#define FBINFO_DEFAULT 0 +#endif + +// This will go away +#define FBINFO_FLAG_MODULE FBINFO_MODULE +#define FBINFO_FLAG_DEFAULT FBINFO_DEFAULT + +/* This will go away + * fbset currently hacks in FB_ACCELF_TEXT into var.accel_flags + * when it wants to turn the acceleration engine on. This is + * really a separate operation, and should be modified via sysfs. + * But for now, we leave it broken with the following define + */ +#define STUPID_ACCELF_TEXT_SHIT + +// This will go away +#if defined(__sparc__) + +/* We map all of our framebuffers such that big-endian accesses + * are what we want, so the following is sufficient. + */ + +// This will go away +#define fb_readb sbus_readb +#define fb_readw sbus_readw +#define fb_readl sbus_readl +#define fb_readq sbus_readq +#define fb_writeb sbus_writeb +#define fb_writew sbus_writew +#define fb_writel sbus_writel +#define fb_writeq sbus_writeq +#define fb_memset sbus_memset_io + +#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || (defined(__sh__) && !defined(__SH5__)) || defined(__powerpc__) + +#define fb_readb __raw_readb +#define fb_readw __raw_readw +#define fb_readl __raw_readl +#define fb_readq __raw_readq +#define fb_writeb __raw_writeb +#define fb_writew __raw_writew +#define fb_writel __raw_writel +#define fb_writeq __raw_writeq +#define fb_memset memset_io + +#else + +#define fb_readb(addr) (*(volatile u8 *) (addr)) +#define fb_readw(addr) (*(volatile u16 *) (addr)) +#define fb_readl(addr) (*(volatile u32 *) (addr)) +#define fb_readq(addr) (*(volatile u64 *) (addr)) +#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b)) +#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b)) +#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) +#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) +#define fb_memset memset + +#endif + +#if defined (__BIG_ENDIAN) +#define FB_LEFT_POS(bpp) (32 - bpp) +#define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) +#define FB_SHIFT_LOW(val, bits) ((val) << (bits)) +#define FB_BIT_NR(b) (7 - (b)) +#else +#define FB_LEFT_POS(bpp) (0) +#define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) +#define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) +#define FB_BIT_NR(b) (b) +#endif + + /* + * `Generic' versions of the frame buffer device operations + */ + +extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var); +extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var); +extern int fb_blank(struct fb_info *info, int blank); +extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); +extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); +extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image); + +/* drivers/video/fbmem.c */ +extern int register_framebuffer(struct fb_info *fb_info); +extern int unregister_framebuffer(struct fb_info *fb_info); +extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); +extern int fb_show_logo(struct fb_info *fb_info, int rotate); +extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); +extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, + u32 height, u32 shift_high, u32 shift_low, u32 mod); +extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height); +extern void fb_set_suspend(struct fb_info *info, int state); +extern int fb_get_color_depth(struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix); +extern int fb_get_options(char *name, char **option); +extern int fb_new_modelist(struct fb_info *info); +extern int fb_con_duit(struct fb_info *info, int event, void *data); + +extern struct fb_info *registered_fb[FB_MAX]; +extern int num_registered_fb; + +static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, + u8 *src, u32 s_pitch, u32 height) +{ + int i, j; + + d_pitch -= s_pitch; + + for (i = height; i--; ) { + /* s_pitch is a few bytes at the most, memcpy is suboptimal */ + for (j = 0; j < s_pitch; j++) + *dst++ = *src++; + dst += d_pitch; + } +} + +/* drivers/video/fbsysfs.c */ +extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); +extern void framebuffer_release(struct fb_info *info); +extern int fb_init_class_device(struct fb_info *fb_info); +extern void fb_cleanup_class_device(struct fb_info *head); + +/* drivers/video/fbmon.c */ +#define FB_MAXTIMINGS 0 +#define FB_VSYNCTIMINGS 1 +#define FB_HSYNCTIMINGS 2 +#define FB_DCLKTIMINGS 3 +#define FB_IGNOREMON 0x100 + +#define FB_MODE_IS_UNKNOWN 0 +#define FB_MODE_IS_DETAILED 1 +#define FB_MODE_IS_STANDARD 2 +#define FB_MODE_IS_VESA 4 +#define FB_MODE_IS_CALCULATED 8 +#define FB_MODE_IS_FIRST 16 +#define FB_MODE_IS_FROM_VAR 32 + +extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal, + const struct fb_info *fb_info); +extern int fbmon_dpms(const struct fb_info *fb_info); +extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, + struct fb_info *info); +extern int fb_validate_mode(const struct fb_var_screeninfo *var, + struct fb_info *info); +extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var); +extern const unsigned char *fb_firmware_edid(struct device *device); +extern void fb_edid_to_monspecs(unsigned char *edid, + struct fb_monspecs *specs); +extern void fb_destroy_modedb(struct fb_videomode *modedb); +extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); + +/* drivers/video/modedb.c */ +#define VESA_MODEDB_SIZE 34 +extern void fb_var_to_videomode(struct fb_videomode *mode, + struct fb_var_screeninfo *var); +extern void fb_videomode_to_var(struct fb_var_screeninfo *var, + struct fb_videomode *mode); +extern int fb_mode_is_equal(struct fb_videomode *mode1, + struct fb_videomode *mode2); +extern int fb_add_videomode(struct fb_videomode *mode, struct list_head *head); +extern void fb_delete_videomode(struct fb_videomode *mode, + struct list_head *head); +extern struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var, + struct list_head *head); +extern struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var, + struct list_head *head); +extern struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode, + struct list_head *head); +extern void fb_destroy_modelist(struct list_head *head); +extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num, + struct list_head *head); +extern struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs, + struct list_head *head); + +/* drivers/video/fbcmap.c */ +extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); +extern void fb_dealloc_cmap(struct fb_cmap *cmap); +extern int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to); +extern int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to); +extern int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *fb_info); +extern int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *fb_info); +extern struct fb_cmap *fb_default_cmap(int len); +extern void fb_invert_cmaps(void); + +struct fb_videomode { + const char *name; /* optional */ + u32 refresh; /* optional */ + u32 xres; + u32 yres; + u32 pixclock; + u32 left_margin; + u32 right_margin; + u32 upper_margin; + u32 lower_margin; + u32 hsync_len; + u32 vsync_len; + u32 sync; + u32 vmode; + u32 flag; +}; + +extern const struct fb_videomode vesa_modes[]; + +struct fb_modelist { + struct list_head list; + struct fb_videomode mode; +}; + +extern int fb_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, const char *mode_option, + const struct fb_videomode *db, + unsigned int dbsize, + const struct fb_videomode *default_mode, + unsigned int default_bpp); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_FB_H */ diff -urN oldtree/include/linux/sysctl.h newtree/include/linux/sysctl.h --- oldtree/include/linux/sysctl.h 2006-01-03 03:21:10.000000000 +0000 +++ newtree/include/linux/sysctl.h 2006-02-03 18:18:17.100730560 +0000 @@ -146,6 +146,7 @@ KERN_RANDOMIZE=68, /* int: randomize virtual address space */ KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */ KERN_SPIN_RETRY=70, /* int: number of spinlock retries */ + KERN_FBSPLASH=71, /* string: path to fbsplash helper */ }; diff -urN oldtree/include/linux/sysctl.h.orig newtree/include/linux/sysctl.h.orig --- oldtree/include/linux/sysctl.h.orig 1970-01-01 00:00:00.000000000 +0000 +++ newtree/include/linux/sysctl.h.orig 2006-01-03 03:21:10.000000000 +0000 @@ -0,0 +1,983 @@ +/* + * sysctl.h: General linux system control interface + * + * Begun 24 March 1995, Stephen Tweedie + * + **************************************************************** + **************************************************************** + ** + ** The values in this file are exported to user space via + ** the sysctl() binary interface. However this interface + ** is unstable and deprecated and will be removed in the future. + ** For a stable interface use /proc/sys. + ** + **************************************************************** + **************************************************************** + */ + +#ifndef _LINUX_SYSCTL_H +#define _LINUX_SYSCTL_H + +#include +#include +#include + +struct file; +struct completion; + +#define CTL_MAXNAME 10 /* how many path components do we allow in a + call to sysctl? In other words, what is + the largest acceptable value for the nlen + member of a struct __sysctl_args to have? */ + +struct __sysctl_args { + int __user *name; + int nlen; + void __user *oldval; + size_t __user *oldlenp; + void __user *newval; + size_t newlen; + unsigned long __unused[4]; +}; + +/* Define sysctl names first */ + +/* Top-level names: */ + +/* For internal pattern-matching use only: */ +#ifdef __KERNEL__ +#define CTL_ANY -1 /* Matches any name */ +#define CTL_NONE 0 +#endif + +enum +{ + CTL_KERN=1, /* General kernel info and control */ + CTL_VM=2, /* VM management */ + CTL_NET=3, /* Networking */ + CTL_PROC=4, /* Process info */ + CTL_FS=5, /* Filesystems */ + CTL_DEBUG=6, /* Debugging */ + CTL_DEV=7, /* Devices */ + CTL_BUS=8, /* Busses */ + CTL_ABI=9, /* Binary emulation */ + CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +}; + +/* CTL_BUS names: */ +enum +{ + CTL_BUS_ISA=1 /* ISA */ +}; + +/* /proc/sys/fs/inotify/ */ +enum +{ + INOTIFY_MAX_USER_INSTANCES=1, /* max instances per user */ + INOTIFY_MAX_USER_WATCHES=2, /* max watches per user */ + INOTIFY_MAX_QUEUED_EVENTS=3 /* max queued events per instance */ +}; + +/* CTL_KERN names: */ +enum +{ + KERN_OSTYPE=1, /* string: system version */ + KERN_OSRELEASE=2, /* string: system release */ + KERN_OSREV=3, /* int: system revision */ + KERN_VERSION=4, /* string: compile time info */ + KERN_SECUREMASK=5, /* struct: maximum rights mask */ + KERN_PROF=6, /* table: profiling information */ + KERN_NODENAME=7, + KERN_DOMAINNAME=8, + + KERN_CAP_BSET=14, /* int: capability bounding set */ + KERN_PANIC=15, /* int: panic timeout */ + KERN_REALROOTDEV=16, /* real root device to mount after initrd */ + + KERN_SPARC_REBOOT=21, /* reboot command on Sparc */ + KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */ + KERN_PRINTK=23, /* struct: control printk logging parameters */ + KERN_NAMETRANS=24, /* Name translation */ + KERN_PPC_HTABRECLAIM=25, /* turn htab reclaimation on/off on PPC */ + KERN_PPC_ZEROPAGED=26, /* turn idle page zeroing on/off on PPC */ + KERN_PPC_POWERSAVE_NAP=27, /* use nap mode for power saving */ + KERN_MODPROBE=28, + KERN_SG_BIG_BUFF=29, + KERN_ACCT=30, /* BSD process accounting parameters */ + KERN_PPC_L2CR=31, /* l2cr register on PPC */ + + KERN_RTSIGNR=32, /* Number of rt sigs queued */ + KERN_RTSIGMAX=33, /* Max queuable */ + + KERN_SHMMAX=34, /* long: Maximum shared memory segment */ + KERN_MSGMAX=35, /* int: Maximum size of a messege */ + KERN_MSGMNB=36, /* int: Maximum message queue size */ + KERN_MSGPOOL=37, /* int: Maximum system message pool size */ + KERN_SYSRQ=38, /* int: Sysreq enable */ + KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */ + KERN_RANDOM=40, /* Random driver */ + KERN_SHMALL=41, /* int: Maximum size of shared memory */ + KERN_MSGMNI=42, /* int: msg queue identifiers */ + KERN_SEM=43, /* struct: sysv semaphore limits */ + KERN_SPARC_STOP_A=44, /* int: Sparc Stop-A enable */ + KERN_SHMMNI=45, /* int: shm array identifiers */ + KERN_OVERFLOWUID=46, /* int: overflow UID */ + KERN_OVERFLOWGID=47, /* int: overflow GID */ + KERN_SHMPATH=48, /* string: path to shm fs */ + KERN_HOTPLUG=49, /* string: path to hotplug policy agent */ + KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */ + KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */ + KERN_CORE_USES_PID=52, /* int: use core or core.%pid */ + KERN_TAINTED=53, /* int: various kernel tainted flags */ + KERN_CADPID=54, /* int: PID of the process to notify on CAD */ + KERN_PIDMAX=55, /* int: PID # limit */ + KERN_CORE_PATTERN=56, /* string: pattern for core-file names */ + KERN_PANIC_ON_OOPS=57, /* int: whether we will panic on an oops */ + KERN_HPPA_PWRSW=58, /* int: hppa soft-power enable */ + KERN_HPPA_UNALIGNED=59, /* int: hppa unaligned-trap enable */ + KERN_PRINTK_RATELIMIT=60, /* int: tune printk ratelimiting */ + KERN_PRINTK_RATELIMIT_BURST=61, /* int: tune printk ratelimiting */ + KERN_PTY=62, /* dir: pty driver */ + KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */ + KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */ + KERN_HZ_TIMER=65, /* int: hz timer on or off */ + KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */ + KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */ + KERN_RANDOMIZE=68, /* int: randomize virtual address space */ + KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */ + KERN_SPIN_RETRY=70, /* int: number of spinlock retries */ +}; + + +/* CTL_VM names: */ +enum +{ + VM_UNUSED1=1, /* was: struct: Set vm swapping control */ + VM_UNUSED2=2, /* was; int: Linear or sqrt() swapout for hogs */ + VM_UNUSED3=3, /* was: struct: Set free page thresholds */ + VM_UNUSED4=4, /* Spare */ + VM_OVERCOMMIT_MEMORY=5, /* Turn off the virtual memory safety limit */ + VM_UNUSED5=6, /* was: struct: Set buffer memory thresholds */ + VM_UNUSED7=7, /* was: struct: Set cache memory thresholds */ + VM_UNUSED8=8, /* was: struct: Control kswapd behaviour */ + VM_UNUSED9=9, /* was: struct: Set page table cache parameters */ + VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */ + VM_DIRTY_BACKGROUND=11, /* dirty_background_ratio */ + VM_DIRTY_RATIO=12, /* dirty_ratio */ + VM_DIRTY_WB_CS=13, /* dirty_writeback_centisecs */ + VM_DIRTY_EXPIRE_CS=14, /* dirty_expire_centisecs */ + VM_NR_PDFLUSH_THREADS=15, /* nr_pdflush_threads */ + VM_OVERCOMMIT_RATIO=16, /* percent of RAM to allow overcommit in */ + VM_PAGEBUF=17, /* struct: Control pagebuf parameters */ + VM_HUGETLB_PAGES=18, /* int: Number of available Huge Pages */ + VM_SWAPPINESS=19, /* Tendency to steal mapped memory */ + VM_LOWMEM_RESERVE_RATIO=20,/* reservation ratio for lower memory zones */ + VM_MIN_FREE_KBYTES=21, /* Minimum free kilobytes to maintain */ + VM_MAX_MAP_COUNT=22, /* int: Maximum number of mmaps/address-space */ + VM_LAPTOP_MODE=23, /* vm laptop mode */ + VM_BLOCK_DUMP=24, /* block dump mode */ + VM_HUGETLB_GROUP=25, /* permitted hugetlb group */ + VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */ + VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */ + VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */ +}; + + +/* CTL_NET names: */ +enum +{ + NET_CORE=1, + NET_ETHER=2, + NET_802=3, + NET_UNIX=4, + NET_IPV4=5, + NET_IPX=6, + NET_ATALK=7, + NET_NETROM=8, + NET_AX25=9, + NET_BRIDGE=10, + NET_ROSE=11, + NET_IPV6=12, + NET_X25=13, + NET_TR=14, + NET_DECNET=15, + NET_ECONET=16, + NET_SCTP=17, + NET_LLC=18, + NET_NETFILTER=19, +}; + +/* /proc/sys/kernel/random */ +enum +{ + RANDOM_POOLSIZE=1, + RANDOM_ENTROPY_COUNT=2, + RANDOM_READ_THRESH=3, + RANDOM_WRITE_THRESH=4, + RANDOM_BOOT_ID=5, + RANDOM_UUID=6 +}; + +/* /proc/sys/kernel/pty */ +enum +{ + PTY_MAX=1, + PTY_NR=2 +}; + +/* /proc/sys/bus/isa */ +enum +{ + BUS_ISA_MEM_BASE=1, + BUS_ISA_PORT_BASE=2, + BUS_ISA_PORT_SHIFT=3 +}; + +/* /proc/sys/net/core */ +enum +{ + NET_CORE_WMEM_MAX=1, + NET_CORE_RMEM_MAX=2, + NET_CORE_WMEM_DEFAULT=3, + NET_CORE_RMEM_DEFAULT=4, +/* was NET_CORE_DESTROY_DELAY */ + NET_CORE_MAX_BACKLOG=6, + NET_CORE_FASTROUTE=7, + NET_CORE_MSG_COST=8, + NET_CORE_MSG_BURST=9, + NET_CORE_OPTMEM_MAX=10, + NET_CORE_HOT_LIST_LENGTH=11, + NET_CORE_DIVERT_VERSION=12, + NET_CORE_NO_CONG_THRESH=13, + NET_CORE_NO_CONG=14, + NET_CORE_LO_CONG=15, + NET_CORE_MOD_CONG=16, + NET_CORE_DEV_WEIGHT=17, + NET_CORE_SOMAXCONN=18, + NET_CORE_BUDGET=19, +}; + +/* /proc/sys/net/ethernet */ + +/* /proc/sys/net/802 */ + +/* /proc/sys/net/unix */ + +enum +{ + NET_UNIX_DESTROY_DELAY=1, + NET_UNIX_DELETE_DELAY=2, + NET_UNIX_MAX_DGRAM_QLEN=3, +}; + +/* /proc/sys/net/netfilter */ +enum +{ + NET_NF_CONNTRACK_MAX=1, + NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2, + NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3, + NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4, + NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5, + NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6, + NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7, + NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8, + NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9, + NET_NF_CONNTRACK_UDP_TIMEOUT=10, + NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11, + NET_NF_CONNTRACK_ICMP_TIMEOUT=12, + NET_NF_CONNTRACK_GENERIC_TIMEOUT=13, + NET_NF_CONNTRACK_BUCKETS=14, + NET_NF_CONNTRACK_LOG_INVALID=15, + NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16, + NET_NF_CONNTRACK_TCP_LOOSE=17, + NET_NF_CONNTRACK_TCP_BE_LIBERAL=18, + NET_NF_CONNTRACK_TCP_MAX_RETRANS=19, + NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20, + NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21, + NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22, + NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23, + NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24, + NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25, + NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26, + NET_NF_CONNTRACK_COUNT=27, + NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28, + NET_NF_CONNTRACK_FRAG6_TIMEOUT=29, + NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30, + NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31, +}; + +/* /proc/sys/net/ipv4 */ +enum +{ + /* v2.0 compatibile variables */ + NET_IPV4_FORWARD=8, + NET_IPV4_DYNADDR=9, + + NET_IPV4_CONF=16, + NET_IPV4_NEIGH=17, + NET_IPV4_ROUTE=18, + NET_IPV4_FIB_HASH=19, + NET_IPV4_NETFILTER=20, + + NET_IPV4_TCP_TIMESTAMPS=33, + NET_IPV4_TCP_WINDOW_SCALING=34, + NET_IPV4_TCP_SACK=35, + NET_IPV4_TCP_RETRANS_COLLAPSE=36, + NET_IPV4_DEFAULT_TTL=37, + NET_IPV4_AUTOCONFIG=38, + NET_IPV4_NO_PMTU_DISC=39, + NET_IPV4_TCP_SYN_RETRIES=40, + NET_IPV4_IPFRAG_HIGH_THRESH=41, + NET_IPV4_IPFRAG_LOW_THRESH=42, + NET_IPV4_IPFRAG_TIME=43, + NET_IPV4_TCP_MAX_KA_PROBES=44, + NET_IPV4_TCP_KEEPALIVE_TIME=45, + NET_IPV4_TCP_KEEPALIVE_PROBES=46, + NET_IPV4_TCP_RETRIES1=47, + NET_IPV4_TCP_RETRIES2=48, + NET_IPV4_TCP_FIN_TIMEOUT=49, + NET_IPV4_IP_MASQ_DEBUG=50, + NET_TCP_SYNCOOKIES=51, + NET_TCP_STDURG=52, + NET_TCP_RFC1337=53, + NET_TCP_SYN_TAILDROP=54, + NET_TCP_MAX_SYN_BACKLOG=55, + NET_IPV4_LOCAL_PORT_RANGE=56, + NET_IPV4_ICMP_ECHO_IGNORE_ALL=57, + NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS=58, + NET_IPV4_ICMP_SOURCEQUENCH_RATE=59, + NET_IPV4_ICMP_DESTUNREACH_RATE=60, + NET_IPV4_ICMP_TIMEEXCEED_RATE=61, + NET_IPV4_ICMP_PARAMPROB_RATE=62, + NET_IPV4_ICMP_ECHOREPLY_RATE=63, + NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64, + NET_IPV4_IGMP_MAX_MEMBERSHIPS=65, + NET_TCP_TW_RECYCLE=66, + NET_IPV4_ALWAYS_DEFRAG=67, + NET_IPV4_TCP_KEEPALIVE_INTVL=68, + NET_IPV4_INET_PEER_THRESHOLD=69, + NET_IPV4_INET_PEER_MINTTL=70, + NET_IPV4_INET_PEER_MAXTTL=71, + NET_IPV4_INET_PEER_GC_MINTIME=72, + NET_IPV4_INET_PEER_GC_MAXTIME=73, + NET_TCP_ORPHAN_RETRIES=74, + NET_TCP_ABORT_ON_OVERFLOW=75, + NET_TCP_SYNACK_RETRIES=76, + NET_TCP_MAX_ORPHANS=77, + NET_TCP_MAX_TW_BUCKETS=78, + NET_TCP_FACK=79, + NET_TCP_REORDERING=80, + NET_TCP_ECN=81, + NET_TCP_DSACK=82, + NET_TCP_MEM=83, + NET_TCP_WMEM=84, + NET_TCP_RMEM=85, + NET_TCP_APP_WIN=86, + NET_TCP_ADV_WIN_SCALE=87, + NET_IPV4_NONLOCAL_BIND=88, + NET_IPV4_ICMP_RATELIMIT=89, + NET_IPV4_ICMP_RATEMASK=90, + NET_TCP_TW_REUSE=91, + NET_TCP_FRTO=92, + NET_TCP_LOW_LATENCY=93, + NET_IPV4_IPFRAG_SECRET_INTERVAL=94, + NET_IPV4_IGMP_MAX_MSF=96, + NET_TCP_NO_METRICS_SAVE=97, + NET_TCP_DEFAULT_WIN_SCALE=105, + NET_TCP_MODERATE_RCVBUF=106, + NET_TCP_TSO_WIN_DIVISOR=107, + NET_TCP_BIC_BETA=108, + NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, + NET_TCP_CONG_CONTROL=110, + NET_TCP_ABC=111, +}; + +enum { + NET_IPV4_ROUTE_FLUSH=1, + NET_IPV4_ROUTE_MIN_DELAY=2, + NET_IPV4_ROUTE_MAX_DELAY=3, + NET_IPV4_ROUTE_GC_THRESH=4, + NET_IPV4_ROUTE_MAX_SIZE=5, + NET_IPV4_ROUTE_GC_MIN_INTERVAL=6, + NET_IPV4_ROUTE_GC_TIMEOUT=7, + NET_IPV4_ROUTE_GC_INTERVAL=8, + NET_IPV4_ROUTE_REDIRECT_LOAD=9, + NET_IPV4_ROUTE_REDIRECT_NUMBER=10, + NET_IPV4_ROUTE_REDIRECT_SILENCE=11, + NET_IPV4_ROUTE_ERROR_COST=12, + NET_IPV4_ROUTE_ERROR_BURST=13, + NET_IPV4_ROUTE_GC_ELASTICITY=14, + NET_IPV4_ROUTE_MTU_EXPIRES=15, + NET_IPV4_ROUTE_MIN_PMTU=16, + NET_IPV4_ROUTE_MIN_ADVMSS=17, + NET_IPV4_ROUTE_SECRET_INTERVAL=18, + NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS=19, +}; + +enum +{ + NET_PROTO_CONF_ALL=-2, + NET_PROTO_CONF_DEFAULT=-3 + + /* And device ifindices ... */ +}; + +enum +{ + NET_IPV4_CONF_FORWARDING=1, + NET_IPV4_CONF_MC_FORWARDING=2, + NET_IPV4_CONF_PROXY_ARP=3, + NET_IPV4_CONF_ACCEPT_REDIRECTS=4, + NET_IPV4_CONF_SECURE_REDIRECTS=5, + NET_IPV4_CONF_SEND_REDIRECTS=6, + NET_IPV4_CONF_SHARED_MEDIA=7, + NET_IPV4_CONF_RP_FILTER=8, + NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9, + NET_IPV4_CONF_BOOTP_RELAY=10, + NET_IPV4_CONF_LOG_MARTIANS=11, + NET_IPV4_CONF_TAG=12, + NET_IPV4_CONF_ARPFILTER=13, + NET_IPV4_CONF_MEDIUM_ID=14, + NET_IPV4_CONF_NOXFRM=15, + NET_IPV4_CONF_NOPOLICY=16, + NET_IPV4_CONF_FORCE_IGMP_VERSION=17, + NET_IPV4_CONF_ARP_ANNOUNCE=18, + NET_IPV4_CONF_ARP_IGNORE=19, + NET_IPV4_CONF_PROMOTE_SECONDARIES=20, + __NET_IPV4_CONF_MAX +}; + +/* /proc/sys/net/ipv4/netfilter */ +enum +{ + NET_IPV4_NF_CONNTRACK_MAX=1, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9, + NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10, + NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11, + NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12, + NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13, + NET_IPV4_NF_CONNTRACK_BUCKETS=14, + NET_IPV4_NF_CONNTRACK_LOG_INVALID=15, + NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16, + NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17, + NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18, + NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26, + NET_IPV4_NF_CONNTRACK_COUNT=27, +}; + +/* /proc/sys/net/ipv6 */ +enum { + NET_IPV6_CONF=16, + NET_IPV6_NEIGH=17, + NET_IPV6_ROUTE=18, + NET_IPV6_ICMP=19, + NET_IPV6_BINDV6ONLY=20, + NET_IPV6_IP6FRAG_HIGH_THRESH=21, + NET_IPV6_IP6FRAG_LOW_THRESH=22, + NET_IPV6_IP6FRAG_TIME=23, + NET_IPV6_IP6FRAG_SECRET_INTERVAL=24, + NET_IPV6_MLD_MAX_MSF=25, +}; + +enum { + NET_IPV6_ROUTE_FLUSH=1, + NET_IPV6_ROUTE_GC_THRESH=2, + NET_IPV6_ROUTE_MAX_SIZE=3, + NET_IPV6_ROUTE_GC_MIN_INTERVAL=4, + NET_IPV6_ROUTE_GC_TIMEOUT=5, + NET_IPV6_ROUTE_GC_INTERVAL=6, + NET_IPV6_ROUTE_GC_ELASTICITY=7, + NET_IPV6_ROUTE_MTU_EXPIRES=8, + NET_IPV6_ROUTE_MIN_ADVMSS=9, + NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS=10 +}; + +enum { + NET_IPV6_FORWARDING=1, + NET_IPV6_HOP_LIMIT=2, + NET_IPV6_MTU=3, + NET_IPV6_ACCEPT_RA=4, + NET_IPV6_ACCEPT_REDIRECTS=5, + NET_IPV6_AUTOCONF=6, + NET_IPV6_DAD_TRANSMITS=7, + NET_IPV6_RTR_SOLICITS=8, + NET_IPV6_RTR_SOLICIT_INTERVAL=9, + NET_IPV6_RTR_SOLICIT_DELAY=10, + NET_IPV6_USE_TEMPADDR=11, + NET_IPV6_TEMP_VALID_LFT=12, + NET_IPV6_TEMP_PREFERED_LFT=13, + NET_IPV6_REGEN_MAX_RETRY=14, + NET_IPV6_MAX_DESYNC_FACTOR=15, + NET_IPV6_MAX_ADDRESSES=16, + NET_IPV6_FORCE_MLD_VERSION=17, + __NET_IPV6_MAX +}; + +/* /proc/sys/net/ipv6/icmp */ +enum { + NET_IPV6_ICMP_RATELIMIT=1 +}; + +/* /proc/sys/net//neigh/ */ +enum { + NET_NEIGH_MCAST_SOLICIT=1, + NET_NEIGH_UCAST_SOLICIT=2, + NET_NEIGH_APP_SOLICIT=3, + NET_NEIGH_RETRANS_TIME=4, + NET_NEIGH_REACHABLE_TIME=5, + NET_NEIGH_DELAY_PROBE_TIME=6, + NET_NEIGH_GC_STALE_TIME=7, + NET_NEIGH_UNRES_QLEN=8, + NET_NEIGH_PROXY_QLEN=9, + NET_NEIGH_ANYCAST_DELAY=10, + NET_NEIGH_PROXY_DELAY=11, + NET_NEIGH_LOCKTIME=12, + NET_NEIGH_GC_INTERVAL=13, + NET_NEIGH_GC_THRESH1=14, + NET_NEIGH_GC_THRESH2=15, + NET_NEIGH_GC_THRESH3=16, + NET_NEIGH_RETRANS_TIME_MS=17, + NET_NEIGH_REACHABLE_TIME_MS=18, + __NET_NEIGH_MAX +}; + +/* /proc/sys/net/ipx */ +enum { + NET_IPX_PPROP_BROADCASTING=1, + NET_IPX_FORWARDING=2 +}; + +/* /proc/sys/net/llc */ +enum { + NET_LLC2=1, + NET_LLC_STATION=2, +}; + +/* /proc/sys/net/llc/llc2 */ +enum { + NET_LLC2_TIMEOUT=1, +}; + +/* /proc/sys/net/llc/station */ +enum { + NET_LLC_STATION_ACK_TIMEOUT=1, +}; + +/* /proc/sys/net/llc/llc2/timeout */ +enum { + NET_LLC2_ACK_TIMEOUT=1, + NET_LLC2_P_TIMEOUT=2, + NET_LLC2_REJ_TIMEOUT=3, + NET_LLC2_BUSY_TIMEOUT=4, +}; + +/* /proc/sys/net/appletalk */ +enum { + NET_ATALK_AARP_EXPIRY_TIME=1, + NET_ATALK_AARP_TICK_TIME=2, + NET_ATALK_AARP_RETRANSMIT_LIMIT=3, + NET_ATALK_AARP_RESOLVE_TIME=4 +}; + + +/* /proc/sys/net/netrom */ +enum { + NET_NETROM_DEFAULT_PATH_QUALITY=1, + NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER=2, + NET_NETROM_NETWORK_TTL_INITIALISER=3, + NET_NETROM_TRANSPORT_TIMEOUT=4, + NET_NETROM_TRANSPORT_MAXIMUM_TRIES=5, + NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY=6, + NET_NETROM_TRANSPORT_BUSY_DELAY=7, + NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8, + NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9, + NET_NETROM_ROUTING_CONTROL=10, + NET_NETROM_LINK_FAILS_COUNT=11, + NET_NETROM_RESET=12 +}; + +/* /proc/sys/net/ax25 */ +enum { + NET_AX25_IP_DEFAULT_MODE=1, + NET_AX25_DEFAULT_MODE=2, + NET_AX25_BACKOFF_TYPE=3, + NET_AX25_CONNECT_MODE=4, + NET_AX25_STANDARD_WINDOW=5, + NET_AX25_EXTENDED_WINDOW=6, + NET_AX25_T1_TIMEOUT=7, + NET_AX25_T2_TIMEOUT=8, + NET_AX25_T3_TIMEOUT=9, + NET_AX25_IDLE_TIMEOUT=10, + NET_AX25_N2=11, + NET_AX25_PACLEN=12, + NET_AX25_PROTOCOL=13, + NET_AX25_DAMA_SLAVE_TIMEOUT=14 +}; + +/* /proc/sys/net/rose */ +enum { + NET_ROSE_RESTART_REQUEST_TIMEOUT=1, + NET_ROSE_CALL_REQUEST_TIMEOUT=2, + NET_ROSE_RESET_REQUEST_TIMEOUT=3, + NET_ROSE_CLEAR_REQUEST_TIMEOUT=4, + NET_ROSE_ACK_HOLD_BACK_TIMEOUT=5, + NET_ROSE_ROUTING_CONTROL=6, + NET_ROSE_LINK_FAIL_TIMEOUT=7, + NET_ROSE_MAX_VCS=8, + NET_ROSE_WINDOW_SIZE=9, + NET_ROSE_NO_ACTIVITY_TIMEOUT=10 +}; + +/* /proc/sys/net/x25 */ +enum { + NET_X25_RESTART_REQUEST_TIMEOUT=1, + NET_X25_CALL_REQUEST_TIMEOUT=2, + NET_X25_RESET_REQUEST_TIMEOUT=3, + NET_X25_CLEAR_REQUEST_TIMEOUT=4, + NET_X25_ACK_HOLD_BACK_TIMEOUT=5 +}; + +/* /proc/sys/net/token-ring */ +enum +{ + NET_TR_RIF_TIMEOUT=1 +}; + +/* /proc/sys/net/decnet/ */ +enum { + NET_DECNET_NODE_TYPE = 1, + NET_DECNET_NODE_ADDRESS = 2, + NET_DECNET_NODE_NAME = 3, + NET_DECNET_DEFAULT_DEVICE = 4, + NET_DECNET_TIME_WAIT = 5, + NET_DECNET_DN_COUNT = 6, + NET_DECNET_DI_COUNT = 7, + NET_DECNET_DR_COUNT = 8, + NET_DECNET_DST_GC_INTERVAL = 9, + NET_DECNET_CONF = 10, + NET_DECNET_NO_FC_MAX_CWND = 11, + NET_DECNET_MEM = 12, + NET_DECNET_RMEM = 13, + NET_DECNET_WMEM = 14, + NET_DECNET_DEBUG_LEVEL = 255 +}; + +/* /proc/sys/net/decnet/conf/ */ +enum { + NET_DECNET_CONF_LOOPBACK = -2, + NET_DECNET_CONF_DDCMP = -3, + NET_DECNET_CONF_PPP = -4, + NET_DECNET_CONF_X25 = -5, + NET_DECNET_CONF_GRE = -6, + NET_DECNET_CONF_ETHER = -7 + + /* ... and ifindex of devices */ +}; + +/* /proc/sys/net/decnet/conf// */ +enum { + NET_DECNET_CONF_DEV_PRIORITY = 1, + NET_DECNET_CONF_DEV_T1 = 2, + NET_DECNET_CONF_DEV_T2 = 3, + NET_DECNET_CONF_DEV_T3 = 4, + NET_DECNET_CONF_DEV_FORWARDING = 5, + NET_DECNET_CONF_DEV_BLKSIZE = 6, + NET_DECNET_CONF_DEV_STATE = 7 +}; + +/* /proc/sys/net/sctp */ +enum { + NET_SCTP_RTO_INITIAL = 1, + NET_SCTP_RTO_MIN = 2, + NET_SCTP_RTO_MAX = 3, + NET_SCTP_RTO_ALPHA = 4, + NET_SCTP_RTO_BETA = 5, + NET_SCTP_VALID_COOKIE_LIFE = 6, + NET_SCTP_ASSOCIATION_MAX_RETRANS = 7, + NET_SCTP_PATH_MAX_RETRANS = 8, + NET_SCTP_MAX_INIT_RETRANSMITS = 9, + NET_SCTP_HB_INTERVAL = 10, + NET_SCTP_PRESERVE_ENABLE = 11, + NET_SCTP_MAX_BURST = 12, + NET_SCTP_ADDIP_ENABLE = 13, + NET_SCTP_PRSCTP_ENABLE = 14, + NET_SCTP_SNDBUF_POLICY = 15, + NET_SCTP_SACK_TIMEOUT = 16, + NET_SCTP_RCVBUF_POLICY = 17, +}; + +/* /proc/sys/net/bridge */ +enum { + NET_BRIDGE_NF_CALL_ARPTABLES = 1, + NET_BRIDGE_NF_CALL_IPTABLES = 2, + NET_BRIDGE_NF_CALL_IP6TABLES = 3, + NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4, +}; + +/* CTL_PROC names: */ + +/* CTL_FS names: */ +enum +{ + FS_NRINODE=1, /* int:current number of allocated inodes */ + FS_STATINODE=2, + FS_MAXINODE=3, /* int:maximum number of inodes that can be allocated */ + FS_NRDQUOT=4, /* int:current number of allocated dquots */ + FS_MAXDQUOT=5, /* int:maximum number of dquots that can be allocated */ + FS_NRFILE=6, /* int:current number of allocated filedescriptors */ + FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated */ + FS_DENTRY=8, + FS_NRSUPER=9, /* int:current number of allocated super_blocks */ + FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */ + FS_OVERFLOWUID=11, /* int: overflow UID */ + FS_OVERFLOWGID=12, /* int: overflow GID */ + FS_LEASES=13, /* int: leases enabled */ + FS_DIR_NOTIFY=14, /* int: directory notification enabled */ + FS_LEASE_TIME=15, /* int: maximum time to wait for a lease break */ + FS_DQSTATS=16, /* disc quota usage statistics and control */ + FS_XFS=17, /* struct: control xfs parameters */ + FS_AIO_NR=18, /* current system-wide number of aio requests */ + FS_AIO_MAX_NR=19, /* system-wide maximum number of aio requests */ + FS_INOTIFY=20, /* inotify submenu */ +}; + +/* /proc/sys/fs/quota/ */ +enum { + FS_DQ_LOOKUPS = 1, + FS_DQ_DROPS = 2, + FS_DQ_READS = 3, + FS_DQ_WRITES = 4, + FS_DQ_CACHE_HITS = 5, + FS_DQ_ALLOCATED = 6, + FS_DQ_FREE = 7, + FS_DQ_SYNCS = 8, + FS_DQ_WARNINGS = 9, +}; + +/* CTL_DEBUG names: */ + +/* CTL_DEV names: */ +enum { + DEV_CDROM=1, + DEV_HWMON=2, + DEV_PARPORT=3, + DEV_RAID=4, + DEV_MAC_HID=5, + DEV_SCSI=6, + DEV_IPMI=7, +}; + +/* /proc/sys/dev/cdrom */ +enum { + DEV_CDROM_INFO=1, + DEV_CDROM_AUTOCLOSE=2, + DEV_CDROM_AUTOEJECT=3, + DEV_CDROM_DEBUG=4, + DEV_CDROM_LOCK=5, + DEV_CDROM_CHECK_MEDIA=6 +}; + +/* /proc/sys/dev/parport */ +enum { + DEV_PARPORT_DEFAULT=-3 +}; + +/* /proc/sys/dev/raid */ +enum { + DEV_RAID_SPEED_LIMIT_MIN=1, + DEV_RAID_SPEED_LIMIT_MAX=2 +}; + +/* /proc/sys/dev/parport/default */ +enum { + DEV_PARPORT_DEFAULT_TIMESLICE=1, + DEV_PARPORT_DEFAULT_SPINTIME=2 +}; + +/* /proc/sys/dev/parport/parport n */ +enum { + DEV_PARPORT_SPINTIME=1, + DEV_PARPORT_BASE_ADDR=2, + DEV_PARPORT_IRQ=3, + DEV_PARPORT_DMA=4, + DEV_PARPORT_MODES=5, + DEV_PARPORT_DEVICES=6, + DEV_PARPORT_AUTOPROBE=16 +}; + +/* /proc/sys/dev/parport/parport n/devices/ */ +enum { + DEV_PARPORT_DEVICES_ACTIVE=-3, +}; + +/* /proc/sys/dev/parport/parport n/devices/device n */ +enum { + DEV_PARPORT_DEVICE_TIMESLICE=1, +}; + +/* /proc/sys/dev/mac_hid */ +enum { + DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES=1, + DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES=2, + DEV_MAC_HID_MOUSE_BUTTON_EMULATION=3, + DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4, + DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5, + DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6 +}; + +/* /proc/sys/dev/scsi */ +enum { + DEV_SCSI_LOGGING_LEVEL=1, +}; + +/* /proc/sys/dev/ipmi */ +enum { + DEV_IPMI_POWEROFF_POWERCYCLE=1, +}; + +/* /proc/sys/abi */ +enum +{ + ABI_DEFHANDLER_COFF=1, /* default handler for coff binaries */ + ABI_DEFHANDLER_ELF=2, /* default handler for ELF binaries */ + ABI_DEFHANDLER_LCALL7=3,/* default handler for procs using lcall7 */ + ABI_DEFHANDLER_LIBCSO=4,/* default handler for an libc.so ELF interp */ + ABI_TRACE=5, /* tracing flags */ + ABI_FAKE_UTSNAME=6, /* fake target utsname information */ +}; + +#ifdef __KERNEL__ +#include + +extern void sysctl_init(void); + +typedef struct ctl_table ctl_table; + +typedef int ctl_handler (ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, + void **context); + +typedef int proc_handler (ctl_table *ctl, int write, struct file * filp, + void __user *buffer, size_t *lenp, loff_t *ppos); + +extern int proc_dostring(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_dointvec(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_dointvec_bset(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_dointvec_minmax(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_dointvec_jiffies(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_doulongvec_minmax(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int, + struct file *, void __user *, size_t *, loff_t *); + +extern int do_sysctl (int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen); + +extern int do_sysctl_strategy (ctl_table *table, + int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void ** context); + +extern ctl_handler sysctl_string; +extern ctl_handler sysctl_intvec; +extern ctl_handler sysctl_jiffies; +extern ctl_handler sysctl_ms_jiffies; + + +/* + * Register a set of sysctl names by calling register_sysctl_table + * with an initialised array of ctl_table's. An entry with zero + * ctl_name terminates the table. table->de will be set up by the + * registration and need not be initialised in advance. + * + * sysctl names can be mirrored automatically under /proc/sys. The + * procname supplied controls /proc naming. + * + * The table's mode will be honoured both for sys_sysctl(2) and + * proc-fs access. + * + * Leaf nodes in the sysctl tree will be represented by a single file + * under /proc; non-leaf nodes will be represented by directories. A + * null procname disables /proc mirroring at this node. + * + * sysctl(2) can automatically manage read and write requests through + * the sysctl table. The data and maxlen fields of the ctl_table + * struct enable minimal validation of the values being written to be + * performed, and the mode field allows minimal authentication. + * + * More sophisticated management can be enabled by the provision of a + * strategy routine with the table entry. This will be called before + * any automatic read or write of the data is performed. + * + * The strategy routine may return: + * <0: Error occurred (error is passed to user process) + * 0: OK - proceed with automatic read or write. + * >0: OK - read or write has been done by the strategy routine, so + * return immediately. + * + * There must be a proc_handler routine for any terminal nodes + * mirrored under /proc/sys (non-terminals are handled by a built-in + * directory handler). Several default handlers are available to + * cover common cases. + */ + +/* A sysctl table is an array of struct ctl_table: */ +struct ctl_table +{ + int ctl_name; /* Binary ID */ + const char *procname; /* Text ID for /proc/sys, or zero */ + void *data; + int maxlen; + mode_t mode; + ctl_table *child; + proc_handler *proc_handler; /* Callback for text formatting */ + ctl_handler *strategy; /* Callback function for all r/w */ + struct proc_dir_entry *de; /* /proc control block */ + void *extra1; + void *extra2; +}; + +/* struct ctl_table_header is used to maintain dynamic lists of + ctl_table trees. */ +struct ctl_table_header +{ + ctl_table *ctl_table; + struct list_head ctl_entry; + int used; + struct completion *unregistering; +}; + +struct ctl_table_header * register_sysctl_table(ctl_table * table, + int insert_at_head); +void unregister_sysctl_table(struct ctl_table_header * table); + +#else /* __KERNEL__ */ + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_SYSCTL_H */ diff -urN oldtree/kernel/sysctl.c newtree/kernel/sysctl.c --- oldtree/kernel/sysctl.c 2006-01-03 03:21:10.000000000 +0000 +++ newtree/kernel/sysctl.c 2006-02-03 18:18:17.102730256 +0000 @@ -86,6 +86,9 @@ #ifdef CONFIG_HOTPLUG extern char hotplug_path[]; #endif +#ifdef CONFIG_FB_SPLASH +extern char fbsplash_path[]; +#endif #ifdef CONFIG_CHR_DEV_SG extern int sg_big_buff; #endif @@ -404,6 +407,17 @@ .strategy = &sysctl_string, }, #endif +#ifdef CONFIG_FB_SPLASH + { + .ctl_name = KERN_FBSPLASH, + .procname = "fbsplash", + .data = &fbsplash_path, + .maxlen = KMOD_PATH_LEN, + .mode = 0644, + .proc_handler = &proc_dostring, + .strategy = &sysctl_string, + }, +#endif #ifdef CONFIG_CHR_DEV_SG { .ctl_name = KERN_SG_BIG_BUFF,