]> git.pld-linux.org Git - packages/kernel.git/blame - fbsplash-0.9-r6-2.6.8.1.patch
- obsolete
[packages/kernel.git] / fbsplash-0.9-r6-2.6.8.1.patch
CommitLineData
3b9d5c1c 1diff -Nru a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
2--- a/Documentation/fb/00-INDEX 2004-08-23 11:56:23 +02:00
3+++ b/Documentation/fb/00-INDEX 2004-08-23 11:56:23 +02:00
4@@ -19,6 +19,8 @@
5 - info on the Matrox frame buffer driver
6 pvr2fb.txt
7 - info on the PowerVR 2 frame buffer driver
8+splash.txt
9+ - info on the Framebuffer Splash
10 tgafb.txt
11 - info on the TGA (DECChip 21030) frame buffer driver
12 vesafb.txt
13diff -Nru a/Documentation/fb/splash.txt b/Documentation/fb/splash.txt
14--- /dev/null Wed Dec 31 16:00:00 196900
15+++ b/Documentation/fb/splash.txt 2004-08-23 11:56:23 +02:00
16@@ -0,0 +1,230 @@
17+What is it?
18+-----------
19+
20+The framebuffer splash is a kernel feature that allows displaying a background
21+picture on selected consoles and switching the first console to the so-called
22+silent mode, while booting/rebooting/shutting down the system.
23+
24+What do I need to get it to work?
25+---------------------------------
26+
27+To get fb splash up-and-running you will have to:
28+ 1) get a copy of splashutils from (FIXME URL)
29+ 2) get some splash themes (FIXME URL)
30+ 3) build the kernel helper program
31+ 4) build your kernel with the FB_SPLASH option enabled.
32+
33+To get fb splash operational right after fbcon initialization is finished, you
34+will have to include a theme and the kernel helper into your initramfs image.
35+Please refer to splashutils documentation for instructions on how to do that.
36+
37+Operation modes
38+---------------
39+
40+The framebuffer splash can work in two modes: verbose and silent. The first
41+one means "console with a background image". The latter one is a concept
42+first introduced in bootsplash. When silent mode is active, the console is
43+switched to a graphic mode and no text is displayed. It's up to the userspace
44+programs to display something (a progress bar for example) on the screen.
45+
46+Kernel command line parameters
47+------------------------------
48+
49+Framebuffer splash can be configured from the kernel command line by passing
50+options in the following way: "splash=option1,option2".
51+
52+The following options are recognized:
53+
54+off - do not enable fbsplash after fbcon initialization; this is
55+ default behaviour
56+verbose - switch fbsplash to verbose mode after fbcon is initialized
57+silent - switch fbsplash to silent mode after fbcon is initialized
58+
59+theme:<name> - use theme 'name' on the first console, default theme name
60+ is 'default' (who'd have guessed?)
61+
62+Example - you want to get verbose splash with the theme 'tux' right after
63+fbcon is up:
64+ splash=verbose,theme:tux
65+
66+The userspace helper
67+--------------------
68+
69+The userspace splash helper (by default: /sbin/splash_helper) is called by the
70+kernel whenever an important event occurs and the kernel needs some kind of
71+job to be carried out. Important events include console switches and graphic
72+mode switches (the kernel requests background images and config for the current
73+console). The splash helper must be accessible at all times. If it's not,
74+fbsplash will be switched off automatically.
75+
76+It's possible to set path to the splash helper by writing it to
77+/proc/sys/kernel/fbsplash.
78+
79+*****************************************************************************
80+
81+The information below is mostly technical stuff. If you don't plan to develop
82+something fbsplash-related, there's probably no need to read it.
83+
84+The splash protocol
85+-------------------
86+
87+The splash protocol defines a communication interface between the kernel and
88+the userspace splash helper.
89+
90+The kernel side is responsible for:
91+
92+ o rendering console text, using an image as a background (instead of a
93+ standard solid color fbcon uses),
94+ o accepting commands from the user via ioctls on the fbsplash device,
95+ o calling the userspace helper to set things up as soon as the fb subsystem is
96+ initialized.
97+
98+The userspace helper is responsible for everything else, including parsing
99+configuration files, decompressing the image files whenever the kernel needs
100+it, and communicating with the kernel if necessary.
101+
102+The splash protocol specifies how communication is done in both ways:
103+kernel->userspace and userspace->helper.
104+
105+Kernel -> Userspace
106+-------------------
107+
108+The kernel communicates with the userspace helper by calling it and specifying
109+the task that to be done in a series of arguments.
110+
111+The arguments follow the pattern:
112+<splash protocol version> <command> <parameters>
113+
114+All commands defined in splash protocol v1 have the following parameters:
115+ virtual console
116+ framebuffer number
117+ splash mode - 'v' indicates verbose, 's' indicates silent
118+ theme
119+
120+Splash protocol v1 specifies the following commands:
121+
122+getpic
123+------
124+ The kernel issues this command to request image data. It's up to the userspace
125+ helper to find a background image appropriate for the specified theme and the
126+ current resolution. The userspace helper should respond by issuing the
127+ FBIOSPLASH_SETPIC ioctl.
128+
129+init
130+----
131+ The kernel issues this command if either 'verbose' or 'silent' has been
132+ specified in splash= on the kernel command line. Upon receiving this command,
133+ the userspace helper should find a proper configuration file for the
134+ specified theme and the current resolution, and issue the FBIOSPLASH_SETCFG.
135+ FBIOSPLASH_SETPIC and FBIOSPLASH_SETSTATE commands.
136+
137+ When the userspace helper is called in an early phase of the boot process
138+ (right after the initialization of fbcon), no filesystems will be mounted.
139+ The helper program should mount sysfs and then create the appropriate
140+ framebuffer, fbsplash and tty0 devices (if they don't already exist) to get
141+ current display settings and to be able to communicate with the kernel side.
142+
143+ Note that the console sem is not held when the kernel calls splash_helper
144+ with the 'init' command. The splash helper should perform all ioctls with
145+ origin set to FB_SPLASH_IO_ORIG_USER.
146+
147+modechange
148+----------
149+ The kernel issues this command on a mode change. The helper's response should
150+ be similar to the response to the 'init' command. Note that this time the
151+ console sem is held and all ioctls must be performed with origin set to
152+ FB_SPLASH_IO_ORIG_KERNEL.
153+
154+
155+Userspace -> Kernel
156+-------------------
157+
158+Userspace programs can communicate with the kernel side via ioctls on the
159+on the fbsplash device. These ioctls are to be used by both the userspace helper
160+(called only by the kernel) and userspace configuration tools (run by the users).
161+The splash helper should set the origin field to FB_SPLASH_IO_ORIG_KERNEL when
162+doing the appropriate ioctls. All userspace configuration tools should use
163+FB_SPLASH_IO_ORIG_USER. Failure to set the appropriate value in the origin
164+field when performing ioctls from the kernel helper may result in a deadlock.
165+
166+The framebuffer splash provides the following ioctls (all defined in linux/fb.h):
167+
168+FBIOSPLASH_SETMODE
169+description: sets the global fbsplash mode
170+argument: unsigned int; values: FB_SPLASH_MODE_VERBOSE, FB_SPLASH_MODE_SILENT
171+
172+FBIOSPLASH_GETMODE
173+description: gets the global fbsplash mode
174+argument: unsigned int*; values as in FBIOSPLASH_SETMODE
175+
176+FBIOSPLASH_SETPIC
177+description: loads a background picture for a virtual console
178+argument: struct fb_splash_iowrapper*; data: struct fb_image*
179+notes:
180+If called for consoles other than the current foreground one, the picture data
181+will be ignored.
182+
183+If the current virtual console is running in a 8-bpp mode, the cmap substruct
184+of fb_image has to be filled appropriately: start should be set to 16 (first 16
185+colors are reserved for fbcon), len to a value <= 240 and red, green and blue
186+should point to valid cmap data. The transp field is ingored. The fields dx, dy
187+bg_color, fg_color in fb_image are ignored as well.
188+
189+FBIOSPLASH_SETCFG
190+description: sets the fbsplash config for a virtual console
191+argument: struct fb_splash_iowrapper*; data: struct vc_splash*;
192+ the structure has to be filled with valid data.
193+
194+FBIOSPLASH_GETCFG
195+description: gets the fbsplash config for a virtual console
196+argument: struct fb_splash_iowrapper*; data: struct vc_splash*
197+
198+FBIOSPLASH_SETSTATE
199+description: sets the fbsplash state for a virtual console
200+argument: struct fb_splash_iowrapper*; data: unsigned int*
201+ values: 0 = disabled, 1 = enabled.
202+
203+FBIOSPLASH_GETSTATE
204+description: gets the fbsplash state for a virtual console
205+argument: struct fb_splash_iowrapper*; data: unsigned int*
206+ values: as in FBIOSPLASH_SETSTATE
207+
208+Info on used structures:
209+
210+Definition of struct vc_splash can be found in linux/console_splash.h, it's
211+heavily commented, so no special descriptions are necessary. Note that
212+the 'theme' field should point to a string no longer than FB_SPLASH_THEME_LEN.
213+When FBIOSPLASH_GETCFG call is performed, the theme field should point to a
214+char buffer of length FB_SPLASH_THEME_LEN.
215+
216+Definition of struct fb_splash_iowrapper can be found in linux/fb.h.
217+The fields in this struct have the following meaning:
218+
219+vc:
220+Virtual console number.
221+
222+origin:
223+Specifies if the ioctl is performed as a response to a kernel request. The
224+splash helper should set this field to FB_SPLASH_IO_ORIG_KERNEL, userspace
225+programs should set it to FB_SPLASH_IO_ORIG_USER. This field is necessary to
226+avoid console semaphore deadlocks.
227+
228+data:
229+Pointer to a data structure appropriate for the performed ioctl. Type of
230+the data struct is specified in the ioctls description, for example 'data:
231+struct vc_splash*' means that the 'data' field should be a pointer to a
232+vc_splash struct.
233+
234+*****************************************************************************
235+
236+Credit
237+------
238+
239+Original idea & implementation by:
240+ Volker Poplawski <volker@poplawski.de>, Stefan Reinauer <stepan@suse.de>,
241+ Steffen Winterfeldt <snwint@suse.de>, Michael Schroeder <mls@suse.de>,
242+ Ken Wimer <wimer@suse.de>.
243+
244+Splash protocol redesign, current implementation, docs by:
245+ Michal Januszewski <spock@gentoo.org>
246+
247diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
248--- a/drivers/char/keyboard.c 2004-08-23 11:56:23 +02:00
249+++ b/drivers/char/keyboard.c 2004-08-23 11:56:23 +02:00
250@@ -41,6 +41,8 @@
251 #include <linux/sysrq.h>
252 #include <linux/input.h>
253
254+#include "../video/fbsplash.h"
255+
256 static void kbd_disconnect(struct input_handle *handle);
257 extern void ctrl_alt_del(void);
258
259@@ -1057,6 +1059,12 @@
260 if (emulate_raw(vc, keycode, !down << 7))
261 if (keycode < BTN_MISC)
262 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
263+
264+ /* switch splash to verbose mode if ESC or F2 is pressed */
265+ if (down == 1 && (keycode == KEY_ESC || keycode == KEY_F2)) {
266+ if (fbsplash_verbose())
267+ return;
268+ }
269
270 #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
271 if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
272diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
273--- a/drivers/char/n_tty.c 2004-08-23 11:56:23 +02:00
274+++ b/drivers/char/n_tty.c 2004-08-23 11:56:23 +02:00
275@@ -49,6 +49,8 @@
276 #include <asm/system.h>
277 #include <asm/bitops.h>
278
279+#include "../video/fbsplash.h"
280+
281 /* number of characters left in xmit buffer before select has we have room */
282 #define WAKEUP_CHARS 256
283
284@@ -987,6 +989,15 @@
285 if (!tty->read_buf) {
286 printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
287 return -EIO;
288+ }
289+
290+ /* automatically switch splash to verbose mode if someone tries to
291+ read from tty0 */
292+ if (file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,0) ||
293+ file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1) ||
294+ file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) ||
295+ file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,1)) {
296+ fbsplash_verbose();
297 }
298
299 /* Job control check -- must be done at start and after
300diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
301--- a/drivers/video/Kconfig 2004-08-23 11:56:23 +02:00
302+++ b/drivers/video/Kconfig 2004-08-23 11:56:23 +02:00
303@@ -1002,5 +1002,15 @@
304 source "drivers/video/logo/Kconfig"
305 endif
306
307-endmenu
308+config FB_SPLASH
309+ bool "Support for the framebuffer splash"
310+ depends on FRAMEBUFFER_CONSOLE=y
311+ default n
312+ ---help---
313+ This option enables support for the Linux boot-up splash screen and
314+ graphical backgrounds on consoles. Note that you will need userspace
315+ splashutils in order to take advantage of these features. Refer to
316+ Documentation/fb/splash.txt for more information.
317
318+ If unsure, say N.
319+endmenu
320diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
321--- a/drivers/video/Makefile 2004-08-23 11:56:23 +02:00
322+++ b/drivers/video/Makefile 2004-08-23 11:56:23 +02:00
323@@ -6,6 +6,7 @@
324
325 obj-$(CONFIG_VT) += console/
326 obj-$(CONFIG_LOGO) += logo/
327+obj-$(CONFIG_FB_SPLASH) += fbsplash.o cfbsplash.o
328
329 obj-$(CONFIG_FB) += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
330 # Only include macmodes.o if we have FB support and are PPC
331diff -Nru a/drivers/video/cfbsplash.c b/drivers/video/cfbsplash.c
332--- /dev/null Wed Dec 31 16:00:00 196900
333+++ b/drivers/video/cfbsplash.c 2004-08-23 11:56:23 +02:00
334@@ -0,0 +1,471 @@
335+/*
336+ * linux/drivers/video/cfbsplash.c -- Framebuffer splash render functions
337+ *
338+ * Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
339+ *
340+ * Code based upon "Bootsplash" (C) 2001-2003
341+ * Volker Poplawski <volker@poplawski.de>,
342+ * Stefan Reinauer <stepan@suse.de>,
343+ * Steffen Winterfeldt <snwint@suse.de>,
344+ * Michael Schroeder <mls@suse.de>,
345+ * Ken Wimer <wimer@suse.de>.
346+ *
347+ * This file is subject to the terms and conditions of the GNU General Public
348+ * License. See the file COPYING in the main directory of this archive for
349+ * more details.
350+ */
351+#include <linux/config.h>
352+#include <linux/module.h>
353+#include <linux/types.h>
354+#include <linux/fb.h>
355+#include <linux/vt_kern.h>
356+#include <asm/irq.h>
357+#include <asm/system.h>
358+
359+#include "console/fbcon.h"
360+#include "fbsplash.h"
361+
362+#define parse_pixel(shift,bpp,type) \
363+ do { \
364+ if (d & (0x80 >> (shift))) \
365+ dd2[(shift)] = fgx; \
366+ else \
367+ dd2[(shift)] = transparent ? *(type *)splash_src : bgx; \
368+ splash_src += (bpp); \
369+ } while (0) \
370+
371+void fbsplash_renderc(struct fb_info *info, int ypos, int xpos, int height,
372+ int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
373+{
374+ unsigned int x, y;
375+ u32 dd;
376+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
377+ unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
378+ u16 dd2[4];
379+
380+ u8* splash_src = (u8 *)(info->splash.data + d);
381+ u8* dst = (u8 *)(info->screen_base + d);
382+
383+ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
384+ return;
385+
386+ for (y = 0; y < height; y++) {
387+ switch (info->var.bits_per_pixel) {
388+
389+ case 32:
390+ for (x = 0; x < width; x++) {
391+
392+ if ((x & 7) == 0)
393+ d = *src++;
394+ if (d & 0x80)
395+ dd = fgx;
396+ else
397+ dd = transparent ?
398+ *(u32 *)splash_src : bgx;
399+
400+ d <<= 1;
401+ splash_src += 4;
402+ fb_writel(dd, dst);
403+ dst += 4;
404+ }
405+ break;
406+ case 24:
407+ for (x = 0; x < width; x++) {
408+
409+ if ((x & 7) == 0)
410+ d = *src++;
411+ if (d & 0x80)
412+ dd = fgx;
413+ else
414+ dd = transparent ?
415+ (*(u32 *)splash_src & 0xffffff) : bgx;
416+
417+ d <<= 1;
418+ splash_src += 3;
419+#ifdef __LITTLE_ENDIAN
420+ fb_writew(dd & 0xffff, dst);
421+ dst += 2;
422+ fb_writeb((dd >> 16), dst);
423+#else
424+ fb_writew(dd >> 8, dst);
425+ dst += 2;
426+ fb_writeb(dd & 0xff, dst);
427+#endif
428+ dst++;
429+ }
430+ break;
431+ case 16:
432+ for (x = 0; x < width; x += 2) {
433+ if ((x & 7) == 0)
434+ d = *src++;
435+
436+ parse_pixel(0, 2, u16);
437+ parse_pixel(1, 2, u16);
438+#ifdef __LITTLE_ENDIAN
439+ dd = dd2[0] | (dd2[1] << 16);
440+#else
441+ dd = dd2[1] | (dd2[1] << 16);
442+#endif
443+ d <<= 2;
444+ fb_writel(dd, dst);
445+ dst += 4;
446+ }
447+ break;
448+
449+ case 8:
450+ for (x = 0; x < width; x += 4) {
451+ if ((x & 7) == 0)
452+ d = *src++;
453+
454+ parse_pixel(0, 1, u8);
455+ parse_pixel(1, 1, u8);
456+ parse_pixel(2, 1, u8);
457+ parse_pixel(3, 1, u8);
458+
459+#ifdef __LITTLE_ENDIAN
460+ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
461+#else
462+ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
463+#endif
464+ d <<= 4;
465+ fb_writel(dd, dst);
466+ dst += 4;
467+ }
468+ }
469+
470+ d = info->fix.line_length - width * bytespp;
471+ dst += d;
472+ splash_src += d;
473+ }
474+}
475+
476+#define cc2cx(a) \
477+ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \
478+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \
479+ ((u32*)info->pseudo_palette)[a] : a)
480+
481+void fbsplash_putcs(struct vc_data *vc, struct fb_info *info,
482+ const unsigned short *s, int count, int yy, int xx)
483+{
484+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
485+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
486+ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
487+ int fg_color, bg_color, transparent;
488+
489+ u8 *src;
490+ u32 bgx, fgx;
491+
492+ u16 c = scr_readw(s);
493+
494+ fg_color = attr_fgcol(fgshift, c);
495+ bg_color = attr_bgcol(bgshift, c);
496+ transparent = vc->vc_splash.bg_color == bg_color;
497+
498+ xx = xx * vc->vc_font.width + vc->vc_splash.tx;
499+ yy = yy * vc->vc_font.height + vc->vc_splash.ty;
500+
501+ fgx = cc2cx(fg_color);
502+ bgx = cc2cx(bg_color);
503+
504+ while (count--) {
505+ c = scr_readw(s++);
506+ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
507+ ((vc->vc_font.width + 7) >> 3);
508+
509+ fbsplash_renderc(info, yy, xx, vc->vc_font.height,
510+ vc->vc_font.width, src, fgx, bgx, transparent);
511+ xx += vc->vc_font.width;
512+ }
513+}
514+
515+void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c,
516+ int ypos, int xpos)
517+{
518+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
519+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
520+ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
521+ u32 bg_color = attr_bgcol(bgshift, c);
522+ u32 fg_color = attr_fgcol(fgshift, c);
523+ u8 *src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
524+ ((vc->vc_font.width + 7) >> 3);
525+ xpos = xpos * vc->vc_font.width + vc->vc_splash.tx;
526+ ypos = ypos * vc->vc_font.height + vc->vc_splash.ty;
527+
528+ fbsplash_renderc(info, ypos, xpos, vc->vc_font.height, vc->vc_font.width,
529+ src, cc2cx(fg_color), cc2cx(bg_color),
530+ vc->vc_splash.bg_color == bg_color);
531+}
532+
533+void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor)
534+{
535+ int i;
536+ unsigned int dsize, s_pitch;
537+ char *t = (char *)info->cursor.image.data;
538+ struct vc_data* vc;
539+
540+ vc = vc_cons[info->currcon].d;
541+
542+ if (cursor->set & FB_CUR_SETSIZE) {
543+ info->cursor.image.height = cursor->image.height;
544+ info->cursor.image.width = cursor->image.width;
545+ }
546+ if (cursor->set & FB_CUR_SETPOS) {
547+ info->cursor.image.dx = cursor->image.dx;
548+ info->cursor.image.dy = cursor->image.dy;
549+ }
550+ if (cursor->set & FB_CUR_SETHOT)
551+ info->cursor.hot = cursor->hot;
552+ if (cursor->set & FB_CUR_SETCMAP) {
553+ if (cursor->image.depth == 1) {
554+ info->cursor.image.bg_color = cursor->image.bg_color;
555+ info->cursor.image.fg_color = cursor->image.fg_color;
556+ } else {
557+ if (cursor->image.cmap.len)
558+ fb_copy_cmap(&cursor->image.cmap,
559+ &info->cursor.image.cmap);
560+ }
561+ info->cursor.image.depth = cursor->image.depth;
562+ }
563+ s_pitch = (info->cursor.image.width + 7) >> 3;
564+ dsize = s_pitch * info->cursor.image.height;
565+ if (info->cursor.enable) {
566+ switch (info->cursor.rop) {
567+ case ROP_XOR:
568+ for (i = 0; i < dsize; i++)
569+ t[i] = cursor->image.data[i] ^ info->cursor.mask[i];
570+ break;
571+ case ROP_COPY:
572+ default:
573+ for (i = 0; i < dsize; i++)
574+ t[i] = cursor->image.data[i] & info->cursor.mask[i];
575+ break;
576+ }
577+ } else if (t != cursor->image.data)
578+ memcpy(t, cursor->image.data, dsize);
579+
580+ fbsplash_renderc(info,
581+ info->cursor.image.dy + vc->vc_splash.ty,
582+ info->cursor.image.dx + vc->vc_splash.tx,
583+ info->cursor.image.height,
584+ info->cursor.image.width,
585+ (u8*)info->cursor.image.data,
586+ cc2cx(info->cursor.image.fg_color),
587+ cc2cx(info->cursor.image.bg_color),
588+ info->cursor.image.bg_color == vc->vc_splash.bg_color);
589+}
590+
591+static void splashset(u8 *dst, int height, int width, int dstbytes,
592+ u32 bgx, int bpp)
593+{
594+ int i;
595+
596+ if (bpp == 8)
597+ bgx |= bgx << 8;
598+ if (bpp == 16 || bpp == 8)
599+ bgx |= bgx << 16;
600+
601+ while (height-- > 0) {
602+ u8 *p = dst;
603+
604+ switch (bpp) {
605+
606+ case 32:
607+ for (i=0; i < width; i++) {
608+ fb_writel(bgx, p); p += 4;
609+ }
610+ break;
611+ case 24:
612+ for (i=0; i < width; i++) {
613+#ifdef __LITTLE_ENDIAN
614+ fb_writew((bgx & 0xffff),(u16*)p); p += 2;
615+ fb_writeb((bgx >> 16),p++);
616+#else
617+ fb_writew((bgx >> 8),(u16*)p); p += 2;
618+ fb_writeb((bgx & 0xff),p++);
619+#endif
620+ }
621+ case 16:
622+ for (i=0; i < width/4; i++) {
623+ fb_writel(bgx,p); p += 4;
624+ fb_writel(bgx,p); p += 4;
625+ }
626+ if (width & 2) {
627+ fb_writel(bgx,p); p += 4;
628+ }
629+ if (width & 1)
630+ fb_writew(bgx,(u16*)p);
631+ break;
632+ case 8:
633+ for (i=0; i < width/4; i++) {
634+ fb_writel(bgx,p); p += 4;
635+ }
636+
637+ if (width & 2) {
638+ fb_writew(bgx,p); p += 2;
639+ }
640+ if (width & 1)
641+ fb_writeb(bgx,(u8*)p);
642+ break;
643+
644+ }
645+ dst += dstbytes;
646+ }
647+}
648+
649+void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
650+ int bpp)
651+{
652+ int i;
653+
654+ while (height-- > 0) {
655+ u32 *p = (u32 *)dst;
656+ u32 *q = (u32 *)src;
657+
658+ switch (bpp) {
659+
660+ case 32:
661+ for (i=0; i < width; i++)
662+ fb_writel(*q++, p++);
663+ break;
664+ case 24:
665+ for (i=0; i < (width*3/4); i++)
666+ fb_writel(*q++, p++);
667+ if ((width*3) % 4) {
668+ if (width & 2) {
669+ fb_writeb(*(u8*)q, (u8*)p);
670+ } else if (width & 1) {
671+ fb_writew(*(u16*)q, (u16*)p);
672+ fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
673+ }
674+ }
675+ break;
676+ case 16:
677+ for (i=0; i < width/4; i++) {
678+ fb_writel(*q++, p++);
679+ fb_writel(*q++, p++);
680+ }
681+ if (width & 2)
682+ fb_writel(*q++, p++);
683+ if (width & 1)
684+ fb_writew(*(u16*)q, (u16*)p);
685+ break;
686+ case 8:
687+ for (i=0; i < width/4; i++)
688+ fb_writel(*q++, p++);
689+
690+ if (width & 2) {
691+ fb_writew(*(u16*)q, (u16*)p);
692+ q = (u32*) ((u16*)q + 1);
693+ p = (u32*) ((u16*)p + 1);
694+ }
695+ if (width & 1)
696+ fb_writeb(*(u8*)q, (u8*)p);
697+ break;
698+ }
699+
700+ dst += linebytes;
701+ src += linebytes;
702+ }
703+}
704+
705+static void splashfill(struct fb_info *info, int sy, int sx, int height,
706+ int width)
707+{
708+ int d = sy * info->fix.line_length + sx * ((info->var.bits_per_pixel + 7) >> 3);
709+
710+ fbsplash_copy((u8 *)(info->screen_base + d), (u8 *)(info->splash.data + d),
711+ height, width, info->fix.line_length, info->var.bits_per_pixel);
712+}
713+
714+void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
715+ int height, int width)
716+{
717+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
718+ int bg_color = attr_bgcol_ec(bgshift, vc);
719+ int transparent = vc->vc_splash.bg_color == bg_color;
720+ u8 *dst;
721+
722+ sy = sy * vc->vc_font.height + vc->vc_splash.ty;
723+ sx = sx * vc->vc_font.width + vc->vc_splash.tx;
724+ height *= vc->vc_font.height;
725+ width *= vc->vc_font.width;
726+
727+ if (transparent) {
728+ splashfill(info, sy, sx, height, width);
729+ } else {
730+ dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
731+ sx * ((info->var.bits_per_pixel + 7) >> 3));
732+ splashset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
733+ info->var.bits_per_pixel);
734+ }
735+}
736+
737+void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info,
738+ int bottom_only)
739+{
740+ unsigned int tw = vc->vc_cols*vc->vc_font.width;
741+ unsigned int th = vc->vc_rows*vc->vc_font.height;
742+
743+ if (!bottom_only) {
744+ /* top margin */
745+ splashfill(info, 0, 0, vc->vc_splash.ty, info->var.xres);
746+ /* left margin */
747+ splashfill(info, vc->vc_splash.ty, 0, th, vc->vc_splash.tx);
748+ /* right margin */
749+ splashfill(info, vc->vc_splash.ty, vc->vc_splash.tx + tw, th,
750+ info->var.xres - vc->vc_splash.tx - tw);
751+ }
752+ splashfill(info, vc->vc_splash.ty + th, 0,
753+ info->var.yres - vc->vc_splash.ty - th, info->var.xres);
754+}
755+
756+void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
757+ int sx, int dx, int width)
758+{
759+ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
760+ u16 *s = d + (dx - sx);
761+ u16 *start = d;
762+ u16 *ls = d;
763+ u16 *le = d + width;
764+ u16 c;
765+ int x = dx;
766+ u16 attr = 1;
767+
768+ do {
769+ c = scr_readw(d);
770+ if (attr != (c & 0xff00)) {
771+ attr = c & 0xff00;
772+ if (d > start) {
773+ fbsplash_putcs(vc, info, start, d - start, y, x);
774+ x += d - start;
775+ start = d;
776+ }
777+ }
778+ if (s >= ls && s < le && c == scr_readw(s)) {
779+ if (d > start) {
780+ fbsplash_putcs(vc, info, start, d - start, y, x);
781+ x += d - start + 1;
782+ start = d + 1;
783+ } else {
784+ x++;
785+ start++;
786+ }
787+ }
788+ s++;
789+ d++;
790+ } while (d < le);
791+ if (d > start)
792+ fbsplash_putcs(vc, info, start, d - start, y, x);
793+}
794+
795+void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank)
796+{
797+ if (blank) {
798+ splashset((u8 *)info->screen_base, info->var.yres, info->var.xres,
799+ info->fix.line_length, 0, info->var.bits_per_pixel);
800+ } else {
801+ update_screen(vc->vc_num);
802+ fbsplash_clear_margins(vc, info, 0);
803+ }
804+}
805+
806diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
807--- a/drivers/video/console/fbcon.c 2004-08-23 11:56:23 +02:00
808+++ b/drivers/video/console/fbcon.c 2004-08-23 11:56:23 +02:00
809@@ -93,6 +93,7 @@
810 #endif
811
812 #include "fbcon.h"
813+#include "../fbsplash.h"
814
815 #ifdef FBCONDEBUG
816 # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
817@@ -210,9 +211,14 @@
818 info->cursor.rop == ROP_COPY || !vc || !CON_IS_VISIBLE(vc)
819 || registered_fb[(int) con2fb_map[vc->vc_num]] != info)
820 return;
821+
822 acquire_console_sem();
823 info->cursor.enable ^= 1;
824- info->fbops->fb_cursor(info, &info->cursor);
825+ if (fbsplash_active(info, vc_cons[info->currcon].d)) {
826+ fbsplash_cursor(info, &info->cursor);
827+ } else {
828+ info->fbops->fb_cursor(info, &info->cursor);
829+ }
830 release_console_sem();
831 }
832
833@@ -414,6 +420,14 @@
834 area.sy = sy * vc->vc_font.height;
835 area.dx = dx * vc->vc_font.width;
836 area.dy = dy * vc->vc_font.height;
837+
838+ if (fbsplash_active(info, vc)) {
839+ area.sx += vc->vc_splash.tx;
840+ area.sy += vc->vc_splash.ty;
841+ area.dx += vc->vc_splash.tx;
842+ area.dy += vc->vc_splash.ty;
843+ }
844+
845 area.height = height * vc->vc_font.height;
846 area.width = width * vc->vc_font.width;
847
848@@ -426,6 +440,11 @@
849 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
850 struct fb_fillrect region;
851
852+ if (fbsplash_active(info, vc)) {
853+ fbsplash_clear(vc, info, sy, sx, height, width);
854+ return;
855+ }
856+
857 region.color = attr_bgcol_ec(bgshift, vc);
858 region.dx = sx * vc->vc_font.width;
859 region.dy = sy * vc->vc_font.height;
860@@ -458,6 +477,11 @@
861 struct fb_image image;
862 u8 *src, *dst;
863
864+ if (fbsplash_active(info, vc)) {
865+ fbsplash_putcs(vc, info, s, count, yy, xx);
866+ return;
867+ }
868+
869 image.fg_color = attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8,
870 scr_readw(s));
871 image.bg_color = attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12,
872@@ -526,6 +550,13 @@
873 unsigned int bs = info->var.yres - bh;
874 struct fb_fillrect region;
875
876+ if (fbsplash_active(info, vc)) {
877+ if (!fbsplash_isverbose)
878+ return;
879+ fbsplash_clear_margins(vc, info, bottom_only);
880+ return;
881+ }
882+
883 region.color = 0;
884 region.rop = ROP_COPY;
885
886@@ -622,6 +653,12 @@
887
888 cols = info->var.xres / vc->vc_font.width;
889 rows = info->var.yres / vc->vc_font.height;
890+
891+ if (fbsplash_active(info, vc)) {
892+ cols = vc->vc_splash.twidth / vc->vc_font.width;
893+ rows = vc->vc_splash.theight / vc->vc_font.height;
894+ }
895+
896 vc_resize(vc->vc_num, cols, rows);
897
898 DPRINTK("mode: %s\n", info->fix.id);
899@@ -718,7 +755,7 @@
900 if (info_idx == -1 || info == NULL)
901 return;
902 if (vc->vc_num != display_fg || (info->flags & FBINFO_MODULE) ||
903- (info->fix.type == FB_TYPE_TEXT))
904+ (info->fix.type == FB_TYPE_TEXT) || fbsplash_active(info, vc))
905 logo = 0;
906
907 info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
908@@ -948,6 +985,11 @@
909 if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
910 return;
911
912+ if (fbsplash_active(info, vc)) {
913+ fbsplash_putc(vc, info, c, ypos, xpos);
914+ return;
915+ }
916+
917 image.dx = xpos * vc->vc_font.width;
918 image.dy = real_y(p, ypos) * vc->vc_font.height;
919 image.width = vc->vc_font.width;
920@@ -1025,7 +1067,11 @@
921 if (info->cursor.rop == ROP_XOR) {
922 info->cursor.enable = 0;
923 info->cursor.rop = ROP_COPY;
924- info->fbops->fb_cursor(info, &cursor);
925+ if (fbsplash_active(info, vc)) {
926+ fbsplash_cursor(info, &cursor);
927+ } else {
928+ info->fbops->fb_cursor(info, &cursor);
929+ }
930 }
931 break;
932 case CM_MOVE:
933@@ -1101,7 +1147,11 @@
934 mask[i++] = 0xff;
935 }
936 info->cursor.rop = ROP_XOR;
937- info->fbops->fb_cursor(info, &cursor);
938+ if (fbsplash_active(info, vc)) {
939+ fbsplash_cursor(info, &cursor);
940+ } else {
941+ info->fbops->fb_cursor(info, &cursor);
942+ }
943 vbl_cursor_cnt = CURSOR_DRAW_DELAY;
944 break;
945 }
946@@ -1538,7 +1588,7 @@
947 count = vc->vc_rows;
948 if (softback_top)
949 fbcon_softback_note(vc, t, count);
950- if (logo_shown >= 0)
951+ if (logo_shown >= 0 || fbsplash_active(info, vc))
952 goto redraw_up;
953 switch (p->scrollmode) {
954 case SCROLL_MOVE:
955@@ -1625,6 +1675,8 @@
956 case SM_DOWN:
957 if (count > vc->vc_rows) /* Maximum realistic size */
958 count = vc->vc_rows;
959+ if (fbsplash_active(info, vc))
960+ goto redraw_down;
961 switch (p->scrollmode) {
962 case SCROLL_MOVE:
963 accel_bmove(vc, info, t, 0, t + count, 0,
964@@ -1767,6 +1819,13 @@
965 }
966 return;
967 }
968+
969+ if (fbsplash_active(info, vc) && sy == dy && height == 1) {
970+ /* must use slower redraw bmove to keep background pic intact */
971+ fbsplash_bmove_redraw(vc, info, sy, sx, dx, width);
972+ return;
973+ }
974+
975 accel_bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
976 height, width);
977 }
978@@ -1821,7 +1880,7 @@
979 var.yres = height * fh;
980 x_diff = info->var.xres - var.xres;
981 y_diff = info->var.yres - var.yres;
982- if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) {
983+ if ((x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) && !vc->vc_splash.state) {
984 char mode[40];
985
986 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
987@@ -1849,6 +1908,15 @@
988 struct display *p = &fb_display[vc->vc_num];
989 int i;
990
991+ if (fbsplash_active_vc(vc)) {
992+ struct vc_data *vc_curr = vc_cons[info->currcon].d;
993+
994+ if (!vc_curr->vc_splash.theme || strcmp(vc->vc_splash.theme, vc_curr->vc_splash.theme)) {
995+ if (fbsplash_call_helper("getpic", vc->vc_num))
996+ fbsplash_disable(vc, 0);
997+ }
998+ }
999+
1000 if (softback_top) {
1001 int l = fbcon_softback_size / vc->vc_size_row;
1002 if (softback_lines)
1003@@ -1966,6 +2034,12 @@
1004 fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
1005
1006 if (!info->fbops->fb_blank) {
1007+
1008+ if (fbsplash_active(info, vc)) {
1009+ fbsplash_blank(vc, info, blank);
1010+ return 0;
1011+ }
1012+
1013 if (blank) {
1014 unsigned short oldc;
1015 u_int height;
1016@@ -2134,9 +2208,16 @@
1017 }
1018
1019 if (resize) {
1020+ u32 xres = info->var.xres, yres = info->var.yres;
1021 /* reset wrap/pan */
1022 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
1023- vc_resize(vc->vc_num, info->var.xres / w, info->var.yres / h);
1024+
1025+ if (fbsplash_active(info, vc)) {
1026+ xres = vc->vc_splash.twidth;
1027+ yres = vc->vc_splash.theight;
1028+ }
1029+
1030+ vc_resize(vc->vc_num, xres / w, yres / h);
1031 if (CON_IS_VISIBLE(vc) && softback_buf) {
1032 int l = fbcon_softback_size / vc->vc_size_row;
1033 if (l > 5)
1034@@ -2310,7 +2391,63 @@
1035 else
1036 palette_cmap.len = 16;
1037 palette_cmap.start = 0;
1038- return fb_set_cmap(&palette_cmap, info);
1039+
1040+ if (fbsplash_active(info, vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1041+
1042+ u16 *red, *green, *blue;
1043+ u32 col;
1044+ int minlen = min(min(info->var.red.length, info->var.green.length),
1045+ info->var.blue.length);
1046+ int h;
1047+
1048+ struct fb_cmap cmap = {
1049+ .start = 0,
1050+ .len = (1 << minlen),
1051+ .red = NULL,
1052+ .green = NULL,
1053+ .blue = NULL,
1054+ .transp = NULL
1055+ };
1056+
1057+ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
1058+
1059+ if (!red)
1060+ goto out;
1061+
1062+ green = red + 256;
1063+ blue = green + 265;
1064+ cmap.red = red;
1065+ cmap.green = green;
1066+ cmap.blue = blue;
1067+
1068+ for (i = 0; i < cmap.len; i++) {
1069+ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
1070+ }
1071+
1072+ h = fb_set_cmap(&cmap, info);
1073+
1074+ for (j = i = 0; i < 16; i++) {
1075+ k = table[i];
1076+
1077+ col = ((vc->vc_palette[j++] >> (8-minlen))
1078+ << info->var.red.offset);
1079+ col |= ((vc->vc_palette[j++] >> (8-minlen))
1080+ << info->var.green.offset);
1081+ col |= ((vc->vc_palette[j++] >> (8-minlen))
1082+ << info->var.blue.offset);
1083+
1084+ ((u32 *)info->pseudo_palette)[k] = col;
1085+ }
1086+
1087+ kfree(red);
1088+
1089+ return h;
1090+
1091+ } else if (fbsplash_active(info, vc) && info->var.bits_per_pixel == 8 &&
1092+ info->splash.cmap.red != NULL)
1093+ fb_set_cmap(&info->splash.cmap, info);
1094+
1095+out: return fb_set_cmap(&palette_cmap, info);
1096 }
1097
1098 static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
1099@@ -2490,7 +2627,10 @@
1100 {
1101 /* Clear cursor, restore saved data */
1102 info->cursor.enable = 0;
1103- info->fbops->fb_cursor(info, &info->cursor);
1104+ if (fbsplash_active(info, vc_cons[info->currcon].d))
1105+ fbsplash_cursor(info, &info->cursor);
1106+ else
1107+ info->fbops->fb_cursor(info, &info->cursor);
1108 }
1109
1110 static void fbcon_resumed(struct fb_info *info)
1111@@ -2522,7 +2662,14 @@
1112 if (CON_IS_VISIBLE(vc)) {
1113 cols = info->var.xres / vc->vc_font.width;
1114 rows = info->var.yres / vc->vc_font.height;
1115- vc_resize(vc->vc_num, cols, rows);
1116+
1117+ if (!fbsplash_active(info, vc)) {
1118+ vc_resize(vc->vc_num, cols, rows);
1119+ } else {
1120+ if (fbsplash_call_helper("modechange", vc->vc_num))
1121+ fbsplash_disable(vc, 0);
1122+ }
1123+
1124 updatescrollmode(p, info, vc);
1125 scrollback_max = 0;
1126 scrollback_current = 0;
1127@@ -2632,6 +2779,9 @@
1128 fbcon_event_notifier_registered = 1;
1129 }
1130 release_console_sem();
1131+
1132+ fbsplash_init();
1133+
1134 return 0;
1135 }
1136
1137diff -Nru a/drivers/video/fbsplash.c b/drivers/video/fbsplash.c
1138--- /dev/null Wed Dec 31 16:00:00 196900
1139+++ b/drivers/video/fbsplash.c 2004-08-23 11:56:23 +02:00
1140@@ -0,0 +1,527 @@
1141+/*
1142+ * linux/drivers/video/fbsplash.c -- Framebuffer splash routines
1143+ *
1144+ * Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
1145+ *
1146+ * Code based upon "Bootsplash" (C) 2001-2003
1147+ * Volker Poplawski <volker@poplawski.de>,
1148+ * Stefan Reinauer <stepan@suse.de>,
1149+ * Steffen Winterfeldt <snwint@suse.de>,
1150+ * Michael Schroeder <mls@suse.de>,
1151+ * Ken Wimer <wimer@suse.de>.
1152+ *
1153+ * Splash render routines are located in /linux/drivers/video/cfbsplash.c
1154+ *
1155+ * This file is subject to the terms and conditions of the GNU General Public
1156+ * License. See the file COPYING in the main directory of this archive for
1157+ * more details.
1158+ *
1159+ */
1160+#include <linux/config.h>
1161+#include <linux/module.h>
1162+#include <linux/kernel.h>
1163+#include <linux/string.h>
1164+#include <linux/types.h>
1165+#include <linux/fb.h>
1166+#include <linux/vt_kern.h>
1167+#include <linux/vmalloc.h>
1168+#include <linux/unistd.h>
1169+#include <linux/syscalls.h>
1170+#include <linux/init.h>
1171+#include <linux/proc_fs.h>
1172+#include <linux/workqueue.h>
1173+#include <linux/kmod.h>
1174+#include <linux/miscdevice.h>
1175+#include <linux/device.h>
1176+#include <linux/fs.h>
1177+
1178+#include <asm/uaccess.h>
1179+#include <asm/irq.h>
1180+#include <asm/system.h>
1181+
1182+#include "console/fbcon.h"
1183+#include "fbsplash.h"
1184+
1185+#define SPLASH_VERSION "0.9"
1186+
1187+#ifdef DEBUG
1188+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
1189+#else
1190+#define DPRINTK(fmt, args...)
1191+#endif
1192+
1193+static void splash_work_verbose(void *data);
1194+static int fbsplash_enable(struct vc_data *vc);
1195+
1196+DECLARE_WORK(splash_wq_verbose, splash_work_verbose, NULL);
1197+
1198+int fbsplash_mode = 0;
1199+char fbsplash_path[KMOD_PATH_LEN] = "/sbin/splash_helper";
1200+static char fbsplash_theme[FB_SPLASH_THEME_LEN] __initdata = "default";
1201+
1202+int fbsplash_call_helper(char* cmd, unsigned short vc)
1203+{
1204+ char *envp[] = {
1205+ "HOME=/",
1206+ "PATH=/sbin:/bin",
1207+ NULL
1208+ };
1209+
1210+ char tfb[5];
1211+ char tcons[5];
1212+ unsigned char fb = (int) con2fb_map[vc];
1213+
1214+ char *argv[] = {
1215+ fbsplash_path,
1216+ "1",
1217+ cmd,
1218+ tcons,
1219+ tfb,
1220+ (fbsplash_mode == FB_SPLASH_MODE_SILENT) ? "s" : "v",
1221+ vc_cons[vc].d->vc_splash.theme,
1222+ NULL
1223+ };
1224+
1225+ snprintf(tfb,5,"%d",fb);
1226+ snprintf(tcons,5,"%d",vc);
1227+
1228+ return call_usermodehelper(fbsplash_path, argv, envp, 1);
1229+}
1230+
1231+int fbsplash_verbose(void)
1232+{
1233+ if (fbsplash_mode == FB_SPLASH_MODE_VERBOSE)
1234+ return 0;
1235+
1236+ fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1237+
1238+ /* We have to do the switch from a workqueue helper, because chances are this
1239+ * function gets called from interrupt context, and we can't get hold of the
1240+ * console sem this way. */
1241+ schedule_work(&splash_wq_verbose);
1242+
1243+ return 1;
1244+}
1245+
1246+/* Switches the first console to verbose mode. */
1247+static void splash_work_verbose(void *data)
1248+{
1249+ struct fb_info *info;
1250+ struct vc_data *vc;
1251+
1252+ vc = vc_cons[0].d;
1253+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1254+
1255+ if (info == NULL)
1256+ return;
1257+
1258+ printk(KERN_INFO "fbsplash: switching to verbose mode\n");
1259+
1260+ vt_cons[0]->vc_mode = KD_TEXT;
1261+
1262+ acquire_console_sem();
1263+ do_unblank_screen(0);
1264+
1265+ if (info->splash.data) {
1266+ fbsplash_enable(vc);
1267+ } else {
1268+ fbsplash_disable(vc, 1);
1269+ }
1270+ release_console_sem();
1271+}
1272+
1273+/* Disables fbsplash on a virtual console; called with console sem held. */
1274+int fbsplash_disable(struct vc_data *vc, unsigned char redraw)
1275+{
1276+ struct fb_info* info;
1277+
1278+ if (!vc->vc_splash.state)
1279+ return -EINVAL;
1280+
1281+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1282+
1283+ if (info == NULL)
1284+ return -EINVAL;
1285+
1286+ vc->vc_splash.state = 0;
1287+ vc_resize(vc->vc_num, info->var.xres / vc->vc_font.width,
1288+ info->var.yres / vc->vc_font.height);
1289+
1290+ if (fg_console == vc->vc_num && redraw) {
1291+ redraw_screen(fg_console, 0);
1292+ update_region(fg_console, vc->vc_origin +
1293+ vc->vc_size_row * vc->vc_top,
1294+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1295+ }
1296+
1297+ printk(KERN_INFO "fbsplash: switched splash state to 'off' on console %d\n",
1298+ vc->vc_num);
1299+
1300+ return 0;
1301+}
1302+
1303+/* Enables fbsplash on a virtual console; called with console sem held. */
1304+static int fbsplash_enable(struct vc_data *vc)
1305+{
1306+ struct fb_info* info;
1307+
1308+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1309+
1310+ if (vc->vc_splash.twidth == 0 || vc->vc_splash.theight == 0 ||
1311+ info == NULL || !info->splash.data || vc->vc_splash.state)
1312+ return -EINVAL;
1313+
1314+ vc->vc_splash.state = 1;
1315+ vc_resize(vc->vc_num, vc->vc_splash.twidth / vc->vc_font.width,
1316+ vc->vc_splash.theight / vc->vc_font.height);
1317+
1318+ if (fg_console == vc->vc_num) {
1319+ redraw_screen(fg_console, 0);
1320+ update_region(fg_console, vc->vc_origin +
1321+ vc->vc_size_row * vc->vc_top,
1322+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
1323+ fbsplash_clear_margins(vc, info, 0);
1324+ }
1325+
1326+ printk(KERN_INFO "fbsplash: switched splash state to 'on' on console %d\n",
1327+ vc->vc_num);
1328+
1329+ return 0;
1330+}
1331+
1332+static int __init splash_setup(char *options)
1333+{
1334+ char *this_opt;
1335+
1336+ while ((this_opt = strsep(&options, ",")) != NULL) {
1337+
1338+ if (!strcmp(this_opt, "silent")) {
1339+ fbsplash_mode = FB_SPLASH_MODE_SILENT;
1340+ printk(KERN_INFO "fbsplash: silent\n");
1341+ } else if (!strcmp(this_opt, "verbose")) {
1342+ fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1343+ printk(KERN_INFO "fbsplash: verbose\n");
1344+ } else if (!strcmp(this_opt, "off")) {
1345+ fbsplash_mode = 0;
1346+ } else if (!strncmp(this_opt, "theme:", 6)) {
1347+ strncpy(fbsplash_theme, this_opt+6, 64);
1348+ printk(KERN_INFO "fbsplash: theme %s\n", fbsplash_theme);
1349+ } else {
1350+ printk(KERN_WARNING "fbsplash: unrecognized option %s\n", this_opt);
1351+ }
1352+ }
1353+ return 0;
1354+}
1355+
1356+__setup("splash=", splash_setup);
1357+
1358+static int splash_get_info(char *buf, char **start, off_t fpos, int length)
1359+{
1360+ char *p = buf;
1361+
1362+ p += sprintf(p, "Framebuffer splash v%s, mode: %s\n", SPLASH_VERSION,
1363+ ((fbsplash_mode == 2) ? "silent" : (fbsplash_mode == 1) ? "verbose" : "off"));
1364+
1365+ return p - buf;
1366+}
1367+
1368+static inline int fbsplash_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin)
1369+{
1370+ int tmp, ret;
1371+
1372+ if (get_user(tmp, state))
1373+ return -EFAULT;
1374+
1375+ if (origin == FB_SPLASH_IO_ORIG_USER)
1376+ acquire_console_sem();
1377+ if (!tmp)
1378+ ret = fbsplash_disable(vc, 1);
1379+ else
1380+ ret = fbsplash_enable(vc);
1381+ if (origin == FB_SPLASH_IO_ORIG_USER)
1382+ release_console_sem();
1383+
1384+ return ret;
1385+}
1386+
1387+static inline int fbsplash_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state)
1388+{
1389+ return put_user(vc->vc_splash.state, (unsigned int __user*) state);
1390+}
1391+
1392+static int fbsplash_ioctl_dosetcfg(struct vc_data *vc, struct vc_splash __user *arg, unsigned char origin)
1393+{
1394+ struct vc_splash cfg;
1395+ struct fb_info *info;
1396+ int len;
1397+ char *tmp;
1398+
1399+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1400+
1401+ if (copy_from_user(&cfg, arg, sizeof(struct vc_splash)))
1402+ return -EFAULT;
1403+ if (info == NULL || !cfg.twidth || !cfg.theight ||
1404+ cfg.tx + cfg.twidth > info->var.xres ||
1405+ cfg.ty + cfg.theight > info->var.yres)
1406+ return -EINVAL;
1407+
1408+ len = strlen_user(cfg.theme);
1409+ if (!len || len > FB_SPLASH_THEME_LEN)
1410+ return -EINVAL;
1411+ tmp = kmalloc(len, GFP_KERNEL);
1412+ if (!tmp)
1413+ return -ENOMEM;
1414+ if (copy_from_user(tmp, (void __user *)cfg.theme, len))
1415+ return -EFAULT;
1416+ cfg.theme = tmp;
1417+ cfg.state = 0;
1418+
1419+ /* If this ioctl is a response to a request from kernel, the console sem
1420+ * is already held; we also don't need to disable splash because either the
1421+ * new config and background picture will be successfully loaded, and the
1422+ * splash will stay on, or in case of a failure it'll be turned off in fbcon. */
1423+ if (origin == FB_SPLASH_IO_ORIG_USER) {
1424+ acquire_console_sem();
1425+ if (vc->vc_splash.state)
1426+ fbsplash_disable(vc, 1);
1427+ }
1428+
1429+ if (vc->vc_splash.theme)
1430+ kfree(vc->vc_splash.theme);
1431+
1432+ vc->vc_splash = cfg;
1433+
1434+ if (origin == FB_SPLASH_IO_ORIG_USER)
1435+ release_console_sem();
1436+
1437+ printk(KERN_INFO "fbsplash: console %d using theme '%s'\n",
1438+ vc->vc_num, vc->vc_splash.theme);
1439+ return 0;
1440+}
1441+
1442+static int fbsplash_ioctl_dogetcfg(struct vc_data *vc, struct vc_splash __user *arg)
1443+{
1444+ struct vc_splash splash;
1445+ char __user *tmp;
1446+
1447+ if (get_user(tmp, &arg->theme))
1448+ return -EFAULT;
1449+
1450+ splash = vc->vc_splash;
1451+ splash.theme = tmp;
1452+
1453+ if (vc->vc_splash.theme) {
1454+ if (copy_to_user(tmp, vc->vc_splash.theme, strlen(vc->vc_splash.theme) + 1))
1455+ return -EFAULT;
1456+ } else
1457+ if (put_user(0, tmp))
1458+ return -EFAULT;
1459+
1460+ if (copy_to_user(arg, &splash, sizeof(struct vc_splash)))
1461+ return -EFAULT;
1462+
1463+ return 0;
1464+}
1465+
1466+static int fbsplash_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin)
1467+{
1468+ struct fb_image img;
1469+ struct fb_info *info;
1470+ int len;
1471+ u8 *tmp;
1472+
1473+ if (vc->vc_num != fg_console)
1474+ return -EINVAL;
1475+
1476+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
1477+
1478+ if (info == NULL)
1479+ return -EINVAL;
1480+
1481+ if (copy_from_user(&img, arg, sizeof(struct fb_image)))
1482+ return -EFAULT;
1483+
1484+ if (img.width != info->var.xres || img.height != info->var.yres) {
1485+ printk(KERN_ERR "fbsplash: picture dimensions mismatch\n");
1486+ return -EINVAL;
1487+ }
1488+
1489+ if (img.depth != info->var.bits_per_pixel) {
1490+ printk(KERN_ERR "fbsplash: picture depth mismatch\n");
1491+ return -EINVAL;
1492+ }
1493+
1494+ if (img.depth == 8) {
1495+ if (!img.cmap.len || !img.cmap.red || !img.cmap.green ||
1496+ !img.cmap.blue)
1497+ return -EINVAL;
1498+
1499+ tmp = vmalloc(img.cmap.len * 3 * 2);
1500+ if (!tmp)
1501+ return -ENOMEM;
1502+
1503+ if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) ||
1504+ copy_from_user(tmp + (img.cmap.len << 1),
1505+ (void __user*)img.cmap.green, (img.cmap.len << 1)) ||
1506+ copy_from_user(tmp + (img.cmap.len << 2),
1507+ (void __user*)img.cmap.blue, (img.cmap.len << 1))) {
1508+ vfree(tmp);
1509+ return -EFAULT;
1510+ }
1511+
1512+ img.cmap.transp = NULL;
1513+ img.cmap.red = (u16*)tmp;
1514+ img.cmap.green = img.cmap.red + img.cmap.len;
1515+ img.cmap.blue = img.cmap.green + img.cmap.len;
1516+ } else {
1517+ img.cmap.red = NULL;
1518+ }
1519+
1520+ len = ((img.depth + 7) >> 3) * img.width * img.height;
1521+ tmp = vmalloc(len);
1522+
1523+ if (!tmp)
1524+ goto out;
1525+
1526+ if (copy_from_user(tmp, (void __user*)img.data, len))
1527+ goto out;
1528+
1529+ img.data = tmp;
1530+
1531+ /* If this ioctl is a response to a request from kernel, the console sem
1532+ * is already held. */
1533+ if (origin == FB_SPLASH_IO_ORIG_USER)
1534+ acquire_console_sem();
1535+
1536+ if (info->splash.data)
1537+ vfree((u8*)info->splash.data);
1538+ if (info->splash.cmap.red)
1539+ vfree(info->splash.cmap.red);
1540+
1541+ info->splash = img;
1542+
1543+ if (origin == FB_SPLASH_IO_ORIG_USER)
1544+ release_console_sem();
1545+
1546+ return 0;
1547+
1548+out: if (img.cmap.red)
1549+ vfree(img.cmap.red);
1550+ if (tmp)
1551+ vfree(tmp);
1552+ return -ENOMEM;
1553+}
1554+
1555+static int splash_ioctl(struct inode * inode, struct file *filp, u_int cmd,
1556+ u_long arg)
1557+{
1558+ struct fb_splash_iowrapper __user *wrapper = (void __user*) arg;
1559+ struct vc_data *vc = NULL;
1560+ unsigned short vc_num = 0;
1561+ unsigned char origin = 0;
1562+ void __user *data = NULL;
1563+
1564+ if (cmd != FBIOSPLASH_SETMODE && cmd != FBIOSPLASH_GETMODE)
1565+ {
1566+ if (verify_area(VERIFY_READ, wrapper,
1567+ sizeof(struct fb_splash_iowrapper)))
1568+ return -EFAULT;
1569+
1570+ __get_user(vc_num, &wrapper->vc);
1571+ __get_user(origin, &wrapper->origin);
1572+ __get_user(data, &wrapper->data);
1573+
1574+ if (!vc_cons_allocated(vc_num))
1575+ return -EINVAL;
1576+
1577+ vc = vc_cons[vc_num].d;
1578+ }
1579+
1580+ switch (cmd) {
1581+
1582+ case FBIOSPLASH_SETMODE:
1583+ if (arg != FB_SPLASH_MODE_SILENT && arg != FB_SPLASH_MODE_VERBOSE)
1584+ return -EINVAL;
1585+
1586+ if (fbsplash_mode == arg)
1587+ return 0;
1588+
1589+ fbsplash_mode = arg;
1590+ if (arg == FB_SPLASH_MODE_VERBOSE)
1591+ splash_work_verbose(NULL);
1592+ return 0;
1593+
1594+ case FBIOSPLASH_GETMODE:
1595+ return put_user(fbsplash_mode, (unsigned int __user *)arg);
1596+ case FBIOSPLASH_SETPIC:
1597+ return fbsplash_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin);
1598+ case FBIOSPLASH_SETCFG:
1599+ return fbsplash_ioctl_dosetcfg(vc, (struct vc_splash*)data, origin);
1600+ case FBIOSPLASH_GETCFG:
1601+ return fbsplash_ioctl_dogetcfg(vc, (struct vc_splash*)data);
1602+ case FBIOSPLASH_SETSTATE:
1603+ return fbsplash_ioctl_dosetstate(vc, (unsigned int *)data, origin);
1604+ case FBIOSPLASH_GETSTATE:
1605+ return fbsplash_ioctl_dogetstate(vc, (unsigned int *)data);
1606+ default:
1607+ return -ENOIOCTLCMD;
1608+ }
1609+}
1610+
1611+static struct file_operations splash_ops = {
1612+ .owner = THIS_MODULE,
1613+ .ioctl = splash_ioctl
1614+};
1615+
1616+static struct miscdevice splash_dev = {
1617+ .minor = MISC_DYNAMIC_MINOR,
1618+ .name = "fbsplash",
1619+ .fops = &splash_ops
1620+};
1621+
1622+int fbsplash_init(void)
1623+{
1624+ struct proc_dir_entry *splash_proc;
1625+ struct fb_info *info;
1626+ struct vc_data *vc;
1627+ int i;
1628+
1629+ vc = vc_cons[0].d;
1630+ info = registered_fb[0];
1631+
1632+ for (i = 0; i < num_registered_fb; i++) {
1633+ registered_fb[i]->splash.data = NULL;
1634+ registered_fb[i]->splash.cmap.red = NULL;
1635+ }
1636+
1637+ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
1638+ vc_cons[i].d->vc_splash.state = vc_cons[i].d->vc_splash.twidth =
1639+ vc_cons[i].d->vc_splash.theight = 0;
1640+ vc_cons[i].d->vc_splash.theme = NULL;
1641+ }
1642+
1643+ i = misc_register(&splash_dev);
1644+ if (i) {
1645+ printk(KERN_ERR "fbsplash: failed to register device\n");
1646+ return i;
1647+ }
1648+
1649+#ifdef CONFIG_PROC_FS
1650+ splash_proc = create_proc_info_entry("fbsplash", 0, NULL, splash_get_info);
1651+ if (splash_proc)
1652+ splash_proc->owner = THIS_MODULE;
1653+#endif
1654+
1655+ if (fbsplash_mode && info) {
1656+ vc->vc_splash.theme = kmalloc((strlen(fbsplash_theme)+1) * sizeof(char), GFP_KERNEL);
1657+ strcpy(vc->vc_splash.theme, fbsplash_theme);
1658+ if (fbsplash_call_helper("init", 0))
1659+ fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1660+ } else {
1661+ fbsplash_mode = FB_SPLASH_MODE_VERBOSE;
1662+ }
1663+
1664+ return 0;
1665+}
1666+
1667+EXPORT_SYMBOL(fbsplash_path);
1668diff -Nru a/drivers/video/fbsplash.h b/drivers/video/fbsplash.h
1669--- /dev/null Wed Dec 31 16:00:00 196900
1670+++ b/drivers/video/fbsplash.h 2004-08-23 11:56:23 +02:00
1671@@ -0,0 +1,69 @@
1672+/*
1673+ * linux/drivers/video/fbsplash.h -- Framebuffer splash headers
1674+ *
1675+ * Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
1676+ *
1677+ */
1678+
1679+#ifndef __FB_SPLASH_H
1680+#define __FB_SPLASH_H
1681+
1682+struct fb_cursor;
1683+struct fb_info;
1684+struct vc_data;
1685+
1686+#ifdef CONFIG_FB_SPLASH
1687+/* fbsplash.c */
1688+int fbsplash_init(void);
1689+int fbsplash_verbose(void);
1690+int fbsplash_call_helper(char* cmd, unsigned short cons);
1691+int fbsplash_disable(struct vc_data *vc, unsigned char redraw);
1692+
1693+/* cfbsplash.c */
1694+void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
1695+void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos);
1696+void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor);
1697+void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
1698+void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
1699+void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank);
1700+void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
1701+void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int bpp);
1702+
1703+/* vt.c */
1704+void acquire_console_sem(void);
1705+void release_console_sem(void);
1706+void do_unblank_screen(int entering_gfx);
1707+
1708+extern int fbsplash_mode;
1709+#define fbsplash_isverbose (fbsplash_mode == FB_SPLASH_MODE_VERBOSE)
1710+
1711+/* struct vc_data *y */
1712+#define fbsplash_active_vc(y) (y->vc_splash.state && y->vc_splash.theme)
1713+
1714+/* struct fb_info *x, struct vc_data *y */
1715+#define fbsplash_active(x,y) (x->splash.data && fbsplash_active_vc(y) && \
1716+ x->splash.width == x->var.xres && \
1717+ x->splash.height == x->var.yres && \
1718+ x->splash.depth == x->var.bits_per_pixel)
1719+
1720+#else /* CONFIG_FB_SPLASH */
1721+
1722+static inline void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
1723+static inline void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
1724+static inline void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
1725+static inline void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
1726+static inline void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
1727+static inline void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
1728+static inline void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
1729+static inline int fbsplash_call_helper(char* cmd, unsigned short cons) { return 0; }
1730+static inline int fbsplash_init(void) { return 0; }
1731+static inline int fbsplash_verbose(void) { return 0; }
1732+static inline int fbsplash_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
1733+
1734+#define fbsplash_isverbose (0)
1735+#define fbsplash_active_vc(y) (0)
1736+#define fbsplash_active(x,y) (0)
1737+
1738+#endif /* CONFIG_FB_SPLASH */
1739+
1740+#endif /* __FB_SPLASH_H */
1741diff -Nru a/include/linux/console_splash.h b/include/linux/console_splash.h
1742--- /dev/null Wed Dec 31 16:00:00 196900
1743+++ b/include/linux/console_splash.h 2004-08-23 11:56:23 +02:00
1744@@ -0,0 +1,13 @@
1745+#ifndef _LINUX_CONSOLE_SPLASH_H_
1746+#define _LINUX_CONSOLE_SPLASH_H_ 1
1747+
1748+/* A structure used by the framebuffer splash code (drivers/video/fbsplash.c) */
1749+struct vc_splash {
1750+ __u8 bg_color; /* The color that is to be treated as transparent */
1751+ __u8 state; /* Current splash state: 0 = off, 1 = on */
1752+ __u16 tx, ty; /* Top left corner coordinates of the text field */
1753+ __u16 twidth, theight; /* Width and height of the text field */
1754+ char* theme;
1755+};
1756+
1757+#endif
1758diff -Nru a/include/linux/console_struct.h b/include/linux/console_struct.h
1759--- a/include/linux/console_struct.h 2004-08-23 11:56:23 +02:00
1760+++ b/include/linux/console_struct.h 2004-08-23 11:56:23 +02:00
1761@@ -10,6 +10,7 @@
1762 */
1763
1764 #define NPAR 16
1765+#include <linux/console_splash.h>
1766
1767 struct vc_data {
1768 unsigned short vc_num; /* Console number */
1769@@ -87,6 +88,8 @@
1770 struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */
1771 unsigned long vc_uni_pagedir;
1772 unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
1773+
1774+ struct vc_splash vc_splash;
1775 /* additional information is in vt_kern.h */
1776 };
1777
1778diff -Nru a/include/linux/fb.h b/include/linux/fb.h
1779--- a/include/linux/fb.h 2004-08-23 11:56:23 +02:00
1780+++ b/include/linux/fb.h 2004-08-23 11:56:23 +02:00
1781@@ -8,6 +8,13 @@
1782 #define FB_MAJOR 29
1783 #define FB_MAX 32 /* sufficient for now */
1784
1785+struct fb_splash_iowrapper
1786+{
1787+ unsigned short vc; /* Virtual console */
1788+ unsigned char origin; /* Point of origin of the request */
1789+ void *data;
1790+};
1791+
1792 /* ioctls
1793 0x46 is 'F' */
1794 #define FBIOGET_VSCREENINFO 0x4600
1795@@ -35,7 +42,19 @@
1796 #define FBIOGET_HWCINFO 0x4616
1797 #define FBIOPUT_MODEINFO 0x4617
1798 #define FBIOGET_DISPINFO 0x4618
1799-
1800+#define FBIOSPLASH_SETCFG _IOWR('F', 0x19, struct fb_splash_iowrapper)
1801+#define FBIOSPLASH_GETCFG _IOR('F', 0x1A, struct fb_splash_iowrapper)
1802+#define FBIOSPLASH_SETSTATE _IOWR('F', 0x1B, struct fb_splash_iowrapper)
1803+#define FBIOSPLASH_GETSTATE _IOR('F', 0x1C, struct fb_splash_iowrapper)
1804+#define FBIOSPLASH_SETMODE _IOWR('F', 0x1D, unsigned int)
1805+#define FBIOSPLASH_GETMODE _IOR('F', 0x1E, unsigned int)
1806+#define FBIOSPLASH_SETPIC _IOWR('F', 0x1F, struct fb_splash_iowrapper)
1807+
1808+#define FB_SPLASH_MODE_VERBOSE 1 /* Verbose mode */
1809+#define FB_SPLASH_MODE_SILENT 2 /* Silent mode */
1810+#define FB_SPLASH_THEME_LEN 128 /* Maximum lenght of a theme name */
1811+#define FB_SPLASH_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */
1812+#define FB_SPLASH_IO_ORIG_USER 1 /* User ioctl origin */
1813
1814 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
1815 #define FB_TYPE_PLANES 1 /* Non interleaved planes */
1816@@ -588,6 +607,8 @@
1817 #define FBINFO_STATE_RUNNING 0
1818 #define FBINFO_STATE_SUSPENDED 1
1819 u32 state; /* Hardware state i.e suspend */
1820+
1821+ struct fb_image splash;
1822
1823 /* From here on everything is device dependent */
1824 void *par;
1825diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
1826--- a/include/linux/sysctl.h 2004-08-23 11:56:23 +02:00
1827+++ b/include/linux/sysctl.h 2004-08-23 11:56:23 +02:00
1828@@ -133,6 +133,7 @@
1829 KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */
1830 KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
1831 KERN_HZ_TIMER=65, /* int: hz timer on or off */
1832+ KERN_FBSPLASH=66, /* string: path to fbsplash helper */
1833 };
1834
1835
1836diff -Nru a/kernel/panic.c b/kernel/panic.c
1837--- a/kernel/panic.c 2004-08-23 11:56:23 +02:00
1838+++ b/kernel/panic.c 2004-08-23 11:56:23 +02:00
1839@@ -19,6 +19,7 @@
1840 #include <linux/syscalls.h>
1841 #include <linux/interrupt.h>
1842 #include <linux/nmi.h>
1843+#include "../drivers/video/fbsplash.h"
1844
1845 int panic_timeout;
1846 int panic_on_oops;
1847@@ -82,6 +83,8 @@
1848 * We can't use the "normal" timers since we just panicked..
1849 */
1850 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
1851+ fbsplash_verbose();
1852+
1853 for (i = 0; i < panic_timeout; i++) {
1854 touch_nmi_watchdog();
1855 mdelay(1000);
1856@@ -105,6 +108,8 @@
1857 disabled_wait(caller);
1858 #endif
1859 local_irq_enable();
1860+ fbsplash_verbose();
1861+
1862 for (;;)
1863 ;
1864 }
1865diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
1866--- a/kernel/sysctl.c 2004-08-23 11:56:23 +02:00
1867+++ b/kernel/sysctl.c 2004-08-23 11:56:23 +02:00
1868@@ -77,6 +77,9 @@
1869 #ifdef CONFIG_HOTPLUG
1870 extern char hotplug_path[];
1871 #endif
1872+#ifdef CONFIG_FB_SPLASH
1873+extern char fbsplash_path[];
1874+#endif
1875 #ifdef CONFIG_CHR_DEV_SG
1876 extern int sg_big_buff;
1877 #endif
1878@@ -403,6 +406,17 @@
1879 .ctl_name = KERN_HOTPLUG,
1880 .procname = "hotplug",
1881 .data = &hotplug_path,
1882+ .maxlen = KMOD_PATH_LEN,
1883+ .mode = 0644,
1884+ .proc_handler = &proc_dostring,
1885+ .strategy = &sysctl_string,
1886+ },
1887+#endif
1888+#ifdef CONFIG_FB_SPLASH
1889+ {
1890+ .ctl_name = KERN_FBSPLASH,
1891+ .procname = "fbsplash",
1892+ .data = &fbsplash_path,
1893 .maxlen = KMOD_PATH_LEN,
1894 .mode = 0644,
1895 .proc_handler = &proc_dostring,
This page took 0.270558 seconds and 4 git commands to generate.