1 diff -ruN linux-2.6.32.old//drivers/char/keyboard.c linux-2.6.32/drivers/char/keyboard.c
2 --- linux-2.6.32.old//drivers/char/keyboard.c 2011-06-22 13:21:18.000000000 +0200
3 +++ linux-2.6.32/drivers/char/keyboard.c 2011-06-22 13:30:41.000000000 +0200
5 if (keycode < BTN_MISC && printk_ratelimit())
6 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
8 +#ifdef CONFIG_BOOTSPLASH
9 + /* This code has to be redone for some non-x86 platforms */
10 + if (down == 1 && (keycode == 0x3c || keycode == 0x01)) { /* F2 and ESC on PC keyboard */
11 + extern int splash_verbose(void);
12 + if (splash_verbose())
17 #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
18 if ((keycode == sysrq_key_scancode || keycode == KEY_SYSRQ) &&
19 (sysrq_down || (down == 1 && sysrq_alt))) {
20 diff -ruN linux-2.6.32.old//drivers/char/n_tty.c linux-2.6.32/drivers/char/n_tty.c
21 --- linux-2.6.32.old//drivers/char/n_tty.c 2009-12-03 04:51:21.000000000 +0100
22 +++ linux-2.6.32/drivers/char/n_tty.c 2011-06-22 13:30:41.000000000 +0200
23 @@ -1778,6 +1778,15 @@
24 tty->minimum_to_wake = (minimum - (b - buf));
26 if (!input_available_p(tty, 0)) {
27 +#ifdef CONFIG_BOOTSPLASH
28 + if (file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,0) ||
29 + file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1) ||
30 + file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) ||
31 + file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,1)) {
32 + extern int splash_verbose(void);
33 + (void)splash_verbose();
36 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
39 diff -ruN linux-2.6.32.old//drivers/char/vt.c linux-2.6.32/drivers/char/vt.c
40 --- linux-2.6.32.old//drivers/char/vt.c 2011-05-10 20:38:07.000000000 +0200
41 +++ linux-2.6.32/drivers/char/vt.c 2011-06-22 13:30:41.000000000 +0200
42 @@ -4073,6 +4073,31 @@
46 +#ifdef CONFIG_BOOTSPLASH
47 +void con_remap_def_color(struct vc_data *vc, int new_color)
49 + unsigned short *sbuf = vc->vc_screenbuf;
50 + unsigned c, len = vc->vc_screenbuf_size >> 1;
54 + old_color = vc->vc_def_color << 8;
58 + if (((c ^ old_color) & 0xf000) == 0)
59 + *sbuf ^= (old_color ^ new_color) & 0xf000;
60 + if (((c ^ old_color) & 0x0f00) == 0)
61 + *sbuf ^= (old_color ^ new_color) & 0x0f00;
66 + vc->vc_def_color = vc->vc_color = new_color;
72 * Visible symbols for modules
74 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/bootsplash.c linux-2.6.32/drivers/video/bootsplash/bootsplash.c
75 --- linux-2.6.32.old//drivers/video/bootsplash/bootsplash.c 1970-01-01 01:00:00.000000000 +0100
76 +++ linux-2.6.32/drivers/video/bootsplash/bootsplash.c 2011-06-22 13:30:41.000000000 +0200
79 + * linux/drivers/video/bootsplash/bootsplash.c -
80 + * splash screen handling functions.
82 + * (w) 2001-2004 by Volker Poplawski, <volker@poplawski.de>,
83 + * Stefan Reinauer, <stepan@suse.de>,
84 + * Steffen Winterfeldt, <snwint@suse.de>,
85 + * Michael Schroeder <mls@suse.de>
87 + * Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de>
89 + * For more information on this code check http://www.bootsplash.org/
92 +#include <linux/module.h>
93 +#include <linux/types.h>
94 +#include <linux/fb.h>
95 +#include <linux/vt_kern.h>
96 +#include <linux/vmalloc.h>
97 +#include <linux/unistd.h>
98 +#include <linux/syscalls.h>
100 +#include <asm/irq.h>
101 +#include <asm/system.h>
103 +#include "../console/fbcon.h"
104 +#include "bootsplash.h"
105 +#include "decode-jpg.h"
107 +/* extern struct fb_ops vesafb_ops; */
108 +extern signed char con2fb_map[MAX_NR_CONSOLES];
110 +#define SPLASH_VERSION "3.1.9-2009/10/07"
112 +/* These errors have to match fbcon-jpegdec.h */
113 +static unsigned char *jpg_errors[] = {
118 + "bad width or height",
121 + "quant table selector",
122 + "picture is not YCBCR 221111",
123 + "unknow CID in scan",
124 + "dct not sequential",
131 +static struct jpeg_decdata *decdata = 0; /* private decoder data */
133 +static int splash_registered = 0;
134 +static int splash_usesilent = 0; /* shall we display the silentjpeg? */
135 +int splash_default = 0xf01;
137 +static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth);
139 +static int __init splash_setup(char *options)
141 + if(!strncmp("silent", options, 6)) {
142 + printk(KERN_INFO "bootsplash: silent mode.\n");
143 + splash_usesilent = 1;
144 + /* skip "silent," */
145 + if (strlen(options) == 6)
149 + if(!strncmp("verbose", options, 7)) {
150 + printk(KERN_INFO "bootsplash: verbose mode.\n");
151 + splash_usesilent = 0;
154 + splash_default = simple_strtoul(options, NULL, 0);
158 +__setup("splash=", splash_setup);
161 +static int splash_hasinter(unsigned char *buf, int num)
163 + unsigned char *bufend = buf + num * 12;
164 + while(buf < bufend) {
165 + if (buf[1] > 127) /* inter? */
167 + buf += buf[3] > 127 ? 24 : 12; /* blend? */
172 +static int boxextract(unsigned char *buf, unsigned short *dp, unsigned char *cols, int *blendp)
174 + dp[0] = buf[0] | buf[1] << 8;
175 + dp[1] = buf[2] | buf[3] << 8;
176 + dp[2] = buf[4] | buf[5] << 8;
177 + dp[3] = buf[6] | buf[7] << 8;
178 + *(unsigned int *)(cols + 0) =
179 + *(unsigned int *)(cols + 4) =
180 + *(unsigned int *)(cols + 8) =
181 + *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 8);
182 + if (dp[1] > 32767) {
184 + *(unsigned int *)(cols + 4) = *(unsigned int *)(buf + 12);
185 + *(unsigned int *)(cols + 8) = *(unsigned int *)(buf + 16);
186 + *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 20);
193 +static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint)
195 + int x, y, i, p, doblend, r, g, b, a, add;
196 + unsigned short data1[4];
197 + unsigned char cols1[16];
198 + unsigned short data2[4];
199 + unsigned char cols2[16];
200 + unsigned char *bufend;
201 + unsigned short *picp;
202 + unsigned int stipple[32], sti, stin, stinn, stixs, stixe, stiys, stiye;
203 + int xs, xe, ys, ye, xo, yo;
207 + bufend = buf + num * 12;
208 + stipple[0] = 0xffffffff;
213 + while(buf < bufend) {
215 + buf += boxextract(buf, data1, cols1, &doblend);
216 + if (data1[0] == 32767 && data1[1] == 32767) {
224 + } else if (stinn == 4) {
228 + stipple[stinn++] = (cols1[ 0] << 24) | (cols1[ 1] << 16) | (cols1[ 2] << 8) | cols1[ 3] ;
229 + stipple[stinn++] = (cols1[ 4] << 24) | (cols1[ 5] << 16) | (cols1[ 6] << 8) | cols1[ 7] ;
230 + stipple[stinn++] = (cols1[ 8] << 24) | (cols1[ 9] << 16) | (cols1[10] << 8) | cols1[11] ;
231 + stipple[stinn++] = (cols1[12] << 24) | (cols1[13] << 16) | (cols1[14] << 8) | cols1[15] ;
236 + if (data1[0] > 32767)
237 + buf += boxextract(buf, data2, cols2, &doblend);
238 + if (data1[0] == 32767 && data1[1] == 32766) {
240 + i = 12 * (short)data1[3];
242 + i += boxextract(buf + i, data1, cols1, &doblend);
243 + if (data1[0] > 32767)
244 + boxextract(buf + i, data2, cols2, &doblend);
246 + if (data1[0] == 32767)
248 + if (data1[2] > 32767) {
251 + data1[2] = ~data1[2];
253 + if (data1[3] > 32767) {
254 + if (percent == 65536)
256 + data1[3] = ~data1[3];
258 + if (data1[0] > 32767) {
259 + data1[0] = ~data1[0];
260 + for (i = 0; i < 4; i++)
261 + data1[i] = (data1[i] * (65536 - percent) + data2[i] * percent) >> 16;
262 + for (i = 0; i < 16; i++)
263 + cols1[i] = (cols1[i] * (65536 - percent) + cols2[i] * percent) >> 16;
265 + *(unsigned int *)cols2 = *(unsigned int *)cols1;
267 + if (a == 0 && !doblend)
270 + if (stixs >= 32768) {
271 + xo = xs = (stixs ^ 65535) + data1[0];
272 + xe = stixe ? stixe + data1[0] : data1[2];
273 + } else if (stixe >= 32768) {
274 + xs = stixs ? data1[2] - stixs : data1[0];
275 + xe = data1[2] - (stixe ^ 65535);
279 + xe = stixe ? stixe : data1[2];
281 + if (stiys >= 32768) {
282 + yo = ys = (stiys ^ 65535) + data1[1];
283 + ye = stiye ? stiye + data1[1] : data1[3];
284 + } else if (stiye >= 32768) {
285 + ys = stiys ? data1[3] - stiys : data1[1];
286 + ye = data1[3] - (stiye ^ 65535);
290 + ye = stiye ? stiye : data1[3];
292 + xo = 32 - (xo & 31);
293 + yo = stin - (yo % stin);
303 + for (y = ys; y <= ye; y++) {
304 + sti = stipple[(y + yo) % stin];
305 + x = (xs + xo) & 31;
307 + sti = (sti << x) | (sti >> (32 - x));
309 + if ((p = data1[3] - data1[1]) != 0)
310 + p = ((y - data1[1]) << 16) / p;
311 + for (i = 0; i < 8; i++)
312 + cols2[i + 8] = (cols1[i] * (65536 - p) + cols1[i + 8] * p) >> 16;
315 + add ^= (add ^ y) & 1 ? 1 : 3; /* 2x2 ordered dithering */
316 + picp = (unsigned short *)(pic + xs * 2 + y * bytes);
317 + for (x = xs; x <= xe; x++) {
318 + if (!(sti & 0x80000000)) {
324 + sti = (sti << 1) | 1;
326 + if ((p = data1[2] - data1[0]) != 0)
327 + p = ((x - data1[0]) << 16) / p;
328 + for (i = 0; i < 4; i++)
329 + cols2[i] = (cols2[i + 8] * (65536 - p) + cols2[i + 12] * p) >> 16;
337 + r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
338 + g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
339 + b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
341 + #define CLAMP(x) ((x) >= 256 ? 255 : (x))
342 + i = ((CLAMP(r + add*2+1) & 0xf8) << 8) |
343 + ((CLAMP(g + add ) & 0xfc) << 3) |
344 + ((CLAMP(b + add*2+1) ) >> 3);
352 +static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth)
355 + unsigned char *mem;
357 + size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3);
358 + mem = vmalloc(size);
360 + printk(KERN_INFO "bootsplash: no memory for decoded picture.\n");
364 + decdata = vmalloc(sizeof(*decdata));
365 + if ((err = jpeg_decode(jpeg, mem, ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata)))
366 + printk(KERN_INFO "bootsplash: error while decompressing picture: %s (%d)\n",jpg_errors[err - 1], err);
368 + return err ? -1 : 0;
371 +static void splash_free(struct vc_data *vc, struct fb_info *info)
373 + if (!vc->vc_splash_data)
375 + if (info->silent_screen_base)
376 + info->screen_base = info->silent_screen_base;
377 + info->silent_screen_base = 0;
378 + if (vc->vc_splash_data->splash_silentjpeg)
379 + vfree(vc->vc_splash_data->splash_sboxes);
380 + vfree(vc->vc_splash_data);
381 + vc->vc_splash_data = 0;
382 + info->splash_data = 0;
385 +static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
387 + unsigned char *buf;
390 + if (pwi ==0 || phe == 0)
392 + buf = (unsigned char *)data + sizeof(*data);
407 + for (i = 0; i < 12; i++, buf++)
415 +static const int splash_offsets[3][16] = {
416 + /* len, unit, size, state, fgcol, col, xo, yo, wi, he
417 + boxcnt, ssize, sboxcnt, percent, overok, palcnt */
419 + { 20, -1, 16, -1, -1, -1, 8, 10, 12, 14,
420 + -1, -1, -1, -1, -1, -1 },
422 + { 35, 8, 12, 9, 10, 11, 16, 18, 20, 22,
423 + -1, -1, -1, -1, -1, -1 },
425 + { 38, 8, 12, 9, 10, 11, 16, 18, 20, 22,
426 + 24, 28, 32, 34, 36, 37 },
429 +#define SPLASH_OFF_LEN offsets[0]
430 +#define SPLASH_OFF_UNIT offsets[1]
431 +#define SPLASH_OFF_SIZE offsets[2]
432 +#define SPLASH_OFF_STATE offsets[3]
433 +#define SPLASH_OFF_FGCOL offsets[4]
434 +#define SPLASH_OFF_COL offsets[5]
435 +#define SPLASH_OFF_XO offsets[6]
436 +#define SPLASH_OFF_YO offsets[7]
437 +#define SPLASH_OFF_WI offsets[8]
438 +#define SPLASH_OFF_HE offsets[9]
439 +#define SPLASH_OFF_BOXCNT offsets[10]
440 +#define SPLASH_OFF_SSIZE offsets[11]
441 +#define SPLASH_OFF_SBOXCNT offsets[12]
442 +#define SPLASH_OFF_PERCENT offsets[13]
443 +#define SPLASH_OFF_OVEROK offsets[14]
444 +#define SPLASH_OFF_PALCNT offsets[15]
446 +static inline int splash_getb(unsigned char *pos, int off)
448 + return off == -1 ? 0 : pos[off];
451 +static inline int splash_gets(unsigned char *pos, int off)
453 + return off == -1 ? 0 : pos[off] | pos[off + 1] << 8;
456 +static inline int splash_geti(unsigned char *pos, int off)
458 + return off == -1 ? 0 :
459 + pos[off] | pos[off + 1] << 8 | pos[off + 2] << 16 | pos[off + 3] << 24;
462 +static int splash_getraw(unsigned char *start, unsigned char *end, int *update)
464 + unsigned char *ndata;
474 + const int *offsets;
475 + struct vc_data *vc;
476 + struct fb_info *info;
477 + struct splash_data *sd;
482 + if (!update || start[7] < '2' || start[7] > '3' || splash_geti(start, 12) != (int)0xffffffff)
483 + printk(KERN_INFO "bootsplash %s: looking for picture...", SPLASH_VERSION);
485 + for (ndata = start; ndata < end; ndata++) {
486 + if (ndata[0] != 'B' || ndata[1] != 'O' || ndata[2] != 'O' || ndata[3] != 'T')
488 + if (ndata[4] != 'S' || ndata[5] != 'P' || ndata[6] != 'L' || ndata[7] < '1' || ndata[7] > '3')
490 + version = ndata[7] - '0';
491 + offsets = splash_offsets[version - 1];
492 + len = SPLASH_OFF_LEN;
493 + unit = splash_getb(ndata, SPLASH_OFF_UNIT);
494 + if (unit >= MAX_NR_CONSOLES)
499 + vc = vc_cons[unit].d;
500 + info = registered_fb[(int)con2fb_map[unit]];
501 + width = info->var.xres;
502 + height = info->var.yres;
503 + splash_size = splash_geti(ndata, SPLASH_OFF_SIZE);
504 + if (splash_size == (int)0xffffffff && version > 1) {
505 + if ((sd = vc->vc_splash_data) != 0) {
507 + i = splash_getb(ndata, SPLASH_OFF_STATE);
509 + sd->splash_state = i;
512 + i = splash_getb(ndata, SPLASH_OFF_FGCOL);
514 + sd->splash_fg_color = i;
517 + i = splash_getb(ndata, SPLASH_OFF_COL);
519 + sd->splash_color = i;
522 + boxcnt = sboxcnt = 0;
523 + if (ndata + len <= end) {
524 + boxcnt = splash_gets(ndata, SPLASH_OFF_BOXCNT);
525 + sboxcnt = splash_gets(ndata, SPLASH_OFF_SBOXCNT);
528 + i = splash_gets(ndata, len);
529 + if (boxcnt + i <= sd->splash_boxcount && ndata + len + 2 + boxcnt * 12 <= end) {
531 + if (splash_geti(ndata, len + 2) != 0x7ffd7fff || !memcmp(ndata + len + 2, sd->splash_boxes + i * 12, 8)) {
533 + memcpy(sd->splash_boxes + i * 12, ndata + len + 2, boxcnt * 12);
537 + len += boxcnt * 12 + 2;
540 + i = splash_gets(ndata, len);
541 + if (sboxcnt + i <= sd->splash_sboxcount && ndata + len + 2 + sboxcnt * 12 <= end) {
542 + if (splash_geti(ndata, len + 2) != 0x7ffd7fff || !memcmp(ndata + len + 2, sd->splash_sboxes + i * 12, 8)) {
543 + memcpy(sd->splash_sboxes + i * 12, ndata + len + 2, sboxcnt * 12);
553 + if (splash_size == 0) {
554 + printk(KERN_INFO"...found, freeing memory.\n");
555 + if (vc->vc_splash_data)
556 + splash_free(vc, info);
559 + boxcnt = splash_gets(ndata, SPLASH_OFF_BOXCNT);
560 + palcnt = 3 * splash_getb(ndata, SPLASH_OFF_PALCNT);
561 + if (ndata + len + splash_size > end) {
562 + printk(KERN_INFO "...found, but truncated!\n");
565 + if (!jpeg_check_size(ndata + len + boxcnt * 12 + palcnt, width, height)) {
566 + ndata += len + splash_size - 1;
569 + if (splash_check_jpeg(ndata + len + boxcnt * 12 + palcnt, width, height, info->var.bits_per_pixel))
571 + silentsize = splash_geti(ndata, SPLASH_OFF_SSIZE);
573 + printk(KERN_INFO" silentjpeg size %d bytes,", silentsize);
574 + if (silentsize >= splash_size) {
575 + printk(KERN_INFO " bigger than splashsize!\n");
578 + splash_size -= silentsize;
579 + if (!splash_usesilent)
581 + else if (height * 2 * info->fix.line_length > info->fix.smem_len) {
582 + printk(KERN_INFO " does not fit into framebuffer.\n");
585 + sboxcnt = splash_gets(ndata, SPLASH_OFF_SBOXCNT);
587 + unsigned char *simage = ndata + len + splash_size + 12 * sboxcnt;
588 + if (!jpeg_check_size(simage, width, height) ||
589 + splash_check_jpeg(simage, width, height, info->var.bits_per_pixel)) {
590 + printk(KERN_INFO " error in silent jpeg.\n");
594 + if (vc->vc_splash_data)
595 + splash_free(vc, info);
596 + vc->vc_splash_data = sd = vmalloc(sizeof(*sd) + splash_size + (version < 3 ? 2 * 12 : 0));
599 + sd->splash_silentjpeg = 0;
600 + sd->splash_sboxes = 0;
601 + sd->splash_sboxcount = 0;
603 + sd->splash_silentjpeg = vmalloc(silentsize);
604 + if (sd->splash_silentjpeg) {
605 + memcpy(sd->splash_silentjpeg, ndata + len + splash_size, silentsize);
606 + sd->splash_sboxes = vc->vc_splash_data->splash_silentjpeg;
607 + sd->splash_silentjpeg += 12 * sboxcnt;
608 + sd->splash_sboxcount = sboxcnt;
611 + sd->splash_state = splash_getb(ndata, SPLASH_OFF_STATE);
612 + sd->splash_fg_color = splash_getb(ndata, SPLASH_OFF_FGCOL);
613 + sd->splash_color = splash_getb(ndata, SPLASH_OFF_COL);
614 + sd->splash_overpaintok = splash_getb(ndata, SPLASH_OFF_OVEROK);
615 + sd->splash_text_xo = splash_gets(ndata, SPLASH_OFF_XO);
616 + sd->splash_text_yo = splash_gets(ndata, SPLASH_OFF_YO);
617 + sd->splash_text_wi = splash_gets(ndata, SPLASH_OFF_WI);
618 + sd->splash_text_he = splash_gets(ndata, SPLASH_OFF_HE);
619 + sd->splash_percent = splash_gets(ndata, SPLASH_OFF_PERCENT);
620 + if (version == 1) {
621 + sd->splash_text_xo *= 8;
622 + sd->splash_text_wi *= 8;
623 + sd->splash_text_yo *= 16;
624 + sd->splash_text_he *= 16;
625 + sd->splash_color = (splash_default >> 8) & 0x0f;
626 + sd->splash_fg_color = (splash_default >> 4) & 0x0f;
627 + sd->splash_state = splash_default & 1;
629 + if (sd->splash_text_xo + sd->splash_text_wi > width || sd->splash_text_yo + sd->splash_text_he > height) {
630 + splash_free(vc, info);
631 + printk(KERN_INFO " found, but has oversized text area!\n");
634 +/* if (!vc_cons[unit].d || info->fbops != &vesafb_ops) {
635 + splash_free(vc, info);
636 + printk(KERN_INFO " found, but framebuffer can't handle it!\n");
639 + printk(KERN_INFO "...found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, version);
640 + if (version == 1) {
641 + printk(KERN_WARNING "bootsplash: Using deprecated v1 header. Updating your splash utility recommended.\n");
642 + printk(KERN_INFO "bootsplash: Find the latest version at http://www.bootsplash.org/\n");
645 + /* fake penguin box for older formats */
647 + boxcnt = splash_mkpenguin(sd, sd->splash_text_xo + 10, sd->splash_text_yo + 10, sd->splash_text_wi - 20, sd->splash_text_he - 20, 0xf0, 0xf0, 0xf0);
648 + else if (version == 2)
649 + boxcnt = splash_mkpenguin(sd, splash_gets(ndata, 24), splash_gets(ndata, 26), splash_gets(ndata, 28), splash_gets(ndata, 30), splash_getb(ndata, 32), splash_getb(ndata, 33), splash_getb(ndata, 34));
651 + memcpy((char *)sd + sizeof(*sd) + (version < 3 ? boxcnt * 12 : 0), ndata + len, splash_size);
652 + sd->splash_boxcount = boxcnt;
653 + sd->splash_boxes = (unsigned char *)sd + sizeof(*sd);
654 + sd->splash_palette = sd->splash_boxes + boxcnt * 12;
655 + sd->splash_jpeg = sd->splash_palette + palcnt;
656 + sd->splash_palcnt = palcnt / 3;
657 + sd->splash_dosilent = sd->splash_silentjpeg != 0;
660 + printk(KERN_INFO "...no good signature found.\n");
664 +int splash_verbose(void)
666 + struct vc_data *vc;
667 + struct fb_info *info;
669 + if (!splash_usesilent)
674 + if (!vc || !vc->vc_splash_data || !vc->vc_splash_data->splash_state)
676 + if (fg_console != vc->vc_num)
678 + if (!vc->vc_splash_data->splash_silentjpeg || !vc->vc_splash_data->splash_dosilent)
680 + vc->vc_splash_data->splash_dosilent = 0;
681 + info = registered_fb[(int)con2fb_map[0]];
682 + if (!info->silent_screen_base)
684 + splashcopy(info->silent_screen_base, info->screen_base, info->var.yres, info->var.xres, info->fix.line_length, info->fix.line_length);
685 + info->screen_base = info->silent_screen_base;
686 + info->silent_screen_base = 0;
690 +static void splash_off(struct fb_info *info)
692 + if (info->silent_screen_base)
693 + info->screen_base = info->silent_screen_base;
694 + info->silent_screen_base = 0;
695 + info->splash_data = 0;
696 + if (info->splash_pic)
697 + vfree(info->splash_pic);
698 + info->splash_pic = 0;
699 + info->splash_pic_size = 0;
702 +int splash_prepare(struct vc_data *vc, struct fb_info *info)
705 + int width, height, depth, size, sbytes;
707 + if (!vc->vc_splash_data || !vc->vc_splash_data->splash_state) {
715 + width = info->var.xres;
716 + height = info->var.yres;
717 + depth = info->var.bits_per_pixel;
718 + if (depth != 16) { /* Other targets might need fixing */
723 + sbytes = ((width + 15) & ~15) * (depth >> 3);
724 + size = sbytes * ((height + 15) & ~15);
725 + if (size != info->splash_pic_size)
727 + if (!info->splash_pic)
728 + info->splash_pic = vmalloc(size);
730 + if (!info->splash_pic) {
731 + printk(KERN_INFO "bootsplash: not enough memory.\n");
737 + decdata = vmalloc(sizeof(*decdata));
739 + if (vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent) {
740 + /* fill area after framebuffer with other jpeg */
741 + if ((err = jpeg_decode(vc->vc_splash_data->splash_silentjpeg, info->splash_pic,
742 + ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
743 + printk(KERN_INFO "bootsplash: error while decompressing silent picture: %s (%d)\n", jpg_errors[err - 1], err);
744 + if (info->silent_screen_base)
745 + info->screen_base = info->silent_screen_base;
746 + vc->vc_splash_data->splash_dosilent = 0;
748 + if (vc->vc_splash_data->splash_sboxcount)
749 + boxit(info->splash_pic, sbytes, vc->vc_splash_data->splash_sboxes,
750 + vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 0);
752 + if (!info->silent_screen_base)
753 + info->silent_screen_base = info->screen_base;
754 + splashcopy(info->silent_screen_base, info->splash_pic, info->var.yres, info->var.xres, info->fix.line_length, sbytes);
755 + info->screen_base = info->silent_screen_base + info->fix.line_length * info->var.yres;
757 + } else if (info->silent_screen_base)
758 + info->screen_base = info->silent_screen_base;
760 + if ((err = jpeg_decode(vc->vc_splash_data->splash_jpeg, info->splash_pic,
761 + ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
762 + printk(KERN_INFO "bootsplash: error while decompressing picture: %s (%d) .\n", jpg_errors[err - 1], err);
766 + info->splash_pic_size = size;
767 + info->splash_bytes = sbytes;
768 + if (vc->vc_splash_data->splash_boxcount)
769 + boxit(info->splash_pic, sbytes, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 0);
770 + if (vc->vc_splash_data->splash_state)
771 + info->splash_data = vc->vc_splash_data;
778 +#ifdef CONFIG_PROC_FS
780 +#include <linux/proc_fs.h>
782 +static int splash_read_proc(char *buffer, char **start, off_t offset, int size,
783 + int *eof, void *data);
784 +static int splash_write_proc(struct file *file, const char *buffer,
785 + unsigned long count, void *data);
786 +static int splash_status(struct vc_data *vc);
787 +static int splash_recolor(struct vc_data *vc);
788 +static int splash_proc_register(void);
790 +static struct proc_dir_entry *proc_splash;
792 +static int splash_recolor(struct vc_data *vc)
794 + if (!vc->vc_splash_data)
796 + if (!vc->vc_splash_data->splash_state)
798 + con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
799 + if (fg_console == vc->vc_num) {
800 + update_region(vc, vc->vc_origin + vc->vc_size_row * vc->vc_top,
801 + vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
806 +static int splash_status(struct vc_data *vc)
808 + struct fb_info *info;
809 + printk(KERN_INFO "bootsplash: status on console %d changed to %s\n", vc->vc_num, vc->vc_splash_data && vc->vc_splash_data->splash_state ? "on" : "off");
811 + info = registered_fb[(int) con2fb_map[vc->vc_num]];
812 + if (fg_console == vc->vc_num)
813 + splash_prepare(vc, info);
814 + if (vc->vc_splash_data && vc->vc_splash_data->splash_state) {
815 + con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
816 + /* vc_resize also calls con_switch which resets yscroll */
817 + vc_resize(vc, vc->vc_splash_data->splash_text_wi / vc->vc_font.width, vc->vc_splash_data->splash_text_he / vc->vc_font.height);
818 + if (fg_console == vc->vc_num) {
819 + update_region(vc, vc->vc_origin + vc->vc_size_row * vc->vc_top,
820 + vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
821 + splash_clear_margins(vc->vc_splash_data, vc, info, 0);
824 + /* Switch bootsplash off */
825 + con_remap_def_color(vc, 0x07);
826 + vc_resize(vc, info->var.xres / vc->vc_font.width, info->var.yres / vc->vc_font.height);
831 +static int splash_read_proc(char *buffer, char **start, off_t offset, int size,
832 + int *eof, void *data)
836 + struct vc_data *vc = vc_cons[0].d;
837 + struct fb_info *info = registered_fb[(int)con2fb_map[0]];
838 + int color = vc->vc_splash_data ? vc->vc_splash_data->splash_color << 4 |
839 + vc->vc_splash_data->splash_fg_color : splash_default >> 4;
840 + int status = vc->vc_splash_data ? vc->vc_splash_data->splash_state & 1 : 0;
841 + len += sprintf(buffer + len, "Splash screen v%s (0x%02x, %dx%d%s): %s\n",
842 + SPLASH_VERSION, color, info->var.xres, info->var.yres,
843 + (vc->vc_splash_data ? vc->vc_splash_data->splash_dosilent : 0)? ", silent" : "",
844 + status ? "on" : "off");
845 + if (offset >= begin + len)
848 + *start = buffer + (begin - offset);
850 + return (size < begin + len - offset ? size : begin + len - offset);
853 +static int splash_write_proc(struct file *file, const char *buffer,
854 + unsigned long count, void *data)
857 + struct vc_data *vc;
859 + if (!buffer || !splash_default)
862 + acquire_console_sem();
863 + if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
867 + if (buffer[4] == ' ' && buffer[5] == 'p')
869 + else if (buffer[4] == '\n')
872 + pe = simple_strtoul(buffer + 5, NULL, 0);
877 + if (*buffer == 'h')
880 + if (vc->vc_splash_data && vc->vc_splash_data->splash_percent != pe) {
881 + struct fb_info *info;
882 + struct fbcon_ops *ops;
884 + oldpe = vc->vc_splash_data->splash_percent;
885 + vc->vc_splash_data->splash_percent = pe;
886 + if (fg_console != 0 || !vc->vc_splash_data->splash_state) {
887 + release_console_sem();
890 + info = registered_fb[(int) con2fb_map[vc->vc_num]];
891 + ops = info->fbcon_par;
892 + if (ops->blank_state) {
893 + release_console_sem();
896 + if (!vc->vc_splash_data->splash_overpaintok || pe == 65536 || pe < oldpe) {
897 + if (splash_hasinter(vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount))
900 + splash_prepare(vc, info);
902 + if (vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent && info->silent_screen_base)
903 + boxit(info->silent_screen_base, info->fix.line_length, vc->vc_splash_data->splash_sboxes, vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 1);
904 + boxit(info->screen_base, info->fix.line_length, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 1);
907 + release_console_sem();
910 + if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) {
912 + if (vc->vc_splash_data && vc->vc_splash_data->splash_silentjpeg) {
913 + if (vc->vc_splash_data->splash_dosilent != (buffer[0] == 's')) {
914 + vc->vc_splash_data->splash_dosilent = buffer[0] == 's';
918 + release_console_sem();
921 + if (!strncmp(buffer,"freesilent\n",11)) {
923 + if (vc->vc_splash_data && vc->vc_splash_data->splash_silentjpeg) {
924 + printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
925 + vc->vc_splash_data->splash_silentjpeg = 0;
926 + vfree(vc->vc_splash_data->splash_sboxes);
927 + vc->vc_splash_data->splash_sboxes = 0;
928 + vc->vc_splash_data->splash_sboxcount = 0;
929 + if (vc->vc_splash_data->splash_dosilent)
931 + vc->vc_splash_data->splash_dosilent = 0;
933 + release_console_sem();
937 + if (!strncmp(buffer, "BOOTSPL", 7)) {
939 + unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count, &up);
941 + vc = vc_cons[unit].d;
945 + struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
946 + struct fbcon_ops *ops = info->fbcon_par;
947 + if (ops->blank_state)
949 + if ((up & 2) != 0 && vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent && info->silent_screen_base)
950 + boxit(info->silent_screen_base, info->fix.line_length, vc->vc_splash_data->splash_sboxes, vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 1);
952 + boxit(info->screen_base, info->fix.line_length, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 1);
955 + release_console_sem();
959 + if (!vc->vc_splash_data) {
960 + release_console_sem();
963 + if (buffer[0] == 't') {
964 + vc->vc_splash_data->splash_state ^= 1;
966 + release_console_sem();
969 + new = simple_strtoul(buffer, NULL, 0);
972 + vc->vc_splash_data->splash_color = new >> 8 & 0xff;
973 + vc->vc_splash_data->splash_fg_color = new >> 4 & 0x0f;
975 + if ((new & 1) == vc->vc_splash_data->splash_state)
976 + splash_recolor(vc);
978 + vc->vc_splash_data->splash_state = new & 1;
981 + release_console_sem();
985 +static int splash_proc_register(void)
987 + if ((proc_splash = create_proc_entry("splash", 0, 0))) {
988 + proc_splash->read_proc = splash_read_proc;
989 + proc_splash->write_proc = splash_write_proc;
996 +static int splash_proc_unregister(void)
999 + remove_proc_entry("splash", 0);
1003 +#endif /* CONFIG_PROC_FS */
1005 +void splash_init(void)
1007 + struct fb_info *info;
1008 + struct vc_data *vc;
1012 + int max_len = 1024*1024*2;
1015 + if (splash_registered)
1017 + vc = vc_cons[0].d;
1018 + info = registered_fb[0];
1019 + if (!vc || !info || info->var.bits_per_pixel != 16)
1021 +#ifdef CONFIG_PROC_FS
1022 + splash_proc_register();
1024 + splash_registered = 1;
1025 + if (vc->vc_splash_data)
1027 + if ((fd = sys_open("/bootsplash", O_RDONLY, 0)) < 0) {
1029 + fd = sys_open("/initrd.image", O_RDONLY, 0);
1033 + if ((len = (int)sys_lseek(fd, (off_t)0, 2)) <= 0) {
1037 + /* Don't look for more than the last 2MB */
1038 + if (len > max_len) {
1039 + printk( KERN_INFO "bootsplash: scanning last %dMB of initrd for signature\n",
1041 + sys_lseek(fd, (off_t)(len - max_len), 0);
1044 + sys_lseek(fd, (off_t)0, 0);
1047 + mem = vmalloc(len);
1049 + acquire_console_sem();
1050 + if ((int)sys_read(fd, mem, len) == len && splash_getraw((unsigned char *)mem, (unsigned char *)mem + len, (int *)0) == 0 && vc->vc_splash_data)
1051 + vc->vc_splash_data->splash_state = splash_default & 1;
1052 + release_console_sem();
1057 + sys_unlink("/bootsplash");
1061 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/bootsplash.h linux-2.6.32/drivers/video/bootsplash/bootsplash.h
1062 --- linux-2.6.32.old//drivers/video/bootsplash/bootsplash.h 1970-01-01 01:00:00.000000000 +0100
1063 +++ linux-2.6.32/drivers/video/bootsplash/bootsplash.h 2011-06-22 13:30:41.000000000 +0200
1066 + * linux/drivers/video/bootsplash/bootsplash.h - splash screen definition.
1068 + * (w) 2001-2003 by Volker Poplawski, <volker@poplawski.de>
1069 + * Stefan Reinauer, <stepan@suse.de>
1072 + * idea and SuSE screen work by Ken Wimer, <wimer@suse.de>
1075 +#ifndef __BOOTSPLASH_H
1076 +#define __BOOTSPLASH_H
1081 +extern int splash_prepare(struct vc_data *, struct fb_info *);
1082 +extern void splash_init(void);
1084 +/* splash_render.c */
1085 +extern void splash_putcs(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
1086 + const unsigned short *s, int count, int ypos, int xpos);
1087 +extern void splash_putc(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
1088 + int c, int ypos, int xpos);
1089 +extern void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes);
1090 +extern void splash_clear(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
1091 + int sx, int height, int width);
1092 +extern void splash_bmove(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
1093 + int sx, int dy, int dx, int height, int width);
1094 +extern void splash_clear_margins(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
1096 +extern int splash_cursor(struct splash_data *sd, struct fb_info *info, struct fb_cursor *cursor);
1097 +extern void splash_bmove_redraw(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
1098 + int y, int sx, int dx, int width);
1099 +extern void splash_blank(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
1103 +extern void con_remap_def_color(struct vc_data *, int new_color);
1105 +extern void acquire_console_sem(void);
1106 +extern void release_console_sem(void);
1109 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/decode-jpg.c linux-2.6.32/drivers/video/bootsplash/decode-jpg.c
1110 --- linux-2.6.32.old//drivers/video/bootsplash/decode-jpg.c 1970-01-01 01:00:00.000000000 +0100
1111 +++ linux-2.6.32/drivers/video/bootsplash/decode-jpg.c 2011-06-22 13:30:41.000000000 +0200
1114 + * linux/drivers/video/bootsplash/decode-jpg.c - a tiny jpeg decoder.
1116 + * (w) August 2001 by Michael Schroeder, <mls@suse.de>
1120 +#include <linux/string.h>
1121 +#include <asm/byteorder.h>
1123 +#include "decode-jpg.h"
1127 +#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
1128 +#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
1129 +#define ITOINT(a) ((a) >> ISHIFT)
1135 +/* special markers */
1136 +#define M_BADHUFF -1
1141 + unsigned int bits;
1145 + int (*func) __P((void *));
1149 +/*********************************/
1150 +struct dec_hufftbl;
1151 +struct enc_hufftbl;
1154 + struct dec_hufftbl *dhuff;
1155 + struct enc_hufftbl *ehuff;
1159 + int dc; /* old dc value */
1161 + union hufftblp hudc;
1162 + union hufftblp huac;
1163 + int next; /* when to switch to next scan */
1165 + int cid; /* component id */
1166 + int hv; /* horiz/vert, copied from comp */
1167 + int tq; /* quant tbl, copied from comp */
1170 +/*********************************/
1172 +#define DECBITS 10 /* seems to be the optimum */
1174 +struct dec_hufftbl {
1177 + unsigned char vals[256];
1178 + unsigned int llvals[1 << DECBITS];
1181 +static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
1182 +static int dec_readmarker __P((struct in *));
1183 +static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
1185 +static void setinput __P((struct in *, unsigned char *));
1186 +/*********************************/
1191 +static void idctqtab __P((unsigned char *, PREC *));
1192 +static void idct __P((int *, int *, PREC *, PREC, int));
1193 +static void scaleidctqtab __P((PREC *, PREC));
1195 +/*********************************/
1197 +static void initcol __P((PREC[][64]));
1199 +static void col221111 __P((int *, unsigned char *, int));
1200 +static void col221111_16 __P((int *, unsigned char *, int));
1202 +/*********************************/
1205 +#define M_APP0 0xe0
1207 +#define M_SOF0 0xc0
1211 +#define M_RST0 0xd0
1215 +static unsigned char *datap;
1217 +static int getbyte(void)
1222 +static int getword(void)
1227 + return c1 << 8 | c2;
1238 + int nc; /* number of components */
1239 + int ns; /* number of scans */
1240 + int dri; /* restart interval */
1241 + int nm; /* mcus til next marker */
1242 + int rm; /* next restart marker */
1245 +static struct jpginfo info;
1246 +static struct comp comps[MAXCOMP];
1248 +static struct scan dscans[MAXCOMP];
1250 +static unsigned char quant[4][64];
1252 +static struct dec_hufftbl dhuff[4];
1254 +#define dec_huffdc (dhuff + 0)
1255 +#define dec_huffac (dhuff + 2)
1257 +static struct in in;
1259 +static int readtables(int till)
1261 + int m, l, i, j, lq, pq, tq;
1265 + if (getbyte() != 0xff)
1267 + if ((m = getbyte()) == till)
1284 + for (i = 0; i < 64; i++)
1285 + quant[tq][i] = getbyte();
1293 + int hufflen[16], k;
1294 + unsigned char huffvals[256];
1300 + if (tc > 1 || th > 1)
1302 + for (i = 0; i < 16; i++)
1303 + hufflen[i] = getbyte();
1306 + for (i = 0; i < 16; i++) {
1307 + for (j = 0; j < hufflen[i]; j++)
1308 + huffvals[k++] = getbyte();
1311 + dec_makehuff(dhuff + tt, hufflen,
1318 + info.dri = getword();
1331 +static void dec_initscans(void)
1335 + info.nm = info.dri + 1;
1337 + for (i = 0; i < info.ns; i++)
1341 +static int dec_checkmarker(void)
1345 + if (dec_readmarker(&in) != info.rm)
1347 + info.nm = info.dri;
1348 + info.rm = (info.rm + 1) & ~0x08;
1349 + for (i = 0; i < info.ns; i++)
1354 +int jpeg_check_size(unsigned char *buf, int width, int height)
1359 + readtables(M_SOF0);
1362 + if (height != getword() || width != getword())
1367 +int jpeg_decode(buf, pic, width, height, depth, decdata)
1368 +unsigned char *buf, *pic;
1369 +int width, height, depth;
1370 +struct jpeg_decdata *decdata;
1372 + int i, j, m, tac, tdc;
1373 + int mcusx, mcusy, mx, my;
1376 + if (!decdata || !buf || !pic)
1379 + if (getbyte() != 0xff)
1380 + return ERR_NO_SOI;
1381 + if (getbyte() != M_SOI)
1382 + return ERR_NO_SOI;
1383 + if (readtables(M_SOF0))
1384 + return ERR_BAD_TABLES;
1388 + return ERR_NOT_8BIT;
1389 + if (((getword() + 15) & ~15) != height)
1390 + return ERR_HEIGHT_MISMATCH;
1391 + if (((getword() + 15) & ~15) != width)
1392 + return ERR_WIDTH_MISMATCH;
1393 + if ((height & 15) || (width & 15))
1394 + return ERR_BAD_WIDTH_OR_HEIGHT;
1395 + info.nc = getbyte();
1396 + if (info.nc > MAXCOMP)
1397 + return ERR_TOO_MANY_COMPPS;
1398 + for (i = 0; i < info.nc; i++) {
1400 + comps[i].cid = getbyte();
1401 + comps[i].hv = getbyte();
1402 + v = comps[i].hv & 15;
1403 + h = comps[i].hv >> 4;
1404 + comps[i].tq = getbyte();
1405 + if (h > 3 || v > 3)
1406 + return ERR_ILLEGAL_HV;
1407 + if (comps[i].tq > 3)
1408 + return ERR_QUANT_TABLE_SELECTOR;
1410 + if (readtables(M_SOS))
1411 + return ERR_BAD_TABLES;
1413 + info.ns = getbyte();
1415 + return ERR_NOT_YCBCR_221111;
1416 + for (i = 0; i < 3; i++) {
1417 + dscans[i].cid = getbyte();
1421 + if (tdc > 1 || tac > 1)
1422 + return ERR_QUANT_TABLE_SELECTOR;
1423 + for (j = 0; j < info.nc; j++)
1424 + if (comps[j].cid == dscans[i].cid)
1427 + return ERR_UNKNOWN_CID_IN_SCAN;
1428 + dscans[i].hv = comps[j].hv;
1429 + dscans[i].tq = comps[j].tq;
1430 + dscans[i].hudc.dhuff = dec_huffdc + tdc;
1431 + dscans[i].huac.dhuff = dec_huffac + tac;
1438 + if (i != 0 || j != 63 || m != 0)
1439 + return ERR_NOT_SEQUENTIAL_DCT;
1441 + if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
1442 + return ERR_NOT_YCBCR_221111;
1444 + if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
1445 + return ERR_NOT_YCBCR_221111;
1447 + mcusx = width >> 4;
1448 + mcusy = height >> 4;
1451 + idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
1452 + idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
1453 + idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
1454 + initcol(decdata->dquant);
1455 + setinput(&in, datap);
1458 + /* landing zone */
1460 + img[len + 1] = 0xff;
1461 + img[len + 2] = M_EOF;
1466 + dscans[0].next = 6 - 4;
1467 + dscans[1].next = 6 - 4 - 1;
1468 + dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
1469 + for (my = 0; my < mcusy; my++) {
1470 + for (mx = 0; mx < mcusx; mx++) {
1471 + if (info.dri && !--info.nm)
1472 + if (dec_checkmarker())
1473 + return ERR_WRONG_MARKER;
1475 + decode_mcus(&in, decdata->dcts, 6, dscans, max);
1476 + idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]);
1477 + idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]);
1478 + idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]);
1479 + idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]);
1480 + idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]);
1481 + idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
1485 + col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
1488 + col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
1491 + return ERR_DEPTH_MISMATCH;
1497 + m = dec_readmarker(&in);
1499 + return ERR_NO_EOI;
1504 +/****************************************************************/
1505 +/************** huffman decoder ***************/
1506 +/****************************************************************/
1508 +static int fillbits __P((struct in *, int, unsigned int));
1509 +static int dec_rec2
1510 +__P((struct in *, struct dec_hufftbl *, int *, int, int));
1512 +static void setinput(in, p)
1522 +static int fillbits(in, le, bi)
1531 + in->bits = bi << 16, le += 16;
1534 + while (le <= 24) {
1536 + if (b == 0xff && (m = *in->p++) != 0) {
1538 + if (in->func && (m = in->func(in->data)) == 0)
1543 + bi = bi << 16, le += 16;
1549 + in->bits = bi; /* tmp... 2 return values needed */
1553 +static int dec_readmarker(in)
1558 + in->left = fillbits(in, in->left, in->bits);
1559 + if ((m = in->marker) == 0)
1566 +#define LEBI_DCL int le, bi
1567 +#define LEBI_GET(in) (le = in->left, bi = in->bits)
1568 +#define LEBI_PUT(in) (in->left = le, in->bits = bi)
1570 +#define GETBITS(in, n) ( \
1571 + (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
1573 + bi >> le & ((1 << (n)) - 1) \
1576 +#define UNGETBITS(in, n) ( \
1581 +static int dec_rec2(in, hu, runp, c, i)
1583 +struct dec_hufftbl *hu;
1591 + UNGETBITS(in, i & 127);
1592 + *runp = i >> 8 & 15;
1595 + for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
1597 + in->marker = M_BADHUFF;
1600 + i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
1604 + if (i == 0) { /* sigh, 0xf0 is 11 bit */
1608 + /* receive part */
1609 + c = GETBITS(in, i);
1610 + if (c < (1 << (i - 1)))
1611 + c += (-1 << i) + 1;
1616 +#define DEC_REC(in, hu, r, i) ( \
1617 + r = GETBITS(in, DECBITS), \
1618 + i = hu->llvals[r], \
1621 + UNGETBITS(in, i & 127), \
1622 + r = i >> 8 & 15, \
1628 + i = dec_rec2(in, hu, &r, r, i), \
1634 +static void decode_mcus(in, dct, n, sc, maxp)
1641 + struct dec_hufftbl *hu;
1645 + memset(dct, 0, n * 64 * sizeof(*dct));
1648 + hu = sc->hudc.dhuff;
1649 + *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
1651 + hu = sc->huac.dhuff;
1654 + t = DEC_REC(in, hu, r, t);
1655 + if (t == 0 && r == 0) {
1664 + if (n == sc->next)
1670 +static void dec_makehuff(hu, hufflen, huffvals)
1671 +struct dec_hufftbl *hu;
1673 +unsigned char *huffvals;
1675 + int code, k, i, j, d, x, c, v;
1676 + for (i = 0; i < (1 << DECBITS); i++)
1677 + hu->llvals[i] = 0;
1682 + * value v already known, run r, backup u bits:
1683 + * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
1684 + * value unknown, size b bits, run r, backup u bits:
1685 + * 000000000000bbbb 0000 rrrr 0 uuuuuuu
1686 + * value and size unknown:
1687 + * 0000000000000000 0000 0000 0 0000000
1691 + for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
1692 + hu->valptr[i] = k;
1693 + for (j = 0; j < hufflen[i]; j++) {
1694 + hu->vals[k] = *huffvals++;
1695 + if (i < DECBITS) {
1696 + c = code << (DECBITS - 1 - i);
1697 + v = hu->vals[k] & 0x0f; /* size */
1698 + for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
1699 + if (v + i < DECBITS) { /* both fit in table */
1700 + x = d >> (DECBITS - 1 - v -
1702 + if (v && x < (1 << (v - 1)))
1703 + x += (-1 << v) + 1;
1704 + x = x << 16 | (hu-> vals[k] & 0xf0) << 4 |
1705 + (DECBITS - (i + 1 + v)) | 128;
1707 + x = v << 16 | (hu-> vals[k] & 0xf0) << 4 |
1708 + (DECBITS - (i + 1));
1709 + hu->llvals[c | d] = x;
1715 + hu->maxcode[i] = code;
1717 + hu->maxcode[16] = 0x20000; /* always terminate decode */
1720 +/****************************************************************/
1721 +/************** idct ***************/
1722 +/****************************************************************/
1724 +#define ONE ((PREC)IFIX(1.))
1725 +#define S2 ((PREC)IFIX(0.382683432))
1726 +#define C2 ((PREC)IFIX(0.923879532))
1727 +#define C4 ((PREC)IFIX(0.707106781))
1729 +#define S22 ((PREC)IFIX(2 * 0.382683432))
1730 +#define C22 ((PREC)IFIX(2 * 0.923879532))
1731 +#define IC4 ((PREC)IFIX(1 / 0.707106781))
1733 +#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
1734 +#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
1735 +#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
1737 +#define XPP(a,b) (t = a + b, b = a - b, a = t)
1738 +#define XMP(a,b) (t = a - b, b = a + b, a = t)
1739 +#define XPM(a,b) (t = a + b, b = b - a, a = t)
1741 +#define ROT(a,b,s,c) ( t = IMULT(a + b, s), \
1742 + a = IMULT(a, c - s) + t, \
1743 + b = IMULT(b, c + s) - t)
1749 + t2 = IMULT(t2, IC4) - t3, \
1755 + t5 = IMULT(t5, IC4), \
1756 + ROT(t4, t6, S22, C22),\
1766 +static unsigned char zig2[64] = {
1767 + 0, 2, 3, 9, 10, 20, 21, 35,
1768 + 14, 16, 25, 31, 39, 46, 50, 57,
1769 + 5, 7, 12, 18, 23, 33, 37, 48,
1770 + 27, 29, 41, 44, 52, 55, 59, 62,
1771 + 15, 26, 30, 40, 45, 51, 56, 58,
1772 + 1, 4, 8, 11, 19, 22, 34, 36,
1773 + 28, 42, 43, 53, 54, 60, 61, 63,
1774 + 6, 13, 17, 24, 32, 38, 47, 49
1777 +void idct(in, out, quant, off, max)
1784 + PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
1785 + PREC tmp[64], *tmpp;
1787 + unsigned char *zig2p;
1791 + t0 += in[0] * quant[0];
1792 + for (i = 0; i < 64; i++)
1793 + out[i] = ITOINT(t0);
1798 + for (i = 0; i < 8; i++) {
1800 + t0 += in[j] * quant[j];
1802 + t5 = in[j] * quant[j];
1804 + t2 = in[j] * quant[j];
1806 + t7 = in[j] * quant[j];
1808 + t1 = in[j] * quant[j];
1810 + t4 = in[j] * quant[j];
1812 + t3 = in[j] * quant[j];
1814 + t6 = in[j] * quant[j];
1827 + for (i = 0; i < 8; i++) {
1828 + t0 = tmp[8 * i + 0];
1829 + t1 = tmp[8 * i + 1];
1830 + t2 = tmp[8 * i + 2];
1831 + t3 = tmp[8 * i + 3];
1832 + t4 = tmp[8 * i + 4];
1833 + t5 = tmp[8 * i + 5];
1834 + t6 = tmp[8 * i + 6];
1835 + t7 = tmp[8 * i + 7];
1837 + out[8 * i + 0] = ITOINT(t0);
1838 + out[8 * i + 1] = ITOINT(t1);
1839 + out[8 * i + 2] = ITOINT(t2);
1840 + out[8 * i + 3] = ITOINT(t3);
1841 + out[8 * i + 4] = ITOINT(t4);
1842 + out[8 * i + 5] = ITOINT(t5);
1843 + out[8 * i + 6] = ITOINT(t6);
1844 + out[8 * i + 7] = ITOINT(t7);
1848 +static unsigned char zig[64] = {
1849 + 0, 1, 5, 6, 14, 15, 27, 28,
1850 + 2, 4, 7, 13, 16, 26, 29, 42,
1851 + 3, 8, 12, 17, 25, 30, 41, 43,
1852 + 9, 11, 18, 24, 31, 40, 44, 53,
1853 + 10, 19, 23, 32, 39, 45, 52, 54,
1854 + 20, 22, 33, 38, 46, 51, 55, 60,
1855 + 21, 34, 37, 47, 50, 56, 59, 61,
1856 + 35, 36, 48, 49, 57, 58, 62, 63
1859 +static PREC aaidct[8] = {
1860 + IFIX(0.3535533906), IFIX(0.4903926402),
1861 + IFIX(0.4619397663), IFIX(0.4157348062),
1862 + IFIX(0.3535533906), IFIX(0.2777851165),
1863 + IFIX(0.1913417162), IFIX(0.0975451610)
1867 +static void idctqtab(qin, qout)
1868 +unsigned char *qin;
1873 + for (i = 0; i < 8; i++)
1874 + for (j = 0; j < 8; j++)
1875 + qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
1876 + IMULT(aaidct[i], aaidct[j]);
1879 +static void scaleidctqtab(q, sc)
1885 + for (i = 0; i < 64; i++)
1886 + q[i] = IMULT(q[i], sc);
1889 +/****************************************************************/
1890 +/************** color decoder ***************/
1891 +/****************************************************************/
1896 + * YCbCr Color transformation:
1898 + * y:0..255 Cb:-128..127 Cr:-128..127
1900 + * R = Y + 1.40200 * Cr
1901 + * G = Y - 0.34414 * Cb - 0.71414 * Cr
1902 + * B = Y + 1.77200 * Cb
1907 + * Cg = 0.19421 * Cb + .50937 * Cr;
1913 + * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
1916 +static void initcol(q)
1919 + scaleidctqtab(q[1], IFIX(1.77200));
1920 + scaleidctqtab(q[2], IFIX(1.40200));
1923 +/* This is optimized for the stupid sun SUNWspro compiler. */
1924 +#define STORECLAMP(a,x) \
1927 + (unsigned int)(x) >= 256 ? \
1928 + ((a) = (x) < 0 ? 0 : 255) \
1933 +#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
1937 +#define CBCRCG(yin, xin) \
1939 + cb = outc[0 +yin*8+xin], \
1940 + cr = outc[64+yin*8+xin], \
1941 + cg = (50 * cb + 130 * cr + 128) >> 8 \
1946 +#define CBCRCG(yin, xin) \
1948 + cb = outc[0 +yin*8+xin], \
1949 + cr = outc[64+yin*8+xin], \
1950 + cg = (3 * cb + 8 * cr) >> 4 \
1955 +#define PIC(yin, xin, p, xout) \
1957 + y = outy[(yin) * 8 + xin], \
1958 + STORECLAMP(p[(xout) * 3 + 0], y + cr), \
1959 + STORECLAMP(p[(xout) * 3 + 1], y - cg), \
1960 + STORECLAMP(p[(xout) * 3 + 2], y + cb) \
1963 +#ifdef __LITTLE_ENDIAN
1964 +#define PIC_16(yin, xin, p, xout, add) \
1966 + y = outy[(yin) * 8 + xin], \
1967 + y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
1968 + ((CLAMP(y - cg + add ) & 0xfc) << 3) | \
1969 + ((CLAMP(y + cb + add*2+1) ) >> 3), \
1970 + p[(xout) * 2 + 0] = y & 0xff, \
1971 + p[(xout) * 2 + 1] = y >> 8 \
1975 +#define PIC_16(yin, xin, p, xout, add) \
1977 + y = outy[(yin) * 8 + xin], \
1978 + y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
1979 + ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
1980 + ((CLAMP(y + cb + add*2+1) ) >> 3), \
1981 + p[(xout) * 2 + 0] = y >> 8, \
1982 + p[(xout) * 2 + 1] = y & 0xff \
1985 +#define PIC_16(yin, xin, p, xout, add) \
1987 + y = outy[(yin) * 8 + xin], \
1988 + y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
1989 + ((CLAMP(y - cg + add ) & 0xfc) << 3) | \
1990 + ((CLAMP(y + cb + add*2+1) ) >> 3), \
1991 + p[(xout) * 2 + 0] = y >> 8, \
1992 + p[(xout) * 2 + 1] = y & 0xff \
1997 +#define PIC221111(xin) \
2000 + PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
2001 + PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
2002 + PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
2003 + PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
2006 +#define PIC221111_16(xin) \
2009 + PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
2010 + PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
2011 + PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
2012 + PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
2015 +static void col221111(out, pic, width)
2017 +unsigned char *pic;
2021 + unsigned char *pic0, *pic1;
2023 + int cr, cg, cb, y;
2026 + pic1 = pic + width;
2028 + outc = out + 64 * 4;
2029 + for (i = 2; i > 0; i--) {
2030 + for (j = 4; j > 0; j--) {
2031 + for (k = 0; k < 8; k++) {
2036 + pic0 += 2 * width;
2037 + pic1 += 2 * width;
2039 + outy += 64 * 2 - 16 * 4;
2043 +static void col221111_16(out, pic, width)
2045 +unsigned char *pic;
2049 + unsigned char *pic0, *pic1;
2051 + int cr, cg, cb, y;
2054 + pic1 = pic + width;
2056 + outc = out + 64 * 4;
2057 + for (i = 2; i > 0; i--) {
2058 + for (j = 4; j > 0; j--) {
2059 + for (k = 0; k < 8; k++) {
2064 + pic0 += 2 * width;
2065 + pic1 += 2 * width;
2067 + outy += 64 * 2 - 16 * 4;
2070 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/decode-jpg.h linux-2.6.32/drivers/video/bootsplash/decode-jpg.h
2071 --- linux-2.6.32.old//drivers/video/bootsplash/decode-jpg.h 1970-01-01 01:00:00.000000000 +0100
2072 +++ linux-2.6.32/drivers/video/bootsplash/decode-jpg.h 2011-06-22 13:30:41.000000000 +0200
2075 + * linux/drivers/video/bootsplash/decode-jpg.h - a tiny jpeg decoder.
2077 + * (w) August 2001 by Michael Schroeder, <mls@suse.de>
2080 +#ifndef __DECODE_JPG_H
2081 +#define __DECODE_JPG_H
2083 +#define ERR_NO_SOI 1
2084 +#define ERR_NOT_8BIT 2
2085 +#define ERR_HEIGHT_MISMATCH 3
2086 +#define ERR_WIDTH_MISMATCH 4
2087 +#define ERR_BAD_WIDTH_OR_HEIGHT 5
2088 +#define ERR_TOO_MANY_COMPPS 6
2089 +#define ERR_ILLEGAL_HV 7
2090 +#define ERR_QUANT_TABLE_SELECTOR 8
2091 +#define ERR_NOT_YCBCR_221111 9
2092 +#define ERR_UNKNOWN_CID_IN_SCAN 10
2093 +#define ERR_NOT_SEQUENTIAL_DCT 11
2094 +#define ERR_WRONG_MARKER 12
2095 +#define ERR_NO_EOI 13
2096 +#define ERR_BAD_TABLES 14
2097 +#define ERR_DEPTH_MISMATCH 15
2099 +struct jpeg_decdata {
2100 + int dcts[6 * 64 + 16];
2102 + int dquant[3][64];
2105 +extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int, struct jpeg_decdata *);
2106 +extern int jpeg_check_size(unsigned char *, int, int);
2109 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/Kconfig linux-2.6.32/drivers/video/bootsplash/Kconfig
2110 --- linux-2.6.32.old//drivers/video/bootsplash/Kconfig 1970-01-01 01:00:00.000000000 +0100
2111 +++ linux-2.6.32/drivers/video/bootsplash/Kconfig 2011-06-22 13:30:41.000000000 +0200
2114 +# Bootsplash configuration
2117 +menu "Bootsplash configuration"
2120 + bool "Bootup splash screen"
2121 + depends on FRAMEBUFFER_CONSOLE
2124 + This option enables the Linux bootsplash screen. For more
2125 + information on the bootsplash screen have a look at
2126 + http://www.bootsplash.org/.
2127 + If you are unsure, say N
2130 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/Makefile linux-2.6.32/drivers/video/bootsplash/Makefile
2131 --- linux-2.6.32.old//drivers/video/bootsplash/Makefile 1970-01-01 01:00:00.000000000 +0100
2132 +++ linux-2.6.32/drivers/video/bootsplash/Makefile 2011-06-22 13:30:41.000000000 +0200
2134 +# Makefile for the Linux bootsplash
2136 +obj-$(CONFIG_BOOTSPLASH) += bootsplash.o
2137 +obj-$(CONFIG_BOOTSPLASH) += decode-jpg.o
2138 +obj-$(CONFIG_BOOTSPLASH) += render.o
2139 diff -ruN linux-2.6.32.old//drivers/video/bootsplash/render.c linux-2.6.32/drivers/video/bootsplash/render.c
2140 --- linux-2.6.32.old//drivers/video/bootsplash/render.c 1970-01-01 01:00:00.000000000 +0100
2141 +++ linux-2.6.32/drivers/video/bootsplash/render.c 2011-06-22 13:30:41.000000000 +0200
2144 + * linux/drivers/video/bootsplash/render.c - splash screen render functions.
2147 +#include <linux/module.h>
2148 +#include <linux/types.h>
2149 +#include <linux/fb.h>
2150 +#include <linux/vt_kern.h>
2151 +#include <asm/irq.h>
2152 +#include <asm/system.h>
2154 +#include "../console/fbcon.h"
2155 +#include "bootsplash.h"
2157 +void splash_putcs(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
2158 + const unsigned short *s, int count, int ypos, int xpos)
2160 + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
2161 + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
2162 + int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
2164 + u8 *dst, *splashsrc;
2165 + unsigned int d, x, y;
2167 + u16 c = scr_readw(s);
2169 + int fg_color, bg_color, transparent;
2170 + fg_color = attr_fgcol(fgshift, c);
2171 + bg_color = attr_bgcol(bgshift, c);
2172 + transparent = sd->splash_color == bg_color;
2173 + xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
2174 + ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
2175 + splashsrc = (u8 *)(info->splash_pic + ypos * info->splash_bytes + xpos * 2);
2176 + dst = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * 2);
2178 + fgx = ((u32 *)info->pseudo_palette)[fg_color];
2179 + if (transparent && sd->splash_color == 15) {
2180 + if (fgx == 0xffea)
2182 + else if (fgx == 0x57ea)
2184 + else if (fgx == 0xffff)
2187 + bgx = ((u32 *)info->pseudo_palette)[bg_color];
2191 + c = scr_readw(s++);
2192 + src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
2194 + for (y = 0; y < vc->vc_font.height; y++) {
2195 + for (x = 0; x < vc->vc_font.width; x += 2) {
2201 + dd = transparent ? *(u16 *)splashsrc : bgx;
2206 + dd |= (transparent ? *(u16 *)splashsrc : bgx) << 16;
2209 + fb_writel(dd, dst);
2212 + dst += info->fix.line_length - vc->vc_font.width * 2;
2213 + splashsrc += info->splash_bytes - vc->vc_font.width * 2;
2215 + dst -= info->fix.line_length * vc->vc_font.height - vc->vc_font.width * 2;
2216 + splashsrc -= info->splash_bytes * vc->vc_font.height - vc->vc_font.width * 2;
2220 +static void splash_renderc(struct splash_data *sd, struct fb_info *info, int fg_color, int bg_color, u8 *src, int ypos, int xpos, int height, int width)
2222 + int transparent = sd->splash_color == bg_color;
2224 + u8 *dst, *splashsrc;
2225 + unsigned int d, x, y;
2227 + splashsrc = (u8 *)(info->splash_pic + ypos * info->splash_bytes + xpos * 2);
2228 + dst = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * 2);
2229 + fgx = ((u32 *)info->pseudo_palette)[fg_color];
2230 + if (transparent && sd->splash_color == 15) {
2231 + if (fgx == 0xffea)
2233 + else if (fgx == 0x57ea)
2235 + else if (fgx == 0xffff)
2238 + bgx = ((u32 *)info->pseudo_palette)[bg_color];
2240 + for (y = 0; y < height; y++) {
2241 + for (x = 0; x < width; x += 2) {
2247 + dd = transparent ? *(u16 *)splashsrc : bgx;
2252 + dd |= (transparent ? *(u16 *)splashsrc : bgx) << 16;
2255 + fb_writel(dd, dst);
2258 + dst += info->fix.line_length - width * 2;
2259 + splashsrc += info->splash_bytes - width * 2;
2263 +void splash_putc(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
2264 + int c, int ypos, int xpos)
2266 + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
2267 + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
2268 + int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
2269 + u8 *src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
2270 + xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
2271 + ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
2272 + splash_renderc(sd, info, attr_fgcol(fgshift, c), attr_bgcol(bgshift, c), src, ypos, xpos, vc->vc_font.height, vc->vc_font.width);
2275 +void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes)
2279 + while (height-- > 0) {
2280 + u32 *p = (u32 *)dst;
2281 + u32 *q = (u32 *)src;
2282 + for (i=0; i < width/4; i++) {
2283 + fb_writel(*q++,p++);
2284 + fb_writel(*q++,p++);
2287 + fb_writel(*q++,p++);
2289 + fb_writew(*(u16*)q,(u16*)p);
2295 +static void splashset(u8 *dst, int height, int width, int dstbytes, u32 bgx) {
2299 + while (height-- > 0) {
2300 + u32 *p = (u32 *)dst;
2301 + for (i=0; i < width/4; i++) {
2302 + fb_writel(bgx,p++);
2303 + fb_writel(bgx,p++);
2306 + fb_writel(bgx,p++);
2308 + fb_writew(bgx,(u16*)p);
2313 +static void splashfill(struct fb_info *info, int sy, int sx, int height, int width) {
2314 + splashcopy((u8 *)(info->screen_base + sy * info->fix.line_length + sx * 2), (u8 *)(info->splash_pic + sy * info->splash_bytes + sx * 2), height, width, info->fix.line_length, info->splash_bytes);
2317 +void splash_clear(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
2318 + int sx, int height, int width)
2320 + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
2321 + int bg_color = attr_bgcol_ec(bgshift, vc, info);
2322 + int transparent = sd->splash_color == bg_color;
2326 + sy = sy * vc->vc_font.height + sd->splash_text_yo;
2327 + sx = sx * vc->vc_font.width + sd->splash_text_xo;
2328 + height *= vc->vc_font.height;
2329 + width *= vc->vc_font.width;
2330 + if (transparent) {
2331 + splashfill(info, sy, sx, height, width);
2334 + dst = (u8 *)(info->screen_base + sy * info->fix.line_length + sx * 2);
2335 + bgx = ((u32 *)info->pseudo_palette)[bg_color];
2336 + splashset(dst, height, width, info->fix.line_length, bgx);
2339 +void splash_bmove(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
2340 + int sx, int dy, int dx, int height, int width)
2342 + struct fb_copyarea area;
2344 + area.sx = sx * vc->vc_font.width;
2345 + area.sy = sy * vc->vc_font.height;
2346 + area.dx = dx * vc->vc_font.width;
2347 + area.dy = dy * vc->vc_font.height;
2348 + area.sx += sd->splash_text_xo;
2349 + area.sy += sd->splash_text_yo;
2350 + area.dx += sd->splash_text_xo;
2351 + area.dy += sd->splash_text_yo;
2352 + area.height = height * vc->vc_font.height;
2353 + area.width = width * vc->vc_font.width;
2355 + info->fbops->fb_copyarea(info, &area);
2358 +void splash_clear_margins(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
2361 + unsigned int tw = vc->vc_cols*vc->vc_font.width;
2362 + unsigned int th = vc->vc_rows*vc->vc_font.height;
2364 + if (!bottom_only) {
2366 + splashfill(info, 0, 0, sd->splash_text_yo, info->var.xres);
2368 + splashfill(info, sd->splash_text_yo, 0, th, sd->splash_text_xo);
2369 + /* right margin */
2370 + splashfill(info, sd->splash_text_yo, sd->splash_text_xo + tw, th, info->var.xres - sd->splash_text_xo - tw);
2373 + splashfill(info, sd->splash_text_yo + th, 0, info->var.yres - sd->splash_text_yo - th, info->var.xres);
2376 +int splash_cursor(struct splash_data *sd, struct fb_info *info, struct fb_cursor *cursor)
2379 + unsigned int dsize, s_pitch;
2381 + if (info->state != FBINFO_STATE_RUNNING)
2384 + s_pitch = (cursor->image.width + 7) >> 3;
2385 + dsize = s_pitch * cursor->image.height;
2386 + if (cursor->enable) {
2387 + switch (cursor->rop) {
2389 + for (i = 0; i < dsize; i++)
2390 + info->fb_cursordata[i] = cursor->image.data[i] ^ cursor->mask[i];
2394 + for (i = 0; i < dsize; i++)
2395 + info->fb_cursordata[i] = cursor->image.data[i] & cursor->mask[i];
2398 + } else if (info->fb_cursordata != cursor->image.data)
2399 + memcpy(info->fb_cursordata, cursor->image.data, dsize);
2400 + cursor->image.data = info->fb_cursordata;
2401 + splash_renderc(sd, info, cursor->image.fg_color, cursor->image.bg_color, (u8 *)info->fb_cursordata, cursor->image.dy + sd->splash_text_yo, cursor->image.dx + sd->splash_text_xo, cursor->image.height, cursor->image.width);
2405 +void splash_bmove_redraw(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width)
2407 + unsigned short *d = (unsigned short *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
2408 + unsigned short *s = d + (dx - sx);
2409 + unsigned short *start = d;
2410 + unsigned short *ls = d;
2411 + unsigned short *le = d + width;
2414 + unsigned short attr = 1;
2418 + if (attr != (c & 0xff00)) {
2419 + attr = c & 0xff00;
2421 + splash_putcs(sd, vc, info, start, d - start, y, x);
2426 + if (s >= ls && s < le && c == scr_readw(s)) {
2428 + splash_putcs(sd, vc, info, start, d - start, y, x);
2429 + x += d - start + 1;
2440 + splash_putcs(sd, vc, info, start, d - start, y, x);
2443 +void splash_blank(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int blank)
2446 + if (info->silent_screen_base)
2447 + splashset((u8 *)info->silent_screen_base, info->var.yres, info->var.xres, info->fix.line_length, 0);
2448 + splashset((u8 *)info->screen_base, info->var.yres, info->var.xres, info->fix.line_length, 0);
2450 + if (info->silent_screen_base)
2451 + splash_prepare(vc, info);
2452 + splash_clear_margins(vc->vc_splash_data, vc, info, 0);
2453 + /* no longer needed, done in fbcon_blank */
2454 + /* update_screen(vc->vc_num); */
2458 diff -ruN linux-2.6.32.old//drivers/video/console/bitblit.c linux-2.6.32/drivers/video/console/bitblit.c
2459 --- linux-2.6.32.old//drivers/video/console/bitblit.c 2009-12-03 04:51:21.000000000 +0100
2460 +++ linux-2.6.32/drivers/video/console/bitblit.c 2011-06-22 13:30:41.000000000 +0200
2462 #include <linux/console.h>
2463 #include <asm/types.h>
2465 +#ifdef CONFIG_BOOTSPLASH
2466 +#include "../bootsplash/bootsplash.h"
2470 * Accelerated handlers.
2473 struct fb_copyarea area;
2475 +#ifdef CONFIG_BOOTSPLASH
2476 + if (info->splash_data) {
2477 + splash_bmove(info->splash_data, vc, info,
2478 + sy, sx, dy, dx, height, width);
2482 area.sx = sx * vc->vc_font.width;
2483 area.sy = sy * vc->vc_font.height;
2484 area.dx = dx * vc->vc_font.width;
2486 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
2487 struct fb_fillrect region;
2489 +#ifdef CONFIG_BOOTSPLASH
2490 + if (info->splash_data) {
2491 + splash_clear(info->splash_data, vc, info,
2492 + sy, sx, height, width);
2496 region.color = attr_bgcol_ec(bgshift, vc, info);
2497 region.dx = sx * vc->vc_font.width;
2498 region.dy = sy * vc->vc_font.height;
2499 @@ -160,6 +177,13 @@
2500 image.height = vc->vc_font.height;
2503 +#ifdef CONFIG_BOOTSPLASH
2504 + if (info->splash_data) {
2505 + splash_putcs(info->splash_data, vc, info, s, count, yy, xx);
2511 buf = kmalloc(cellsize, GFP_KERNEL);
2513 @@ -213,6 +237,13 @@
2514 unsigned int bs = info->var.yres - bh;
2515 struct fb_fillrect region;
2517 +#ifdef CONFIG_BOOTSPLASH
2518 + if (info->splash_data) {
2519 + splash_clear_margins(info->splash_data, vc, info, bottom_only);
2524 region.color = attr_bgcol_ec(bgshift, vc, info);
2525 region.rop = ROP_COPY;
2527 @@ -379,6 +410,14 @@
2528 cursor.image.depth = 1;
2529 cursor.rop = ROP_XOR;
2531 +#ifdef CONFIG_BOOTSPLASH
2532 + if (info->splash_data) {
2533 + splash_cursor(info->splash_data, info, &cursor);
2534 + ops->cursor_reset = 0;
2539 if (info->fbops->fb_cursor)
2540 err = info->fbops->fb_cursor(info, &cursor);
2542 diff -ruN linux-2.6.32.old//drivers/video/console/fbcon.c linux-2.6.32/drivers/video/console/fbcon.c
2543 --- linux-2.6.32.old//drivers/video/console/fbcon.c 2011-05-10 20:38:07.000000000 +0200
2544 +++ linux-2.6.32/drivers/video/console/fbcon.c 2011-06-22 13:30:41.000000000 +0200
2549 +#ifdef CONFIG_BOOTSPLASH
2550 +#include "../bootsplash/bootsplash.h"
2554 # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
2559 static struct display fb_display[MAX_NR_CONSOLES];
2561 -static signed char con2fb_map[MAX_NR_CONSOLES];
2562 +signed char con2fb_map[MAX_NR_CONSOLES];
2563 static signed char con2fb_map_boot[MAX_NR_CONSOLES];
2565 static int logo_lines;
2566 @@ -538,6 +541,10 @@
2567 for (i = first_fb_vc; i <= last_fb_vc; i++)
2568 con2fb_map[i] = info_idx;
2570 +#ifdef CONFIG_BOOTSPLASH
2574 err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
2577 @@ -1103,6 +1110,16 @@
2578 new_cols /= vc->vc_font.width;
2579 new_rows /= vc->vc_font.height;
2581 +#ifdef CONFIG_BOOTSPLASH
2582 + if (vc->vc_splash_data && vc->vc_splash_data->splash_state) {
2583 + new_cols = vc->vc_splash_data->splash_text_wi / vc->vc_font.width;
2584 + new_rows = vc->vc_splash_data->splash_text_he / vc->vc_font.height;
2586 + con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
2587 + /* vc_resize(vc, new_cols, new_rows); */
2592 * We must always set the mode. The mode of the previous console
2593 * driver could be in the same resolution but we are using different
2594 @@ -1804,6 +1821,10 @@
2595 fbcon_softback_note(vc, t, count);
2596 if (logo_shown >= 0)
2598 +#ifdef CONFIG_BOOTSPLASH
2599 + if (info->splash_data)
2602 switch (p->scrollmode) {
2604 fbcon_redraw_blit(vc, info, p, t, b - t - count,
2605 @@ -1893,6 +1914,10 @@
2607 if (count > vc->vc_rows) /* Maximum realistic size */
2608 count = vc->vc_rows;
2609 +#ifdef CONFIG_BOOTSPLASH
2610 + if (info->splash_data)
2613 if (logo_shown >= 0)
2615 switch (p->scrollmode) {
2616 @@ -2043,6 +2068,14 @@
2621 +#ifdef CONFIG_BOOTSPLASH
2622 + if (info->splash_data && sy == dy && height == 1) {
2623 + /* must use slower redraw bmove to keep background pic intact */
2624 + splash_bmove_redraw(info->splash_data, vc, info, sy, sx, dx, width);
2628 ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2631 @@ -2151,6 +2184,10 @@
2632 info = registered_fb[con2fb_map[vc->vc_num]];
2633 ops = info->fbcon_par;
2635 +#ifdef CONFIG_BOOTSPLASH
2636 + splash_prepare(vc, info);
2641 fbcon_set_origin(vc);
2642 @@ -2284,6 +2321,12 @@
2644 struct fb_event event;
2646 +#ifdef CONFIG_BOOTSPLASH
2647 + if (info->splash_data) {
2648 + splash_blank(info->splash_data, vc, info, blank);
2653 unsigned short charmask = vc->vc_hi_font_mask ?
2655 @@ -2483,10 +2526,19 @@
2659 + u32 xres = info->var.xres, yres = info->var.yres;
2660 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2661 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2665 +#ifdef CONFIG_BOOTSPLASH
2666 + if (info->splash_data) {
2667 + xres = info->splash_data->splash_text_wi;
2668 + yres = info->splash_data->splash_text_he;
2672 vc_resize(vc, cols, rows);
2673 if (CON_IS_VISIBLE(vc) && softback_buf)
2674 fbcon_update_softback(vc);
2675 diff -ruN linux-2.6.32.old//drivers/video/console/fbcon.h linux-2.6.32/drivers/video/console/fbcon.h
2676 --- linux-2.6.32.old//drivers/video/console/fbcon.h 2009-12-03 04:51:21.000000000 +0100
2677 +++ linux-2.6.32/drivers/video/console/fbcon.h 2011-06-22 13:30:41.000000000 +0200
2679 * low-level frame buffer device
2682 +#ifdef CONFIG_BOOTSPLASH
2683 +struct splash_data {
2684 + int splash_state; /* show splash? */
2685 + int splash_color; /* transparent color */
2686 + int splash_fg_color; /* foreground color */
2687 + int splash_width; /* width of image */
2688 + int splash_height; /* height of image */
2689 + int splash_text_xo; /* text area origin */
2690 + int splash_text_yo;
2691 + int splash_text_wi; /* text area size */
2692 + int splash_text_he;
2693 + int splash_showtext; /* silent/verbose mode */
2694 + int splash_boxcount;
2695 + int splash_percent;
2696 + int splash_overpaintok; /* is it ok to overpaint boxes */
2697 + int splash_palcnt;
2698 + char *oldscreen_base; /* pointer to top of virtual screen */
2699 + unsigned char *splash_boxes;
2700 + unsigned char *splash_jpeg; /* jpeg */
2701 + unsigned char *splash_palette; /* palette for 8-bit */
2703 + int splash_dosilent; /* show silent jpeg */
2704 + unsigned char *splash_silentjpeg;
2705 + unsigned char *splash_sboxes;
2706 + int splash_sboxcount;
2711 /* Filled in by the low-level console driver */
2712 const u_char *fontdata;
2713 diff -ruN linux-2.6.32.old//drivers/video/Kconfig linux-2.6.32/drivers/video/Kconfig
2714 --- linux-2.6.32.old//drivers/video/Kconfig 2009-12-03 04:51:21.000000000 +0100
2715 +++ linux-2.6.32/drivers/video/Kconfig 2011-06-22 13:30:41.000000000 +0200
2716 @@ -2173,4 +2173,8 @@
2717 source "drivers/video/logo/Kconfig"
2721 + source "drivers/video/bootsplash/Kconfig"
2725 diff -ruN linux-2.6.32.old//drivers/video/Makefile linux-2.6.32/drivers/video/Makefile
2726 --- linux-2.6.32.old//drivers/video/Makefile 2009-12-03 04:51:21.000000000 +0100
2727 +++ linux-2.6.32/drivers/video/Makefile 2011-06-22 13:30:41.000000000 +0200
2729 obj-$(CONFIG_VT) += console/
2730 obj-$(CONFIG_LOGO) += logo/
2731 obj-y += backlight/ display/
2732 +obj-$(CONFIG_BOOTSPLASH) += bootsplash/
2734 obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
2735 obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
2736 diff -ruN linux-2.6.32.old//drivers/video/vesafb.c linux-2.6.32/drivers/video/vesafb.c
2737 --- linux-2.6.32.old//drivers/video/vesafb.c 2011-05-10 20:38:07.000000000 +0200
2738 +++ linux-2.6.32/drivers/video/vesafb.c 2011-06-22 13:30:41.000000000 +0200
2739 @@ -182,7 +182,10 @@
2740 framebuffer_release(info);
2743 -static struct fb_ops vesafb_ops = {
2744 +#ifndef CONFIG_BOOTSPLASH
2747 +struct fb_ops vesafb_ops = {
2748 .owner = THIS_MODULE,
2749 .fb_destroy = vesafb_destroy,
2750 .fb_setcolreg = vesafb_setcolreg,
2751 @@ -267,6 +270,11 @@
2752 * option to simply use size_total as that
2753 * wastes plenty of kernel address space. */
2754 size_remap = size_vmode * 2;
2756 +#ifdef CONFIG_BOOTSPLASH
2757 + size_remap *= 2; /* some more for the images */
2761 size_remap = vram_remap * 1024 * 1024;
2762 if (size_remap < size_vmode)
2763 diff -ruN linux-2.6.32.old//include/linux/console_struct.h linux-2.6.32/include/linux/console_struct.h
2764 --- linux-2.6.32.old//include/linux/console_struct.h 2011-05-10 20:37:43.000000000 +0200
2765 +++ linux-2.6.32/include/linux/console_struct.h 2011-06-22 13:32:46.000000000 +0200
2766 @@ -106,6 +106,11 @@
2767 unsigned long vc_uni_pagedir;
2768 unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
2769 bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
2771 +#ifdef CONFIG_BOOTSPLASH
2772 + struct splash_data *vc_splash_data;
2775 /* additional information is in vt_kern.h */
2778 diff -ruN linux-2.6.32.old//include/linux/fb.h linux-2.6.32/include/linux/fb.h
2779 --- linux-2.6.32.old//include/linux/fb.h 2011-05-10 20:38:23.000000000 +0200
2780 +++ linux-2.6.32/include/linux/fb.h 2011-06-22 13:30:41.000000000 +0200
2781 @@ -863,6 +863,16 @@
2782 void *fbcon_par; /* fbcon use-only private area */
2783 /* From here on everything is device dependent */
2786 +#ifdef CONFIG_BOOTSPLASH
2787 + struct splash_data *splash_data;
2788 + unsigned char *splash_pic;
2789 + int splash_pic_size;
2791 + char *silent_screen_base; /* real screen base */
2792 + char fb_cursordata[64];
2795 /* we need the PCI or similiar aperture base/size not
2796 smem_start/size as smem_start may just be an object
2797 allocated inside the aperture so may not actually overlap */