]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/bootsplash-3.0.7-2.4.31-vanilla.diff
Wir kehren zurueck zu Kudzu, da hwinfo noch mehr Aerger macht.
[people/teissler/ipfire-2.x.git] / src / patches / bootsplash-3.0.7-2.4.31-vanilla.diff
CommitLineData
55ab9063
HS
1diff -ruN linux-2.4.31/drivers/char/console.c linux-2.4.31-bs/drivers/char/console.c
2--- linux-2.4.31/drivers/char/console.c 2005-01-19 14:09:44.000000000 +0000
3+++ linux-2.4.31-bs/drivers/char/console.c 2005-05-05 22:20:15.000000000 +0100
4@@ -3031,6 +3031,32 @@
5 return 0;
6 }
7
8+#ifdef CONFIG_FBCON_SPLASHSCREEN
9+void con_remap_def_color(int currcons, int new_color)
10+{
11+ unsigned short *sbuf = screenbuf;
12+ unsigned c, len = screenbuf_size >> 1;
13+ int old_color;
14+
15+ if (sbuf) {
16+ old_color = def_color << 8;
17+ new_color <<= 8;
18+ while(len--) {
19+ c = *sbuf;
20+ if (((c ^ old_color) & 0xf000) == 0)
21+ *sbuf ^= (old_color ^ new_color) & 0xf000;
22+ if (((c ^ old_color) & 0x0f00) == 0)
23+ *sbuf ^= (old_color ^ new_color) & 0x0f00;
24+ sbuf++;
25+ }
26+ new_color >>= 8;
27+ }
28+ def_color = color = new_color;
29+ update_attr(currcons);
30+}
31+#endif
32+
33+
34 /*
35 * Visible symbols for modules
36 */
37diff -ruN linux-2.4.31/drivers/char/keyboard.c linux-2.4.31-bs/drivers/char/keyboard.c
38--- linux-2.4.31/drivers/char/keyboard.c 2003-11-28 18:26:20.000000000 +0000
39+++ linux-2.4.31-bs/drivers/char/keyboard.c 2005-05-05 22:27:48.000000000 +0100
40@@ -263,6 +263,15 @@
41 } else
42 rep = test_and_set_bit(keycode, key_down);
43
44+#ifdef CONFIG_FBCON_SPLASHSCREEN
45+ /* This code has to be redone for some non-x86 platforms */
46+ if (keycode == 0x3c || keycode == 0x01) { /* F2 and ESC on a PC keyboard */
47+ extern int splash_verbose(void);
48+ if (splash_verbose())
49+ goto out;
50+ }
51+#endif
52+
53 #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
54 if (keycode == SYSRQ_KEY) {
55 sysrq_pressed = !up_flag;
56diff -ruN linux-2.4.31/drivers/char/n_tty.c linux-2.4.31-bs/drivers/char/n_tty.c
57--- linux-2.4.31/drivers/char/n_tty.c 2005-01-19 14:09:47.000000000 +0000
58+++ linux-2.4.31-bs/drivers/char/n_tty.c 2005-05-05 22:14:50.000000000 +0100
59@@ -45,6 +45,7 @@
60 #include <linux/string.h>
61 #include <linux/slab.h>
62 #include <linux/poll.h>
63+#include <linux/config.h>
64
65 #include <asm/uaccess.h>
66 #include <asm/system.h>
67@@ -1184,6 +1185,17 @@
68 return -EIO;
69 }
70
71+#ifdef CONFIG_FBCON_SPLASHSCREEN
72+ if (file->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
73+ file->f_dentry->d_inode->i_rdev == SYSCONS_DEV ||
74+ file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) ||
75+ file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1)) {
76+ extern int splash_verbose(void);
77+ (void)splash_verbose();
78+ }
79+#endif
80+
81+
82 c = job_control(tty, file);
83 if(c < 0)
84 return c;
85diff -ruN linux-2.4.31/drivers/video/Config.in linux-2.4.31-bs/drivers/video/Config.in
86--- linux-2.4.31/drivers/video/Config.in 2004-02-18 13:36:31.000000000 +0000
87+++ linux-2.4.31-bs/drivers/video/Config.in 2005-05-05 22:24:55.000000000 +0100
88@@ -239,13 +239,20 @@
89 tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
90 fi
91
92+ dep_bool ' Use splash screen instead of boot logo' CONFIG_FBCON_SPLASHSCREEN $CONFIG_BLK_DEV_INITRD
93+ if [ "$CONFIG_FBCON_SPLASHSCREEN" = "y" ]; then
94+ define_bool CONFIG_FBCON_CFB16 y
95+ fi
96+
97 bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED
98 if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
99 tristate ' Monochrome support' CONFIG_FBCON_MFB
100 tristate ' 2 bpp packed pixels support' CONFIG_FBCON_CFB2
101 tristate ' 4 bpp packed pixels support' CONFIG_FBCON_CFB4
102 tristate ' 8 bpp packed pixels support' CONFIG_FBCON_CFB8
103- tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16
104+ if [ "$CONFIG_FBCON_SPLASHSCREEN" != "y" ]; then
105+ tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16
106+ fi
107 tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24
108 tristate ' 32 bpp packed pixels support' CONFIG_FBCON_CFB32
109 tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB
110@@ -355,7 +362,9 @@
111 "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
112 "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
113 "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" ]; then
114- define_tristate CONFIG_FBCON_CFB16 y
115+ if [ "$CONFIG_FBCON_CFB16" != "m" ]; then
116+ define_tristate CONFIG_FBCON_CFB16 y
117+ fi
118 else
119 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
120 "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
121@@ -373,7 +382,9 @@
122 "$CONFIG_FB_INTEL" = "m" -o \
123 "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
124 "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
125- define_tristate CONFIG_FBCON_CFB16 m
126+ if [ "$CONFIG_FBCON_CFB16" != "y" ]; then
127+ define_tristate CONFIG_FBCON_CFB16 m
128+ fi
129 fi
130 fi
131 if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
132diff -ruN linux-2.4.31/drivers/video/Makefile linux-2.4.31-bs/drivers/video/Makefile
133--- linux-2.4.31/drivers/video/Makefile 2004-02-18 13:36:31.000000000 +0000
134+++ linux-2.4.31-bs/drivers/video/Makefile 2005-05-06 11:28:28.000000000 +0100
135@@ -14,7 +14,7 @@
136 fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
137 fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
138 fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
139- fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
140+ fbcon-cfb8.o fbcon-splash16.o fbcon-mac.o fbcon-mfb.o \
141 cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
142
143 # Each configuration option enables a list of files.
144@@ -154,6 +154,9 @@
145 obj-$(CONFIG_FBCON_VGA) += fbcon-vga.o
146 obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
147 obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
148+obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-splash.o
149+obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-splash16.o
150+obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-jpegdec.o
151
152 include $(TOPDIR)/Rules.make
153
154diff -ruN linux-2.4.31/drivers/video/fbcon-jpegdec.c linux-2.4.31-bs/drivers/video/fbcon-jpegdec.c
155--- linux-2.4.31/drivers/video/fbcon-jpegdec.c 1970-01-01 01:00:00.000000000 +0100
156+++ linux-2.4.31-bs/drivers/video/fbcon-jpegdec.c 2005-05-06 11:22:05.000000000 +0100
157@@ -0,0 +1,960 @@
158+/*
159+ * linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder.
160+ *
161+ * (w) August 2001 by Michael Schroeder, <mls@suse.de>
162+ *
163+ */
164+
165+#include <linux/config.h>
166+#include <linux/string.h>
167+#include <asm/byteorder.h>
168+
169+struct display;
170+#include "fbcon-splash.h"
171+#include "fbcon-jpegdec.h"
172+
173+#define ISHIFT 11
174+
175+#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
176+#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
177+#define ITOINT(a) ((a) >> ISHIFT)
178+
179+#ifndef __P
180+# define __P(x) x
181+#endif
182+
183+/* special markers */
184+#define M_BADHUFF -1
185+#define M_EOF 0x80
186+
187+struct in {
188+ unsigned char *p;
189+ unsigned int bits;
190+ int left;
191+ int marker;
192+
193+ int (*func) __P((void *));
194+ void *data;
195+};
196+
197+/*********************************/
198+struct dec_hufftbl;
199+struct enc_hufftbl;
200+
201+union hufftblp {
202+ struct dec_hufftbl *dhuff;
203+ struct enc_hufftbl *ehuff;
204+};
205+
206+struct scan {
207+ int dc; /* old dc value */
208+
209+ union hufftblp hudc;
210+ union hufftblp huac;
211+ int next; /* when to switch to next scan */
212+
213+ int cid; /* component id */
214+ int hv; /* horiz/vert, copied from comp */
215+ int tq; /* quant tbl, copied from comp */
216+};
217+
218+/*********************************/
219+
220+#define DECBITS 10 /* seems to be the optimum */
221+
222+struct dec_hufftbl {
223+ int maxcode[17];
224+ int valptr[16];
225+ unsigned char vals[256];
226+ unsigned int llvals[1 << DECBITS];
227+};
228+
229+static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
230+static int dec_readmarker __P((struct in *));
231+static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
232+
233+static void setinput __P((struct in *, unsigned char *));
234+/*********************************/
235+
236+#undef PREC
237+#define PREC int
238+
239+static void idctqtab __P((unsigned char *, PREC *));
240+static void idct __P((int *, int *, PREC *, PREC, int));
241+static void scaleidctqtab __P((PREC *, PREC));
242+
243+/*********************************/
244+
245+static void initcol __P((PREC[][64]));
246+
247+static void col221111 __P((int *, unsigned char *, int));
248+static void col221111_16 __P((int *, unsigned char *, int));
249+
250+/*********************************/
251+
252+#define M_SOI 0xd8
253+#define M_APP0 0xe0
254+#define M_DQT 0xdb
255+#define M_SOF0 0xc0
256+#define M_DHT 0xc4
257+#define M_DRI 0xdd
258+#define M_SOS 0xda
259+#define M_RST0 0xd0
260+#define M_EOI 0xd9
261+#define M_COM 0xfe
262+
263+static unsigned char *datap;
264+
265+static int getbyte(void)
266+{
267+ return *datap++;
268+}
269+
270+static int getword(void)
271+{
272+ int c1, c2;
273+ c1 = *datap++;
274+ c2 = *datap++;
275+ return c1 << 8 | c2;
276+}
277+
278+struct comp {
279+ int cid;
280+ int hv;
281+ int tq;
282+};
283+
284+#define MAXCOMP 4
285+struct jpginfo {
286+ int nc; /* number of components */
287+ int ns; /* number of scans */
288+ int dri; /* restart interval */
289+ int nm; /* mcus til next marker */
290+ int rm; /* next restart marker */
291+};
292+
293+static struct jpginfo info;
294+static struct comp comps[MAXCOMP];
295+
296+static struct scan dscans[MAXCOMP];
297+
298+static unsigned char quant[4][64];
299+
300+static struct dec_hufftbl dhuff[4];
301+
302+#define dec_huffdc (dhuff + 0)
303+#define dec_huffac (dhuff + 2)
304+
305+static struct in in;
306+
307+static int readtables(int till)
308+{
309+ int m, l, i, j, lq, pq, tq;
310+ int tc, th, tt;
311+
312+ for (;;) {
313+ if (getbyte() != 0xff)
314+ return -1;
315+ if ((m = getbyte()) == till)
316+ break;
317+
318+ switch (m) {
319+ case 0xc2:
320+ return 0;
321+
322+ case M_DQT:
323+ lq = getword();
324+ while (lq > 2) {
325+ pq = getbyte();
326+ tq = pq & 15;
327+ if (tq > 3)
328+ return -1;
329+ pq >>= 4;
330+ if (pq != 0)
331+ return -1;
332+ for (i = 0; i < 64; i++)
333+ quant[tq][i] = getbyte();
334+ lq -= 64 + 1;
335+ }
336+ break;
337+
338+ case M_DHT:
339+ l = getword();
340+ while (l > 2) {
341+ int hufflen[16], k;
342+ unsigned char huffvals[256];
343+
344+ tc = getbyte();
345+ th = tc & 15;
346+ tc >>= 4;
347+ tt = tc * 2 + th;
348+ if (tc > 1 || th > 1)
349+ return -1;
350+ for (i = 0; i < 16; i++)
351+ hufflen[i] = getbyte();
352+ l -= 1 + 16;
353+ k = 0;
354+ for (i = 0; i < 16; i++) {
355+ for (j = 0; j < hufflen[i]; j++)
356+ huffvals[k++] = getbyte();
357+ l -= hufflen[i];
358+ }
359+ dec_makehuff(dhuff + tt, hufflen,
360+ huffvals);
361+ }
362+ break;
363+
364+ case M_DRI:
365+ l = getword();
366+ info.dri = getword();
367+ break;
368+
369+ default:
370+ l = getword();
371+ while (l-- > 2)
372+ getbyte();
373+ break;
374+ }
375+ }
376+ return 0;
377+}
378+
379+static void dec_initscans(void)
380+{
381+ int i;
382+
383+ info.nm = info.dri + 1;
384+ info.rm = M_RST0;
385+ for (i = 0; i < info.ns; i++)
386+ dscans[i].dc = 0;
387+}
388+
389+static int dec_checkmarker(void)
390+{
391+ int i;
392+
393+ if (dec_readmarker(&in) != info.rm)
394+ return -1;
395+ info.nm = info.dri;
396+ info.rm = (info.rm + 1) & ~0x08;
397+ for (i = 0; i < info.ns; i++)
398+ dscans[i].dc = 0;
399+ return 0;
400+}
401+
402+int jpeg_check_size(unsigned char *buf, int width, int height)
403+{
404+ datap = buf;
405+ getbyte();
406+ getbyte();
407+ readtables(M_SOF0);
408+ getword();
409+ getbyte();
410+ if (height != getword() || width != getword())
411+ return 0;
412+ return 1;
413+}
414+
415+int jpeg_decode(buf, pic, width, height, depth, decdata)
416+unsigned char *buf, *pic;
417+int width, height, depth;
418+struct jpeg_decdata *decdata;
419+{
420+ int i, j, m, tac, tdc;
421+ int mcusx, mcusy, mx, my;
422+ int max[6];
423+
424+ if (!decdata)
425+ return -1;
426+ datap = buf;
427+ if (getbyte() != 0xff)
428+ return ERR_NO_SOI;
429+ if (getbyte() != M_SOI)
430+ return ERR_NO_SOI;
431+ if (readtables(M_SOF0))
432+ return ERR_BAD_TABLES;
433+ getword();
434+ i = getbyte();
435+ if (i != 8)
436+ return ERR_NOT_8BIT;
437+ if (((getword() + 15) & ~15) != height)
438+ return ERR_HEIGHT_MISMATCH;
439+ if (((getword() + 15) & ~15) != width)
440+ return ERR_WIDTH_MISMATCH;
441+ if ((height & 15) || (width & 15))
442+ return ERR_BAD_WIDTH_OR_HEIGHT;
443+ info.nc = getbyte();
444+ if (info.nc > MAXCOMP)
445+ return ERR_TOO_MANY_COMPPS;
446+ for (i = 0; i < info.nc; i++) {
447+ int h, v;
448+ comps[i].cid = getbyte();
449+ comps[i].hv = getbyte();
450+ v = comps[i].hv & 15;
451+ h = comps[i].hv >> 4;
452+ comps[i].tq = getbyte();
453+ if (h > 3 || v > 3)
454+ return ERR_ILLEGAL_HV;
455+ if (comps[i].tq > 3)
456+ return ERR_QUANT_TABLE_SELECTOR;
457+ }
458+ if (readtables(M_SOS))
459+ return ERR_BAD_TABLES;
460+ getword();
461+ info.ns = getbyte();
462+ if (info.ns != 3)
463+ return ERR_NOT_YCBCR_221111;
464+ for (i = 0; i < 3; i++) {
465+ dscans[i].cid = getbyte();
466+ tdc = getbyte();
467+ tac = tdc & 15;
468+ tdc >>= 4;
469+ if (tdc > 1 || tac > 1)
470+ return ERR_QUANT_TABLE_SELECTOR;
471+ for (j = 0; j < info.nc; j++)
472+ if (comps[j].cid == dscans[i].cid)
473+ break;
474+ if (j == info.nc)
475+ return ERR_UNKNOWN_CID_IN_SCAN;
476+ dscans[i].hv = comps[j].hv;
477+ dscans[i].tq = comps[j].tq;
478+ dscans[i].hudc.dhuff = dec_huffdc + tdc;
479+ dscans[i].huac.dhuff = dec_huffac + tac;
480+ }
481+
482+ i = getbyte();
483+ j = getbyte();
484+ m = getbyte();
485+
486+ if (i != 0 || j != 63 || m != 0)
487+ return ERR_NOT_SEQUENTIAL_DCT;
488+
489+ if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
490+ return ERR_NOT_YCBCR_221111;
491+
492+ if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
493+ return ERR_NOT_YCBCR_221111;
494+
495+ mcusx = width >> 4;
496+ mcusy = height >> 4;
497+
498+
499+ idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
500+ idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
501+ idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
502+ initcol(decdata->dquant);
503+ setinput(&in, datap);
504+
505+#if 0
506+ /* landing zone */
507+ img[len] = 0;
508+ img[len + 1] = 0xff;
509+ img[len + 2] = M_EOF;
510+#endif
511+
512+ dec_initscans();
513+
514+ dscans[0].next = 6 - 4;
515+ dscans[1].next = 6 - 4 - 1;
516+ dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
517+ for (my = 0; my < mcusy; my++) {
518+ for (mx = 0; mx < mcusx; mx++) {
519+ if (info.dri && !--info.nm)
520+ if (dec_checkmarker())
521+ return ERR_WRONG_MARKER;
522+
523+ decode_mcus(&in, decdata->dcts, 6, dscans, max);
524+ idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]);
525+ idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]);
526+ idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]);
527+ idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]);
528+ idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]);
529+ idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
530+
531+ switch (depth) {
532+ case 24:
533+ col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
534+ break;
535+ case 16:
536+ col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
537+ break;
538+ default:
539+ return ERR_DEPTH_MISMATCH;
540+ break;
541+ }
542+ }
543+ }
544+
545+ m = dec_readmarker(&in);
546+ if (m != M_EOI)
547+ return ERR_NO_EOI;
548+
549+ return 0;
550+}
551+
552+/****************************************************************/
553+/************** huffman decoder ***************/
554+/****************************************************************/
555+
556+static int fillbits __P((struct in *, int, unsigned int));
557+static int dec_rec2
558+__P((struct in *, struct dec_hufftbl *, int *, int, int));
559+
560+static void setinput(in, p)
561+struct in *in;
562+unsigned char *p;
563+{
564+ in->p = p;
565+ in->left = 0;
566+ in->bits = 0;
567+ in->marker = 0;
568+}
569+
570+static int fillbits(in, le, bi)
571+struct in *in;
572+int le;
573+unsigned int bi;
574+{
575+ int b, m;
576+
577+ if (in->marker) {
578+ if (le <= 16)
579+ in->bits = bi << 16, le += 16;
580+ return le;
581+ }
582+ while (le <= 24) {
583+ b = *in->p++;
584+ if (b == 0xff && (m = *in->p++) != 0) {
585+ if (m == M_EOF) {
586+ if (in->func && (m = in->func(in->data)) == 0)
587+ continue;
588+ }
589+ in->marker = m;
590+ if (le <= 16)
591+ bi = bi << 16, le += 16;
592+ break;
593+ }
594+ bi = bi << 8 | b;
595+ le += 8;
596+ }
597+ in->bits = bi; /* tmp... 2 return values needed */
598+ return le;
599+}
600+
601+static int dec_readmarker(in)
602+struct in *in;
603+{
604+ int m;
605+
606+ in->left = fillbits(in, in->left, in->bits);
607+ if ((m = in->marker) == 0)
608+ return 0;
609+ in->left = 0;
610+ in->marker = 0;
611+ return m;
612+}
613+
614+#define LEBI_DCL int le, bi
615+#define LEBI_GET(in) (le = in->left, bi = in->bits)
616+#define LEBI_PUT(in) (in->left = le, in->bits = bi)
617+
618+#define GETBITS(in, n) ( \
619+ (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
620+ (le -= (n)), \
621+ bi >> le & ((1 << (n)) - 1) \
622+)
623+
624+#define UNGETBITS(in, n) ( \
625+ le += (n) \
626+)
627+
628+
629+static int dec_rec2(in, hu, runp, c, i)
630+struct in *in;
631+struct dec_hufftbl *hu;
632+int *runp;
633+int c, i;
634+{
635+ LEBI_DCL;
636+
637+ LEBI_GET(in);
638+ if (i) {
639+ UNGETBITS(in, i & 127);
640+ *runp = i >> 8 & 15;
641+ i >>= 16;
642+ } else {
643+ for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
644+ if (i >= 16) {
645+ in->marker = M_BADHUFF;
646+ return 0;
647+ }
648+ i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
649+ *runp = i >> 4;
650+ i &= 15;
651+ }
652+ if (i == 0) { /* sigh, 0xf0 is 11 bit */
653+ LEBI_PUT(in);
654+ return 0;
655+ }
656+ /* receive part */
657+ c = GETBITS(in, i);
658+ if (c < (1 << (i - 1)))
659+ c += (-1 << i) + 1;
660+ LEBI_PUT(in);
661+ return c;
662+}
663+
664+#define DEC_REC(in, hu, r, i) ( \
665+ r = GETBITS(in, DECBITS), \
666+ i = hu->llvals[r], \
667+ i & 128 ? \
668+ ( \
669+ UNGETBITS(in, i & 127), \
670+ r = i >> 8 & 15, \
671+ i >> 16 \
672+ ) \
673+ : \
674+ ( \
675+ LEBI_PUT(in), \
676+ i = dec_rec2(in, hu, &r, r, i), \
677+ LEBI_GET(in), \
678+ i \
679+ ) \
680+)
681+
682+static void decode_mcus(in, dct, n, sc, maxp)
683+struct in *in;
684+int *dct;
685+int n;
686+struct scan *sc;
687+int *maxp;
688+{
689+ struct dec_hufftbl *hu;
690+ int i, r, t;
691+ LEBI_DCL;
692+
693+ memset(dct, 0, n * 64 * sizeof(*dct));
694+ LEBI_GET(in);
695+ while (n-- > 0) {
696+ hu = sc->hudc.dhuff;
697+ *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
698+
699+ hu = sc->huac.dhuff;
700+ i = 63;
701+ while (i > 0) {
702+ t = DEC_REC(in, hu, r, t);
703+ if (t == 0 && r == 0) {
704+ dct += i;
705+ break;
706+ }
707+ dct += r;
708+ *dct++ = t;
709+ i -= r + 1;
710+ }
711+ *maxp++ = 64 - i;
712+ if (n == sc->next)
713+ sc++;
714+ }
715+ LEBI_PUT(in);
716+}
717+
718+static void dec_makehuff(hu, hufflen, huffvals)
719+struct dec_hufftbl *hu;
720+int *hufflen;
721+unsigned char *huffvals;
722+{
723+ int code, k, i, j, d, x, c, v;
724+ for (i = 0; i < (1 << DECBITS); i++)
725+ hu->llvals[i] = 0;
726+
727+/*
728+ * llvals layout:
729+ *
730+ * value v already known, run r, backup u bits:
731+ * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
732+ * value unknown, size b bits, run r, backup u bits:
733+ * 000000000000bbbb 0000 rrrr 0 uuuuuuu
734+ * value and size unknown:
735+ * 0000000000000000 0000 0000 0 0000000
736+ */
737+ code = 0;
738+ k = 0;
739+ for (i = 0; i < 16; i++, code <<= 1) { /* sizes */
740+ hu->valptr[i] = k;
741+ for (j = 0; j < hufflen[i]; j++) {
742+ hu->vals[k] = *huffvals++;
743+ if (i < DECBITS) {
744+ c = code << (DECBITS - 1 - i);
745+ v = hu->vals[k] & 0x0f; /* size */
746+ for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
747+ if (v + i < DECBITS) { /* both fit in table */
748+ x = d >> (DECBITS - 1 - v -
749+ i);
750+ if (v && x < (1 << (v - 1)))
751+ x += (-1 << v) + 1;
752+ x = x << 16 | (hu-> vals[k] & 0xf0) << 4 |
753+ (DECBITS - (i + 1 + v)) | 128;
754+ } else
755+ x = v << 16 | (hu-> vals[k] & 0xf0) << 4 |
756+ (DECBITS - (i + 1));
757+ hu->llvals[c | d] = x;
758+ }
759+ }
760+ code++;
761+ k++;
762+ }
763+ hu->maxcode[i] = code;
764+ }
765+ hu->maxcode[16] = 0x20000; /* always terminate decode */
766+}
767+
768+/****************************************************************/
769+/************** idct ***************/
770+/****************************************************************/
771+
772+#define ONE ((PREC)IFIX(1.))
773+#define S2 ((PREC)IFIX(0.382683432))
774+#define C2 ((PREC)IFIX(0.923879532))
775+#define C4 ((PREC)IFIX(0.707106781))
776+
777+#define S22 ((PREC)IFIX(2 * 0.382683432))
778+#define C22 ((PREC)IFIX(2 * 0.923879532))
779+#define IC4 ((PREC)IFIX(1 / 0.707106781))
780+
781+#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */
782+#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */
783+#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */
784+
785+#define XPP(a,b) (t = a + b, b = a - b, a = t)
786+#define XMP(a,b) (t = a - b, b = a + b, a = t)
787+#define XPM(a,b) (t = a + b, b = b - a, a = t)
788+
789+#define ROT(a,b,s,c) ( t = IMULT(a + b, s), \
790+ a = IMULT(a, c - s) + t, \
791+ b = IMULT(b, c + s) - t)
792+
793+#define IDCT \
794+( \
795+ XPP(t0, t1), \
796+ XMP(t2, t3), \
797+ t2 = IMULT(t2, IC4) - t3, \
798+ XPP(t0, t3), \
799+ XPP(t1, t2), \
800+ XMP(t4, t7), \
801+ XPP(t5, t6), \
802+ XMP(t5, t7), \
803+ t5 = IMULT(t5, IC4), \
804+ ROT(t4, t6, S22, C22),\
805+ t6 -= t7, \
806+ t5 -= t6, \
807+ t4 -= t5, \
808+ XPP(t0, t7), \
809+ XPP(t1, t6), \
810+ XPP(t2, t5), \
811+ XPP(t3, t4) \
812+)
813+
814+static unsigned char zig2[64] = {
815+ 0, 2, 3, 9, 10, 20, 21, 35,
816+ 14, 16, 25, 31, 39, 46, 50, 57,
817+ 5, 7, 12, 18, 23, 33, 37, 48,
818+ 27, 29, 41, 44, 52, 55, 59, 62,
819+ 15, 26, 30, 40, 45, 51, 56, 58,
820+ 1, 4, 8, 11, 19, 22, 34, 36,
821+ 28, 42, 43, 53, 54, 60, 61, 63,
822+ 6, 13, 17, 24, 32, 38, 47, 49
823+};
824+
825+void idct(in, out, quant, off, max)
826+int *in;
827+int *out;
828+PREC *quant;
829+PREC off;
830+int max;
831+{
832+ PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
833+ PREC tmp[64], *tmpp;
834+ int i, j;
835+ unsigned char *zig2p;
836+
837+ t0 = off;
838+ if (max == 1) {
839+ t0 += in[0] * quant[0];
840+ for (i = 0; i < 64; i++)
841+ out[i] = ITOINT(t0);
842+ return;
843+ }
844+ zig2p = zig2;
845+ tmpp = tmp;
846+ for (i = 0; i < 8; i++) {
847+ j = *zig2p++;
848+ t0 += in[j] * quant[j];
849+ j = *zig2p++;
850+ t5 = in[j] * quant[j];
851+ j = *zig2p++;
852+ t2 = in[j] * quant[j];
853+ j = *zig2p++;
854+ t7 = in[j] * quant[j];
855+ j = *zig2p++;
856+ t1 = in[j] * quant[j];
857+ j = *zig2p++;
858+ t4 = in[j] * quant[j];
859+ j = *zig2p++;
860+ t3 = in[j] * quant[j];
861+ j = *zig2p++;
862+ t6 = in[j] * quant[j];
863+ IDCT;
864+ tmpp[0 * 8] = t0;
865+ tmpp[1 * 8] = t1;
866+ tmpp[2 * 8] = t2;
867+ tmpp[3 * 8] = t3;
868+ tmpp[4 * 8] = t4;
869+ tmpp[5 * 8] = t5;
870+ tmpp[6 * 8] = t6;
871+ tmpp[7 * 8] = t7;
872+ tmpp++;
873+ t0 = 0;
874+ }
875+ for (i = 0; i < 8; i++) {
876+ t0 = tmp[8 * i + 0];
877+ t1 = tmp[8 * i + 1];
878+ t2 = tmp[8 * i + 2];
879+ t3 = tmp[8 * i + 3];
880+ t4 = tmp[8 * i + 4];
881+ t5 = tmp[8 * i + 5];
882+ t6 = tmp[8 * i + 6];
883+ t7 = tmp[8 * i + 7];
884+ IDCT;
885+ out[8 * i + 0] = ITOINT(t0);
886+ out[8 * i + 1] = ITOINT(t1);
887+ out[8 * i + 2] = ITOINT(t2);
888+ out[8 * i + 3] = ITOINT(t3);
889+ out[8 * i + 4] = ITOINT(t4);
890+ out[8 * i + 5] = ITOINT(t5);
891+ out[8 * i + 6] = ITOINT(t6);
892+ out[8 * i + 7] = ITOINT(t7);
893+ }
894+}
895+
896+static unsigned char zig[64] = {
897+ 0, 1, 5, 6, 14, 15, 27, 28,
898+ 2, 4, 7, 13, 16, 26, 29, 42,
899+ 3, 8, 12, 17, 25, 30, 41, 43,
900+ 9, 11, 18, 24, 31, 40, 44, 53,
901+ 10, 19, 23, 32, 39, 45, 52, 54,
902+ 20, 22, 33, 38, 46, 51, 55, 60,
903+ 21, 34, 37, 47, 50, 56, 59, 61,
904+ 35, 36, 48, 49, 57, 58, 62, 63
905+};
906+
907+static PREC aaidct[8] = {
908+ IFIX(0.3535533906), IFIX(0.4903926402),
909+ IFIX(0.4619397663), IFIX(0.4157348062),
910+ IFIX(0.3535533906), IFIX(0.2777851165),
911+ IFIX(0.1913417162), IFIX(0.0975451610)
912+};
913+
914+
915+static void idctqtab(qin, qout)
916+unsigned char *qin;
917+PREC *qout;
918+{
919+ int i, j;
920+
921+ for (i = 0; i < 8; i++)
922+ for (j = 0; j < 8; j++)
923+ qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *
924+ IMULT(aaidct[i], aaidct[j]);
925+}
926+
927+static void scaleidctqtab(q, sc)
928+PREC *q;
929+PREC sc;
930+{
931+ int i;
932+
933+ for (i = 0; i < 64; i++)
934+ q[i] = IMULT(q[i], sc);
935+}
936+
937+/****************************************************************/
938+/************** color decoder ***************/
939+/****************************************************************/
940+
941+#define ROUND
942+
943+/*
944+ * YCbCr Color transformation:
945+ *
946+ * y:0..255 Cb:-128..127 Cr:-128..127
947+ *
948+ * R = Y + 1.40200 * Cr
949+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
950+ * B = Y + 1.77200 * Cb
951+ *
952+ * =>
953+ * Cr *= 1.40200;
954+ * Cb *= 1.77200;
955+ * Cg = 0.19421 * Cb + .50937 * Cr;
956+ * R = Y + Cr;
957+ * G = Y - Cg;
958+ * B = Y + Cb;
959+ *
960+ * =>
961+ * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
962+ */
963+
964+static void initcol(q)
965+PREC q[][64];
966+{
967+ scaleidctqtab(q[1], IFIX(1.77200));
968+ scaleidctqtab(q[2], IFIX(1.40200));
969+}
970+
971+/* This is optimized for the stupid sun SUNWspro compiler. */
972+#define STORECLAMP(a,x) \
973+( \
974+ (a) = (x), \
975+ (unsigned int)(x) >= 256 ? \
976+ ((a) = (x) < 0 ? 0 : 255) \
977+ : \
978+ 0 \
979+)
980+
981+#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
982+
983+#ifdef ROUND
984+
985+#define CBCRCG(yin, xin) \
986+( \
987+ cb = outc[0 +yin*8+xin], \
988+ cr = outc[64+yin*8+xin], \
989+ cg = (50 * cb + 130 * cr + 128) >> 8 \
990+)
991+
992+#else
993+
994+#define CBCRCG(yin, xin) \
995+( \
996+ cb = outc[0 +yin*8+xin], \
997+ cr = outc[64+yin*8+xin], \
998+ cg = (3 * cb + 8 * cr) >> 4 \
999+)
1000+
1001+#endif
1002+
1003+#define PIC(yin, xin, p, xout) \
1004+( \
1005+ y = outy[(yin) * 8 + xin], \
1006+ STORECLAMP(p[(xout) * 3 + 0], y + cr), \
1007+ STORECLAMP(p[(xout) * 3 + 1], y - cg), \
1008+ STORECLAMP(p[(xout) * 3 + 2], y + cb) \
1009+)
1010+
1011+#ifdef __LITTLE_ENDIAN
1012+#define PIC_16(yin, xin, p, xout, add) \
1013+( \
1014+ y = outy[(yin) * 8 + xin], \
1015+ y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
1016+ ((CLAMP(y - cg + add ) & 0xfc) << 3) | \
1017+ ((CLAMP(y + cb + add*2+1) ) >> 3), \
1018+ p[(xout) * 2 + 0] = y & 0xff, \
1019+ p[(xout) * 2 + 1] = y >> 8 \
1020+)
1021+#else
1022+#ifdef CONFIG_PPC
1023+#define PIC_16(yin, xin, p, xout, add) \
1024+( \
1025+ y = outy[(yin) * 8 + xin], \
1026+ y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \
1027+ ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \
1028+ ((CLAMP(y + cb + add*2+1) ) >> 3), \
1029+ p[(xout) * 2 + 0] = y >> 8, \
1030+ p[(xout) * 2 + 1] = y & 0xff \
1031+)
1032+#else
1033+#define PIC_16(yin, xin, p, xout, add) \
1034+( \
1035+ y = outy[(yin) * 8 + xin], \
1036+ y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \
1037+ ((CLAMP(y - cg + add ) & 0xfc) << 3) | \
1038+ ((CLAMP(y + cb + add*2+1) ) >> 3), \
1039+ p[(xout) * 2 + 0] = y >> 8, \
1040+ p[(xout) * 2 + 1] = y & 0xff \
1041+)
1042+#endif
1043+#endif
1044+
1045+#define PIC221111(xin) \
1046+( \
1047+ CBCRCG(0, xin), \
1048+ PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \
1049+ PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \
1050+ PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \
1051+ PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
1052+)
1053+
1054+#define PIC221111_16(xin) \
1055+( \
1056+ CBCRCG(0, xin), \
1057+ PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
1058+ PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
1059+ PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
1060+ PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
1061+)
1062+
1063+static void col221111(out, pic, width)
1064+int *out;
1065+unsigned char *pic;
1066+int width;
1067+{
1068+ int i, j, k;
1069+ unsigned char *pic0, *pic1;
1070+ int *outy, *outc;
1071+ int cr, cg, cb, y;
1072+
1073+ pic0 = pic;
1074+ pic1 = pic + width;
1075+ outy = out;
1076+ outc = out + 64 * 4;
1077+ for (i = 2; i > 0; i--) {
1078+ for (j = 4; j > 0; j--) {
1079+ for (k = 0; k < 8; k++) {
1080+ PIC221111(k);
1081+ }
1082+ outc += 8;
1083+ outy += 16;
1084+ pic0 += 2 * width;
1085+ pic1 += 2 * width;
1086+ }
1087+ outy += 64 * 2 - 16 * 4;
1088+ }
1089+}
1090+
1091+static void col221111_16(out, pic, width)
1092+int *out;
1093+unsigned char *pic;
1094+int width;
1095+{
1096+ int i, j, k;
1097+ unsigned char *pic0, *pic1;
1098+ int *outy, *outc;
1099+ int cr, cg, cb, y;
1100+
1101+ pic0 = pic;
1102+ pic1 = pic + width;
1103+ outy = out;
1104+ outc = out + 64 * 4;
1105+ for (i = 2; i > 0; i--) {
1106+ for (j = 4; j > 0; j--) {
1107+ for (k = 0; k < 8; k++) {
1108+ PIC221111_16(k);
1109+ }
1110+ outc += 8;
1111+ outy += 16;
1112+ pic0 += 2 * width;
1113+ pic1 += 2 * width;
1114+ }
1115+ outy += 64 * 2 - 16 * 4;
1116+ }
1117+}
1118diff -ruN linux-2.4.31/drivers/video/fbcon-jpegdec.h linux-2.4.31-bs/drivers/video/fbcon-jpegdec.h
1119--- linux-2.4.31/drivers/video/fbcon-jpegdec.h 1970-01-01 01:00:00.000000000 +0100
1120+++ linux-2.4.31-bs/drivers/video/fbcon-jpegdec.h 2005-05-06 11:23:55.000000000 +0100
1121@@ -0,0 +1,24 @@
1122+#define ERR_NO_SOI 1
1123+#define ERR_NOT_8BIT 2
1124+#define ERR_HEIGHT_MISMATCH 3
1125+#define ERR_WIDTH_MISMATCH 4
1126+#define ERR_BAD_WIDTH_OR_HEIGHT 5
1127+#define ERR_TOO_MANY_COMPPS 6
1128+#define ERR_ILLEGAL_HV 7
1129+#define ERR_QUANT_TABLE_SELECTOR 8
1130+#define ERR_NOT_YCBCR_221111 9
1131+#define ERR_UNKNOWN_CID_IN_SCAN 10
1132+#define ERR_NOT_SEQUENTIAL_DCT 11
1133+#define ERR_WRONG_MARKER 12
1134+#define ERR_NO_EOI 13
1135+#define ERR_BAD_TABLES 14
1136+#define ERR_DEPTH_MISMATCH 15
1137+
1138+struct jpeg_decdata {
1139+ int dcts[6 * 64 + 16];
1140+ int out[64 * 6];
1141+ int dquant[3][64];
1142+};
1143+
1144+extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int, struct jpeg_decdata *);
1145+extern int jpeg_check_size(unsigned char *, int, int);
1146diff -ruN linux-2.4.31/drivers/video/fbcon-splash.c linux-2.4.31-bs/drivers/video/fbcon-splash.c
1147--- linux-2.4.31/drivers/video/fbcon-splash.c 1970-01-01 01:00:00.000000000 +0100
1148+++ linux-2.4.31-bs/drivers/video/fbcon-splash.c 2005-05-06 11:24:52.000000000 +0100
1149@@ -0,0 +1,848 @@
1150+/*
1151+ * linux/drivers/video/fbcon-splash.c - splash screen handling functions.
1152+ *
1153+ * (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
1154+ * Stefan Reinauer, <stepan@suse.de>
1155+ * Steffen Winterfeldt, <snwint@suse.de>
1156+ *
1157+ * Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de>
1158+ */
1159+
1160+#include <linux/version.h>
1161+#include <linux/config.h>
1162+#include <linux/module.h>
1163+#include <linux/fb.h>
1164+#include <linux/vt_kern.h>
1165+#include <linux/vmalloc.h>
1166+
1167+#include <asm/irq.h>
1168+#include <asm/system.h>
1169+
1170+#include <video/fbcon.h>
1171+#include <video/font.h>
1172+#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */
1173+
1174+#include "fbcon-splash.h"
1175+#include "fbcon-jpegdec.h"
1176+
1177+#define SPLASH_VERSION "3.0.7-2003/03/10"
1178+
1179+#ifdef CONFIG_BLK_DEV_INITRD
1180+unsigned char signature[] = "BOOTSPL1SPL2SPL3";
1181+#endif
1182+
1183+/* from drivers/char/console.c */
1184+extern void con_remap_def_color(int currcons, int new_color);
1185+
1186+/* from drivers/video/fbcon-splash16.c */
1187+extern void splashfill(u8 *dest, u8 *src, int width, int height,
1188+ int dest_linesize, int src_linesize);
1189+
1190+/* internal control states and data pointers */
1191+struct splash_data splash_data;
1192+
1193+unsigned char *linux_splash; /* decoded picture */
1194+int linux_splash_size = 0;
1195+
1196+static struct jpeg_decdata *decdata = 0; /* private decoder data */
1197+
1198+int splash_bytes; /* bytes per line in linux_splash */
1199+int splash_shown = 0; /* is the splash onscreen? */
1200+int splash_usesilent = 0; /* shall we display the silentjpeg */
1201+int splash_default = 0xf01;
1202+
1203+static int splash_status(struct display *p);
1204+static int splash_recolor(struct display *p);
1205+static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth);
1206+
1207+extern struct display_switch fbcon_splash16;
1208+
1209+int __init splash_init(char *options)
1210+{
1211+ if(!strncmp("silent",options,6)) {
1212+ printk(KERN_INFO "bootsplash: silent mode.\n");
1213+ splash_usesilent = 1;
1214+ /* skip "silent," */
1215+ if (strlen(options)==6)
1216+ return 0;
1217+ options+=7;
1218+ }
1219+ if(!strncmp("verbose",options,7)) {
1220+ printk(KERN_INFO "bootsplash: verbose mode.\n");
1221+ splash_usesilent = 0;
1222+ return 0;
1223+ }
1224+
1225+ splash_default = simple_strtoul(options, NULL, 0);
1226+
1227+ return 0;
1228+}
1229+
1230+__setup("splash=", splash_init);
1231+
1232+
1233+static int splash_hasinter(unsigned char *buf, int num)
1234+{
1235+ unsigned char *bufend = buf + num * 12;
1236+ while(buf < bufend) {
1237+ if (buf[1] > 127) /* inter? */
1238+ return 1;
1239+ buf += buf[3] > 127 ? 24 : 12; /* blend? */
1240+ }
1241+ return 0;
1242+}
1243+
1244+static int boxextract(unsigned char *buf, unsigned short *dp, unsigned char *cols, int *blendp)
1245+{
1246+ dp[0] = buf[0] | buf[1] << 8;
1247+ dp[1] = buf[2] | buf[3] << 8;
1248+ dp[2] = buf[4] | buf[5] << 8;
1249+ dp[3] = buf[6] | buf[7] << 8;
1250+ *(unsigned int *)(cols + 0) =
1251+ *(unsigned int *)(cols + 4) =
1252+ *(unsigned int *)(cols + 8) =
1253+ *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 8);
1254+ if (dp[1] > 32767) {
1255+ dp[1] = ~dp[1];
1256+ *(unsigned int *)(cols + 4) = *(unsigned int *)(buf + 12);
1257+ *(unsigned int *)(cols + 8) = *(unsigned int *)(buf + 16);
1258+ *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 20);
1259+ *blendp = 1;
1260+ return 24;
1261+ }
1262+ return 12;
1263+}
1264+
1265+static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint)
1266+{
1267+ int x, y, i, p, doblend, r, g, b, a, add;
1268+ unsigned short data1[4];
1269+ unsigned char cols1[16];
1270+ unsigned short data2[4];
1271+ unsigned char cols2[16];
1272+ unsigned char *bufend;
1273+ unsigned short *picp;
1274+
1275+ if (num == 0)
1276+ return;
1277+ bufend = buf + num * 12;
1278+ while(buf < bufend) {
1279+ doblend = 0;
1280+ buf += boxextract(buf, data1, cols1, &doblend);
1281+ if (data1[0] > 32767)
1282+ buf += boxextract(buf, data2, cols2, &doblend);
1283+ if (data1[2] > 32767) {
1284+ if (overpaint)
1285+ continue;
1286+ data1[2] = ~data1[2];
1287+ }
1288+ if (data1[3] > 32767) {
1289+ if (percent == 65536)
1290+ continue;
1291+ data1[3] = ~data1[3];
1292+ }
1293+ if (data1[0] > 32767) {
1294+ data1[0] = ~data1[0];
1295+ for (i = 0; i < 4; i++)
1296+ data1[i] = (data1[i] * (65536 - percent) + data2[i] * percent) >> 16;
1297+ for (i = 0; i < 16; i++)
1298+ cols1[i] = (cols1[i] * (65536 - percent) + cols2[i] * percent) >> 16;
1299+ }
1300+ *(unsigned int *)cols2 = *(unsigned int *)cols1;
1301+ a = cols2[3];
1302+ if (a == 0 && !doblend)
1303+ continue;
1304+ for (y = data1[1]; y <= data1[3]; y++) {
1305+ if (doblend) {
1306+ if ((p = data1[3] - data1[1]) != 0)
1307+ p = ((y - data1[1]) << 16) / p;
1308+ for (i = 0; i < 8; i++)
1309+ cols2[i + 8] = (cols1[i] * (65536 - p) + cols1[i + 8] * p) >> 16;
1310+ }
1311+ add = (data1[0] & 1);
1312+ add ^= (add ^ y) & 1 ? 1 : 3; /* 2x2 ordered dithering */
1313+ picp = (unsigned short *)(pic + data1[0] * 2 + y * bytes);
1314+ for (x = data1[0]; x <= data1[2]; x++) {
1315+ if (doblend) {
1316+ if ((p = data1[2] - data1[0]) != 0)
1317+ p = ((x - data1[0]) << 16) / p;
1318+ for (i = 0; i < 4; i++)
1319+ cols2[i] = (cols2[i + 8] * (65536 - p) + cols2[i + 12] * p) >> 16;
1320+ a = cols2[3];
1321+ }
1322+ r = cols2[0];
1323+ g = cols2[1];
1324+ b = cols2[2];
1325+ if (a != 255) {
1326+ i = *picp;
1327+ r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
1328+ g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
1329+ b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
1330+ }
1331+ #define CLAMP(x) ((x) >= 256 ? 255 : (x))
1332+ i = ((CLAMP(r + add*2+1) & 0xf8) << 8) |
1333+ ((CLAMP(g + add ) & 0xfc) << 3) |
1334+ ((CLAMP(b + add*2+1) ) >> 3);
1335+ *picp++ = i;
1336+ add ^= 3;
1337+ }
1338+ }
1339+ }
1340+}
1341+
1342+static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth)
1343+{
1344+ int size, err;
1345+ unsigned char *mem;
1346+
1347+ size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3);
1348+ mem = vmalloc(size);
1349+ if (!mem) {
1350+ printk(KERN_INFO "No memory for decoded picture!\n");
1351+ return -1;
1352+ }
1353+ if (!decdata)
1354+ decdata = vmalloc(sizeof(*decdata));
1355+ if ((err = jpeg_decode(jpeg, mem, ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata)))
1356+ printk(KERN_INFO "error %d while decompressing picture.\n",err);
1357+ vfree(mem);
1358+ return err ? -1 : 0;
1359+}
1360+
1361+static void splash_free(struct display * p)
1362+{
1363+ if (!p->splash_data)
1364+ return;
1365+ if (p->splash_data->oldscreen_base)
1366+ p->screen_base = p->splash_data->oldscreen_base;
1367+ if (p->splash_data->olddispsw)
1368+ p->dispsw = p->splash_data->olddispsw;
1369+ if (p->splash_data->splash_silentjpeg)
1370+ vfree(p->splash_data->splash_sboxes);
1371+ vfree(p->splash_data);
1372+ p->splash_data = 0;
1373+}
1374+
1375+static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
1376+{
1377+ unsigned char *buf;
1378+ int i;
1379+
1380+ if (pwi ==0 || phe == 0)
1381+ return 0;
1382+ buf = (unsigned char *)data + sizeof(*data);
1383+ pwi += pxo - 1;
1384+ phe += pyo - 1;
1385+ *buf++ = pxo;
1386+ *buf++ = pxo >> 8;
1387+ *buf++ = pyo;
1388+ *buf++ = pyo >> 8;
1389+ *buf++ = pwi;
1390+ *buf++ = pwi >> 8;
1391+ *buf++ = phe;
1392+ *buf++ = phe >> 8;
1393+ *buf++ = pr;
1394+ *buf++ = pg;
1395+ *buf++ = pb;
1396+ *buf++ = 0;
1397+ for (i = 0; i < 12; i++, buf++)
1398+ *buf = buf[-12];
1399+ buf[-24] ^= 0xff;
1400+ buf[-23] ^= 0xff;
1401+ buf[-1] = 0xff;
1402+ return 2;
1403+}
1404+
1405+int splash_getraw(unsigned char *start, unsigned char *end)
1406+{
1407+ unsigned char *ndata;
1408+ int found = 0;
1409+ int splash_size = 0;
1410+ void *splash_start = 0;
1411+ int unit = 0;
1412+ int width = 0, height = 0;
1413+ int silentsize;
1414+ int boxcount = 0;
1415+ int sboxcount = 0;
1416+ int palcnt = 0;
1417+ struct display *p;
1418+
1419+ printk(KERN_INFO "Looking for splash picture...");
1420+
1421+ p = &fb_display[0];
1422+ silentsize = 0;
1423+
1424+ for (ndata = start; ndata < end; ndata++) {
1425+ if (*((unsigned int *)ndata) != *((unsigned int *)signature))
1426+ continue;
1427+ if (*((unsigned int *)(ndata+4))==*((unsigned int *)(signature+4))) {
1428+ printk(".");
1429+ unit = 0;
1430+ p = &fb_display[0];
1431+ width = p->var.xres;
1432+ height = p->var.yres;
1433+
1434+ splash_size = ndata[16] + (ndata[17] << 8) + (ndata[18] << 16) + (ndata[19] << 24);
1435+ if (ndata + 20 + splash_size > end) {
1436+ printk(" found, but truncated!\n");
1437+ return -1;
1438+ }
1439+ if (!jpeg_check_size(ndata + 20, width, height)) {
1440+ ndata += 20 - 1 + splash_size;
1441+ continue;
1442+ }
1443+ if (splash_check_jpeg(ndata + 20, width, height, p->var.bits_per_pixel))
1444+ return -1;
1445+ if (p->splash_data)
1446+ splash_free(p);
1447+ p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
1448+ if (!p->splash_data)
1449+ break;
1450+
1451+ p->splash_data->oldscreen_base = 0;
1452+ p->splash_data->olddispsw = 0;
1453+ p->splash_data->splash_silentjpeg = 0;
1454+
1455+ p->splash_data->splash_text_xo = ndata[ 8] + (ndata[ 9] << 8);
1456+ p->splash_data->splash_text_yo = ndata[10] + (ndata[11] << 8);
1457+ p->splash_data->splash_text_wi = ndata[12] + (ndata[13] << 8);
1458+ p->splash_data->splash_text_he = ndata[14] + (ndata[15] << 8);
1459+ /* use 8x16 font... */
1460+ p->splash_data->splash_text_xo *= 8;
1461+ p->splash_data->splash_text_wi *= 8;
1462+ p->splash_data->splash_text_yo *= 16;
1463+ p->splash_data->splash_text_he *= 16;
1464+ p->splash_data->splash_color = (splash_default >> 8) & 0x0f;
1465+ p->splash_data->splash_fg_color = (splash_default >> 4) & 0x0f;
1466+ p->splash_data->splash_state = splash_default & 1;
1467+ p->splash_data->splash_percent = 0;
1468+ p->splash_data->splash_overpaintok = 0;
1469+ boxcount = splash_mkpenguin(p->splash_data, p->splash_data->splash_text_xo + 10, p->splash_data->splash_text_yo + 10, p->splash_data->splash_text_wi - 20, p->splash_data->splash_text_he - 20, 0xf0, 0xf0, 0xf0);
1470+ splash_start = ndata + 20;
1471+ found = 1;
1472+ break;
1473+ }
1474+ if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+8))) {
1475+ printk(".");
1476+ unit = ndata[8];
1477+ if (unit >= MAX_NR_CONSOLES)
1478+ continue;
1479+ if (unit)
1480+ vc_allocate(unit);
1481+ p = &fb_display[unit];
1482+ width = fb_display[unit].var.xres;
1483+ height = fb_display[unit].var.yres;
1484+ splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24);
1485+ if (splash_size == -1) {
1486+ printk(" found, updating values.\n");
1487+ if (p->splash_data) {
1488+ if (ndata[9] != 255)
1489+ p->splash_data->splash_state = ndata[9];
1490+ if (ndata[10] != 255)
1491+ p->splash_data->splash_fg_color = ndata[10];
1492+ if (ndata[11] != 255)
1493+ p->splash_data->splash_color = ndata[11];
1494+ }
1495+ return unit;
1496+ }
1497+ if (splash_size == 0) {
1498+ printk(" found, freeing memory.\n");
1499+ if (p->splash_data)
1500+ splash_free(p);
1501+ return unit;
1502+ }
1503+ if (ndata + 35 + splash_size > end) {
1504+ printk(" found, but truncated!\n");
1505+ return -1;
1506+ }
1507+ if (!jpeg_check_size(ndata + 35, width, height)) {
1508+ ndata += 35 - 1 + splash_size;
1509+ continue;
1510+ }
1511+ if (splash_check_jpeg(ndata + 35, width, height, p->var.bits_per_pixel))
1512+ return -1;
1513+ if (p->splash_data)
1514+ splash_free(p);
1515+ p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
1516+ if (!p->splash_data)
1517+ break;
1518+
1519+ p->splash_data->oldscreen_base = 0;
1520+ p->splash_data->olddispsw = 0;
1521+ p->splash_data->splash_silentjpeg = 0;
1522+
1523+ p->splash_data->splash_state = ndata[9];
1524+ p->splash_data->splash_fg_color = ndata[10];
1525+ p->splash_data->splash_color = ndata[11];
1526+ p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8);
1527+ p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8);
1528+ p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8);
1529+ p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8);
1530+ p->splash_data->splash_percent = 0;
1531+ p->splash_data->splash_overpaintok = 0;
1532+ boxcount = splash_mkpenguin(p->splash_data, ndata[24] + (ndata[25] << 8), ndata[26] + (ndata[27] << 8), ndata[28] + (ndata[29] << 8), ndata[30] + (ndata[31] << 8), ndata[32], ndata[33], ndata[34]);
1533+ splash_start = ndata + 35;
1534+ found = 2;
1535+ break;
1536+ }
1537+ if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+12))) {
1538+ printk(".");
1539+ unit = ndata[8];
1540+ if (unit >= MAX_NR_CONSOLES)
1541+ continue;
1542+ if (unit)
1543+ vc_allocate(unit);
1544+ p = &fb_display[unit];
1545+ width = p->var.xres;
1546+ height = p->var.yres;
1547+ splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24);
1548+ if (splash_size == -1) {
1549+ printk(" found, updating values.\n");
1550+ if (p->splash_data) {
1551+ if (ndata[9] != 255)
1552+ p->splash_data->splash_state = ndata[9];
1553+ if (ndata[10] != 255)
1554+ p->splash_data->splash_fg_color = ndata[10];
1555+ if (ndata[11] != 255)
1556+ p->splash_data->splash_color = ndata[11];
1557+ }
1558+ return unit;
1559+ }
1560+ if (splash_size == 0) {
1561+ printk(" found, freeing memory.\n");
1562+ if (p->splash_data)
1563+ splash_free(p);
1564+ return unit;
1565+ }
1566+ boxcount = ndata[24] + (ndata[25] << 8);
1567+ palcnt = ndata[37] * 3;
1568+ if (ndata + 38 + splash_size > end) {
1569+ printk(" found, but truncated!\n");
1570+ return -1;
1571+ }
1572+ if (!jpeg_check_size(ndata + 38 + boxcount * 12 + palcnt, width, height)) {
1573+ ndata += 38 - 1 + splash_size;
1574+ continue;
1575+ }
1576+ if (splash_check_jpeg(ndata + 38 + boxcount * 12 + palcnt, width, height, p->var.bits_per_pixel))
1577+ return -1;
1578+ silentsize = ndata[28] + (ndata[29] << 8) + (ndata[30] << 16) + (ndata[31] << 24);
1579+ if (silentsize)
1580+ printk(" silenjpeg size %d bytes,", silentsize);
1581+ if (silentsize >= splash_size) {
1582+ printk(" bigger than splashsize!\n");
1583+ return -1;
1584+ }
1585+ splash_size -= silentsize;
1586+ if (!splash_usesilent || !p->fb_info->fbops->fb_get_fix ) {
1587+ silentsize = 0;
1588+ } else {
1589+ struct fb_fix_screeninfo fix;
1590+ p->fb_info->fbops->fb_get_fix(&fix, unit, 0);
1591+ if (height * 2 * p->next_line > fix.smem_len) {
1592+ printk(" does not fit into framebuffer.\n");
1593+ silentsize = 0;
1594+ }
1595+ }
1596+
1597+ sboxcount = ndata[32] + (ndata[33] << 8);
1598+ if (silentsize) {
1599+ char *simage=ndata + 38 + splash_size + 12 * sboxcount;
1600+ if (!jpeg_check_size(simage, width, height) ||
1601+ splash_check_jpeg(simage, width, height, p->var.bits_per_pixel)) {
1602+ printk(" error in silent jpeg.\n");
1603+ silentsize = 0;
1604+ }
1605+ }
1606+ if (p->splash_data)
1607+ splash_free(p);
1608+ p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size);
1609+ if (!p->splash_data)
1610+ break;
1611+ p->splash_data->oldscreen_base = 0;
1612+ p->splash_data->olddispsw = 0;
1613+ p->splash_data->splash_silentjpeg = 0;
1614+ if (silentsize) {
1615+ p->splash_data->splash_silentjpeg = vmalloc(silentsize);
1616+ if (p->splash_data->splash_silentjpeg) {
1617+ memcpy(p->splash_data->splash_silentjpeg, ndata + 38 + splash_size, silentsize);
1618+ p->splash_data->splash_sboxes = p->splash_data->splash_silentjpeg;
1619+ p->splash_data->splash_silentjpeg += 12 * sboxcount;
1620+ p->splash_data->splash_sboxcount = sboxcount;
1621+ }
1622+ }
1623+ p->splash_data->splash_state = ndata[9];
1624+ p->splash_data->splash_fg_color = ndata[10];
1625+ p->splash_data->splash_color = ndata[11];
1626+ p->splash_data->splash_overpaintok = ndata[36];
1627+ p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8);
1628+ p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8);
1629+ p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8);
1630+ p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8);
1631+ p->splash_data->splash_percent = ndata[34] + (ndata[35] << 8);
1632+ p->splash_data->splash_percent += p->splash_data->splash_percent > 32767;
1633+ splash_start = ndata + 38;
1634+ found = 3;
1635+ break;
1636+ }
1637+ }
1638+
1639+ if (!found) {
1640+ printk(" no good signature found.\n");
1641+ return -1;
1642+ }
1643+ if (p->splash_data->splash_text_xo + p->splash_data->splash_text_wi > width || p->splash_data->splash_text_yo + p->splash_data->splash_text_he > height) {
1644+ splash_free(p);
1645+ p->splash_data = 0;
1646+ printk(" found, but has oversized text area!\n");
1647+ return -1;
1648+ }
1649+ if (p->dispsw->setup != fbcon_cfb16.setup) {
1650+ splash_free(p);
1651+ p->splash_data = 0;
1652+ printk(" found, but framebuffer can't handle it!\n");
1653+ return -1;
1654+ }
1655+ printk(" found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, found);
1656+
1657+ if (found==1) {
1658+ printk(KERN_WARNING "bootsplash: Using deprecated v1 header. Updating your splash utility recommended.\n");
1659+ printk(KERN_INFO "bootsplash: Find the latest version at ftp.suse.com/pub/people/stepan/bootsplash/\n");
1660+ }
1661+
1662+ /* copy data so that initrd memory can be freed. */
1663+ memcpy((char *)p->splash_data + sizeof(*p->splash_data) + (found < 3 ? boxcount * 12 : 0), splash_start, splash_size);
1664+ p->splash_data->splash_boxcount = boxcount;
1665+ p->splash_data->splash_boxes = (unsigned char *)p->splash_data + sizeof(*p->splash_data);
1666+ p->splash_data->splash_jpeg = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12 + palcnt;
1667+ p->splash_data->splash_palette = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12;
1668+ p->splash_data->splash_palcnt = palcnt / 3;
1669+ p->splash_data->splash_dosilent = p->splash_data->splash_silentjpeg != 0;
1670+ return unit;
1671+}
1672+
1673+int splash_verbose(void)
1674+{
1675+ struct display *p;
1676+
1677+ p = &fb_display[0];
1678+ if (!p || !p->splash_data || !p->splash_data->splash_state || !p->conp)
1679+ return 0;
1680+ if (fg_console != p->conp->vc_num)
1681+ return 0;
1682+ if (!p->splash_data->splash_silentjpeg || !p->splash_data->splash_dosilent)
1683+ return 0;
1684+ if (!p->splash_data->oldscreen_base)
1685+ return 0;
1686+
1687+ p->splash_data->splash_dosilent = 0;
1688+
1689+ splashfill(p->splash_data->oldscreen_base, p->screen_base, p->var.xres, p->var.yres, p->next_line, p->next_line);
1690+ p->screen_base = p->splash_data->oldscreen_base;
1691+
1692+ return 1;
1693+}
1694+
1695+static void splash_off(struct display *p)
1696+{
1697+ if (p->splash_data && p->splash_data->oldscreen_base)
1698+ p->screen_base = p->splash_data->oldscreen_base;
1699+ if (p->splash_data && p->splash_data->olddispsw)
1700+ p->dispsw = p->splash_data->olddispsw;
1701+ splash_shown = 0;
1702+}
1703+
1704+int splash_prepare(struct display *p)
1705+{
1706+ int err;
1707+ int width, height, depth, size, sbytes;
1708+
1709+ if (!p->splash_data || !p->splash_data->splash_state) {
1710+ if (linux_splash)
1711+ vfree(linux_splash);
1712+ if (decdata)
1713+ vfree(decdata);
1714+ linux_splash = 0;
1715+ decdata = 0;
1716+ linux_splash_size = 0;
1717+ splash_off(p);
1718+ return -1;
1719+ }
1720+
1721+ width = p->var.xres;
1722+ height = p->var.yres;
1723+ depth = p->var.bits_per_pixel;
1724+ if (depth != 16) { /* Other targets might need fixing */
1725+ splash_off(p);
1726+ return -2;
1727+ }
1728+
1729+ sbytes = ((width + 15) & ~15) * (depth >> 3);
1730+ size = sbytes * ((height + 15) & ~15);
1731+ if (size != linux_splash_size) {
1732+ if (linux_splash)
1733+ vfree(linux_splash);
1734+ linux_splash_size = 0;
1735+ linux_splash = 0;
1736+ splash_off(p);
1737+ }
1738+ if (!linux_splash)
1739+ linux_splash = vmalloc(size);
1740+
1741+ if (!linux_splash) {
1742+ linux_splash_size = 0;
1743+ printk(KERN_INFO "Not enough memory for splash screen.\n");
1744+ splash_off(p);
1745+ return -3;
1746+ }
1747+
1748+ if (!decdata)
1749+ decdata = vmalloc(sizeof(*decdata));
1750+
1751+ if (!p->splash_data->oldscreen_base)
1752+ p->splash_data->oldscreen_base = p->screen_base;
1753+
1754+ if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent) {
1755+ printk(KERN_INFO "Got silent jpeg.\n");
1756+ /* fill area after framebuffer with other jpeg */
1757+ if ((err = jpeg_decode(p->splash_data->splash_silentjpeg, linux_splash,
1758+ ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
1759+ printk(KERN_INFO "Error %d while decompressing silent jpeg.\n", err);
1760+ p->screen_base = p->splash_data->oldscreen_base;
1761+ p->splash_data->splash_dosilent = 0;
1762+ } else {
1763+ if (p->splash_data->splash_sboxcount)
1764+ boxit(linux_splash, sbytes, p->splash_data->splash_sboxes,
1765+ p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 0);
1766+
1767+ splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, p->next_line, sbytes);
1768+ p->screen_base = p->splash_data->oldscreen_base + p->next_line * p->var.yres;
1769+ }
1770+ } else
1771+ p->screen_base = p->splash_data->oldscreen_base;
1772+
1773+ if ((err = jpeg_decode(p->splash_data->splash_jpeg, linux_splash,
1774+ ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
1775+ printk(KERN_INFO "Error %d while decompressing splash screen.\n", err);
1776+ vfree(linux_splash);
1777+ linux_splash = 0;
1778+ linux_splash_size = 0;
1779+ splash_off(p);
1780+ return -4;
1781+ }
1782+ linux_splash_size = size;
1783+ splash_bytes = sbytes;
1784+ if (p->splash_data->splash_boxcount)
1785+ boxit(linux_splash, sbytes, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 0);
1786+ splash_data = *p->splash_data;
1787+ splash_shown = p->splash_data->splash_state;
1788+ if (splash_shown) {
1789+ if (p->dispsw != &fbcon_splash16)
1790+ p->splash_data->olddispsw = p->dispsw;
1791+ p->dispsw = &fbcon_splash16;
1792+ } else
1793+ splash_off(p);
1794+ return 0;
1795+}
1796+
1797+
1798+#ifdef CONFIG_PROC_FS
1799+#include <linux/proc_fs.h>
1800+
1801+struct proc_dir_entry *proc_splash;
1802+int splash_read_proc(char *buffer, char **start, off_t offset, int size,
1803+ int *eof, void *data);
1804+int splash_write_proc(struct file *file, const char *buffer,
1805+ unsigned long count, void *data);
1806+
1807+int splash_read_proc(char *buffer, char **start, off_t offset, int size,
1808+ int *eof, void *data)
1809+{
1810+ int len = 0;
1811+
1812+ off_t begin = 0;
1813+ struct display *p = &fb_display[0];
1814+
1815+ int color = p->splash_data ? p->splash_data->splash_color << 4 |
1816+ p->splash_data->splash_fg_color : splash_default >> 4;
1817+ int status = p->splash_data ? p->splash_data->splash_state & 1 : 0;
1818+ len += sprintf(buffer + len, "Splash screen v%s (0x%02x, %dx%d%s): %s\n",
1819+ SPLASH_VERSION, color, p->var.xres, p->var.yres,
1820+ (p->splash_data ? p->splash_data->splash_dosilent : 0)? ", silent" : "",
1821+ status ? "on" : "off");
1822+ if (offset >= begin + len)
1823+ return 0;
1824+
1825+ *start = buffer + (begin - offset);
1826+
1827+ return (size < begin + len - offset ? size : begin + len - offset);
1828+}
1829+
1830+static int splash_recolor(struct display *p)
1831+{
1832+ if (!p->splash_data)
1833+ return -1;
1834+ if (!p->splash_data->splash_state)
1835+ return 0;
1836+ con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
1837+ if (fg_console == p->conp->vc_num) {
1838+ splash_data = *p->splash_data;
1839+ update_region(fg_console,
1840+ p->conp->vc_origin +
1841+ p->conp->vc_size_row *
1842+ p->conp->vc_top,
1843+ p->conp->vc_size_row *
1844+ (p->conp->vc_bottom -
1845+ p->conp->vc_top) / 2);
1846+ }
1847+ return 0;
1848+}
1849+
1850+static int splash_status(struct display *p)
1851+{
1852+ printk(KERN_INFO "Splash status on console %d changed to %s\n", p->conp->vc_num, p->splash_data && p->splash_data->splash_state ? "on" : "off");
1853+
1854+ if (fg_console == p->conp->vc_num)
1855+ splash_prepare(p);
1856+ if (p->splash_data && p->splash_data->splash_state) {
1857+ con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
1858+ /* resize_con also calls con_switch which resets yscroll */
1859+ vc_resize_con(p->splash_data->splash_text_he / fontheight(p),
1860+ p->splash_data->splash_text_wi / fontwidth(p),
1861+ p->conp->vc_num);
1862+ if (fg_console == p->conp->vc_num) {
1863+ update_region(fg_console,
1864+ p->conp->vc_origin +
1865+ p->conp->vc_size_row *
1866+ p->conp->vc_top,
1867+ p->conp->vc_size_row *
1868+ (p->conp->vc_bottom -
1869+ p->conp->vc_top) / 2);
1870+ fbcon_splash16.clear_margins(p->conp, p, 0);
1871+ }
1872+ } else {
1873+ /* Switch bootsplash off */
1874+ con_remap_def_color(p->conp->vc_num, 0x07);
1875+ vc_resize_con(p->var.yres / fontheight(p),
1876+ p->var.xres / fontwidth(p),
1877+ p->conp->vc_num);
1878+ }
1879+ return 0;
1880+}
1881+
1882+int splash_write_proc(struct file *file, const char *buffer,
1883+ unsigned long count, void *data)
1884+{
1885+ int new, unit;
1886+ struct display *p;
1887+
1888+ if (!buffer || !splash_default)
1889+ return count;
1890+
1891+ if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
1892+ int pe;
1893+
1894+ p = &fb_display[0];
1895+ if (buffer[4] == ' ' && buffer[5] == 'p')
1896+ pe = 0;
1897+ else if (buffer[4] == '\n')
1898+ pe = 65535;
1899+ else
1900+ pe = simple_strtoul(buffer + 5, NULL, 0);
1901+ if (pe < 0)
1902+ pe = 0;
1903+ if (pe > 65535)
1904+ pe = 65535;
1905+ if (*buffer == 'h')
1906+ pe = 65535 - pe;
1907+ pe += pe > 32767;
1908+ if (p->splash_data && p->splash_data->splash_percent != pe) {
1909+ p->splash_data->splash_percent = pe;
1910+ if (fg_console != p->conp->vc_num || !p->splash_data->splash_state)
1911+ return count;
1912+ if (!p->splash_data->splash_overpaintok || p->splash_data->splash_percent == 65536) {
1913+ if (splash_hasinter(p->splash_data->splash_boxes, p->splash_data->splash_boxcount))
1914+ splash_status(p);
1915+ else
1916+ splash_prepare(p);
1917+ } else {
1918+ if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent && p->splash_data->oldscreen_base)
1919+ boxit(p->splash_data->oldscreen_base, p->next_line, p->splash_data->splash_sboxes, p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 1);
1920+ boxit(p->screen_base, p->next_line, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 1);
1921+ }
1922+ }
1923+ return count;
1924+ }
1925+ if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) {
1926+ p = &fb_display[0];
1927+ if (p->splash_data && p->splash_data->splash_silentjpeg) {
1928+ if (p->splash_data->splash_dosilent != (buffer[0] == 's')) {
1929+ p->splash_data->splash_dosilent = buffer[0] == 's';
1930+ splash_status(p);
1931+ }
1932+ }
1933+ return count;
1934+ }
1935+ if (!strncmp(buffer,"freesilent\n",11)) {
1936+ p = &fb_display[0];
1937+ if (p->splash_data && p->splash_data->splash_silentjpeg) {
1938+ printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
1939+ p->splash_data->splash_silentjpeg = 0;
1940+ vfree(p->splash_data->splash_sboxes);
1941+ p->splash_data->splash_sboxes = 0;
1942+ p->splash_data->splash_sboxcount = 0;
1943+ if (p->splash_data->splash_dosilent)
1944+ splash_status(p);
1945+ p->splash_data->splash_dosilent = 0;
1946+ }
1947+ return count;
1948+ }
1949+
1950+ if (!strncmp(buffer, signature, 7)) {
1951+ unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count);
1952+ if (unit >= 0) {
1953+ p = &fb_display[unit];
1954+ splash_status(p);
1955+ }
1956+ return count;
1957+ }
1958+ p = &fb_display[0];
1959+ if (!p->splash_data)
1960+ return count;
1961+ if (buffer[0] == 't') {
1962+ p->splash_data->splash_state ^= 1;
1963+ splash_status(p);
1964+ return count;
1965+ }
1966+ new = simple_strtoul(buffer, NULL, 0);
1967+ if (new > 1) {
1968+ /* expert user */
1969+ p->splash_data->splash_color = new >> 8 & 0xff;
1970+ p->splash_data->splash_fg_color = new >> 4 & 0x0f;
1971+ }
1972+ if ((new & 1) == p->splash_data->splash_state)
1973+ splash_recolor(p);
1974+ else {
1975+ p->splash_data->splash_state = new & 1;
1976+ splash_status(p);
1977+ }
1978+ return count;
1979+}
1980+
1981+int splash_proc_register(void)
1982+{
1983+ if ((proc_splash = create_proc_entry("splash", 0, 0))) {
1984+ proc_splash->read_proc = splash_read_proc;
1985+ proc_splash->write_proc = splash_write_proc;
1986+ return 0;
1987+ }
1988+ return 1;
1989+}
1990+
1991+int splash_proc_unregister(void)
1992+{
1993+ if (proc_splash)
1994+ remove_proc_entry("splash", 0);
1995+ return 0;
1996+}
1997+#endif
1998diff -ruN linux-2.4.31/drivers/video/fbcon-splash.h linux-2.4.31-bs/drivers/video/fbcon-splash.h
1999--- linux-2.4.31/drivers/video/fbcon-splash.h 1970-01-01 01:00:00.000000000 +0100
2000+++ linux-2.4.31-bs/drivers/video/fbcon-splash.h 2005-05-06 11:25:18.000000000 +0100
2001@@ -0,0 +1,18 @@
2002+/*
2003+ * linux/drivers/video/splash.h - splash screen definition.
2004+ *
2005+ * (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
2006+ * Stefan Reinauer, <stepan@suse.de>
2007+ *
2008+ *
2009+ * idea and SuSE screen work by Ken Wimer, <wimer@suse.de>
2010+ */
2011+
2012+extern int splash_getraw(unsigned char *, unsigned char *);
2013+extern int splash_prepare(struct display *);
2014+
2015+extern int splash_shown; /* is splash shown? */
2016+extern struct splash_data splash_data; /* image data, copied over
2017+ from display */
2018+extern unsigned char *linux_splash; /* decoded pic data */
2019+extern int splash_bytes; /* bytes per line */
2020diff -ruN linux-2.4.31/drivers/video/fbcon-splash16.c linux-2.4.31-bs/drivers/video/fbcon-splash16.c
2021--- linux-2.4.31/drivers/video/fbcon-splash16.c 1970-01-01 01:00:00.000000000 +0100
2022+++ linux-2.4.31-bs/drivers/video/fbcon-splash16.c 2005-05-06 11:24:19.000000000 +0100
2023@@ -0,0 +1,488 @@
2024+/*
2025+ * linux/drivers/video/fbcon-splash16.c -- Low level frame buffer operations for 16 bpp
2026+ * framebuffer operation. Modified to present
2027+ * boot splash screen. 2002/11/7 stepan@suse.de
2028+ *
2029+ * Based on linux/drivers/video/fbcon-cfb16.c, which is
2030+ *
2031+ * Created 5 Apr 1997 by Geert Uytterhoeven
2032+ *
2033+ * This file is subject to the terms and conditions of the GNU General Public
2034+ * License. See the file COPYING in the main directory of this archive for
2035+ * more details.
2036+ */
2037+
2038+#include <linux/module.h>
2039+#include <linux/config.h>
2040+#include <linux/tty.h>
2041+#include <linux/console.h>
2042+#include <linux/string.h>
2043+#include <linux/fb.h>
2044+#include <asm/io.h>
2045+
2046+#include <video/fbcon.h>
2047+#include <video/fbcon-cfb16.h>
2048+
2049+#include "fbcon-splash.h"
2050+
2051+ /*
2052+ * 16 bpp packed pixels
2053+ */
2054+
2055+static u32 tab_cfb16[] = {
2056+#if defined(__BIG_ENDIAN)
2057+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
2058+#elif defined(__LITTLE_ENDIAN)
2059+ 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
2060+#else
2061+#error FIXME: No endianness??
2062+#endif
2063+};
2064+
2065+void fbcon_splash16_bmove(struct display *p, int sy, int sx, int dy, int dx,
2066+ int height, int width)
2067+{
2068+ int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
2069+ u8 *src, *dst;
2070+
2071+ if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) {
2072+ fb_memmove(p->screen_base + dy * linesize,
2073+ p->screen_base + sy * linesize,
2074+ height * linesize);
2075+ return;
2076+ }
2077+ if (fontwidthlog(p)) {
2078+ sx <<= fontwidthlog(p)+1;
2079+ dx <<= fontwidthlog(p)+1;
2080+ width <<= fontwidthlog(p)+1;
2081+ } else {
2082+ sx *= fontwidth(p)*2;
2083+ dx *= fontwidth(p)*2;
2084+ width *= fontwidth(p)*2;
2085+ }
2086+ sx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes;
2087+ dx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes;
2088+ if (dy < sy || (dy == sy && dx < sx)) {
2089+ src = p->screen_base + sy * linesize + sx;
2090+ dst = p->screen_base + dy * linesize + dx;
2091+ for (rows = height * fontheight(p); rows--;) {
2092+ fb_memmove(dst, src, width);
2093+ src += bytes;
2094+ dst += bytes;
2095+ }
2096+ } else {
2097+ src = p->screen_base + (sy+height) * linesize + sx - bytes;
2098+ dst = p->screen_base + (dy+height) * linesize + dx - bytes;
2099+ for (rows = height * fontheight(p); rows--;) {
2100+ fb_memmove(dst, src, width);
2101+ src -= bytes;
2102+ dst -= bytes;
2103+ }
2104+ }
2105+}
2106+
2107+static inline void rectfill(u8 *dest, int width, int height, u32 data,
2108+ int linesize)
2109+{
2110+ int i;
2111+
2112+ data |= data<<16;
2113+
2114+ while (height-- > 0) {
2115+ u32 *p = (u32 *)dest;
2116+ for (i = 0; i < width/4; i++) {
2117+ fb_writel(data, p++);
2118+ fb_writel(data, p++);
2119+ }
2120+ if (width & 2)
2121+ fb_writel(data, p++);
2122+ if (width & 1)
2123+ fb_writew(data, (u16*)p);
2124+ dest += linesize;
2125+ }
2126+}
2127+
2128+void splashfill(u8 *dest, u8 *src, int width, int height,
2129+ int dest_linesize, int src_linesize)
2130+{
2131+
2132+ int i;
2133+
2134+ while (height-- > 0) {
2135+ u32 *p = (u32 *)dest;
2136+ u32 *q = (u32 *)src;
2137+
2138+ for (i=0; i < width/4; i++) {
2139+ fb_writel(*q++,p++);
2140+ fb_writel(*q++,p++);
2141+ }
2142+ if (width & 2)
2143+ fb_writel(*q++,p++);
2144+ if (width & 1)
2145+ fb_writew(*(u16*)q,(u16*)p);
2146+ dest += dest_linesize;
2147+ src += src_linesize;
2148+ }
2149+}
2150+
2151+void fbcon_splash16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
2152+ int height, int width)
2153+{
2154+ u8 *dest;
2155+ int bytes = p->next_line, lines = height * fontheight(p);
2156+ u32 bgx;
2157+ int offset, transparent=0;
2158+
2159+ dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
2160+
2161+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
2162+
2163+ width *= fontwidth(p)/4;
2164+
2165+ dest += splash_data.splash_text_yo * bytes +
2166+ splash_data.splash_text_xo * 2;
2167+
2168+ transparent = (splash_data.splash_color == attr_bgcol_ec(p, conp));
2169+
2170+ if (transparent) {
2171+ offset = (sy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
2172+ (sx * fontwidth(p) + splash_data.splash_text_xo) * 2;
2173+
2174+ if ((width * 8 == bytes && splash_bytes == bytes))
2175+ splashfill(dest,linux_splash + offset, lines * width * 4,
2176+ 1, bytes, splash_bytes);
2177+ else
2178+ splashfill(dest,linux_splash + offset, width*4, lines,
2179+ bytes, splash_bytes);
2180+ } else {
2181+ if (width * 8 == bytes)
2182+ rectfill(dest, lines * width * 4, 1, bgx, bytes);
2183+ else
2184+ rectfill(dest, width * 4, lines, bgx, bytes);
2185+ }
2186+}
2187+
2188+
2189+/*
2190+ * Helper function to read the background from the splashscreen
2191+ */
2192+# define SPLASH_BGX(off) \
2193+ if (transparent) { \
2194+ bgx = *(u32*)(splashbgx + (off)); \
2195+ eorx = fgx ^ bgx; \
2196+ }
2197+
2198+
2199+void fbcon_splash16_putc(struct vc_data *conp, struct display *p, int c, int yy,
2200+ int xx)
2201+{
2202+ u8 *dest, *cdat, bits;
2203+ int bytes = p->next_line, rows;
2204+ u32 eorx, fgx, bgx;
2205+ int transparent = 0;
2206+ u8 *splashbgx = 0;
2207+
2208+ dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
2209+
2210+ fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
2211+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
2212+
2213+ transparent = (splash_data.splash_color == attr_bgcol(p, c));
2214+
2215+ dest += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes;
2216+ splashbgx = linux_splash +
2217+ (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
2218+ (xx * fontwidth(p) + splash_data.splash_text_xo) * 2;
2219+
2220+ if (transparent && splash_data.splash_color == 0xf) {
2221+ if (fgx == 0xffea)
2222+ fgx = 0xfe4a;
2223+ else if (fgx == 0x57ea)
2224+ fgx = 0x0540;
2225+ else if (fgx == 0xffff)
2226+ fgx = 0x52aa;
2227+ }
2228+
2229+ fgx |= (fgx << 16);
2230+ bgx |= (bgx << 16);
2231+ eorx = fgx ^ bgx;
2232+
2233+ switch (fontwidth(p)) {
2234+ case 4:
2235+ case 8:
2236+ cdat = p->fontdata + (c & p->charmask) * fontheight(p);
2237+ for (rows = fontheight(p); rows--; dest += bytes) {
2238+ bits = *cdat++;
2239+ SPLASH_BGX(0);
2240+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
2241+ SPLASH_BGX(4);
2242+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
2243+ if (fontwidth(p) == 8) {
2244+ SPLASH_BGX(8);
2245+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
2246+ SPLASH_BGX(12);
2247+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
2248+ }
2249+
2250+ splashbgx += splash_bytes;
2251+
2252+ }
2253+ break;
2254+ case 12:
2255+ case 16:
2256+ cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
2257+ for (rows = fontheight(p); rows--; dest += bytes) {
2258+ bits = *cdat++;
2259+ SPLASH_BGX(0);
2260+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
2261+ SPLASH_BGX(4);
2262+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
2263+ SPLASH_BGX(8);
2264+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
2265+ SPLASH_BGX(12);
2266+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
2267+ bits = *cdat++;
2268+ SPLASH_BGX(16);
2269+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
2270+ SPLASH_BGX(20);
2271+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
2272+ if (fontwidth(p) == 16) {
2273+ SPLASH_BGX(24);
2274+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
2275+ SPLASH_BGX(28);
2276+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
2277+ }
2278+ }
2279+ break;
2280+ }
2281+}
2282+
2283+void fbcon_splash16_putcs(struct vc_data *conp, struct display *p,
2284+ const unsigned short *s, int count, int yy, int xx)
2285+{
2286+ u8 *cdat, *dest, *dest0;
2287+ u16 c;
2288+ int rows, bytes = p->next_line;
2289+ u32 eorx, fgx, bgx;
2290+ int transparent = 0;
2291+ u8 *splashbgx0 = 0, *splashbgx;
2292+
2293+ dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
2294+ c = scr_readw(s);
2295+ fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
2296+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
2297+
2298+ transparent = (splash_data.splash_color == attr_bgcol(p, c));
2299+
2300+ dest0 += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes;
2301+ splashbgx0 = linux_splash +
2302+ (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
2303+ (xx * fontwidth(p) + splash_data.splash_text_xo) * 2;
2304+
2305+ if (transparent && splash_data.splash_color == 0xf) {
2306+ if (fgx == 0xffea)
2307+ fgx = 0xfe4a;
2308+ else if (fgx == 0x57ea)
2309+ fgx = 0x0540;
2310+ else if (fgx == 0xffff)
2311+ fgx = 0x52aa;
2312+ }
2313+
2314+ fgx |= (fgx << 16);
2315+ bgx |= (bgx << 16);
2316+ eorx = fgx ^ bgx;
2317+
2318+ switch (fontwidth(p)) {
2319+ case 4:
2320+ case 8:
2321+ while (count--) {
2322+ c = scr_readw(s++) & p->charmask;
2323+ cdat = p->fontdata + c * fontheight(p);
2324+
2325+ splashbgx = splashbgx0;
2326+
2327+ for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
2328+ u8 bits = *cdat++;
2329+ SPLASH_BGX(0);
2330+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
2331+ SPLASH_BGX(4);
2332+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
2333+ if (fontwidth(p) == 8) {
2334+ SPLASH_BGX(8);
2335+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
2336+ SPLASH_BGX(12);
2337+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
2338+ }
2339+ splashbgx += splash_bytes;
2340+ }
2341+
2342+ dest0 += fontwidth(p)*2;
2343+ splashbgx0 += fontwidth(p) * 2;
2344+ }
2345+
2346+ break;
2347+ case 12:
2348+ case 16:
2349+ while (count--) {
2350+ c = scr_readw(s++) & p->charmask;
2351+ cdat = p->fontdata + (c * fontheight(p) << 1);
2352+
2353+ splashbgx = splashbgx0;
2354+
2355+ for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
2356+ u8 bits = *cdat++;
2357+ SPLASH_BGX(0);
2358+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
2359+ SPLASH_BGX(4);
2360+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
2361+ SPLASH_BGX(8);
2362+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
2363+ SPLASH_BGX(12);
2364+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
2365+ bits = *cdat++;
2366+ SPLASH_BGX(16);
2367+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
2368+ SPLASH_BGX(20);
2369+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
2370+ if (fontwidth(p) == 16) {
2371+ SPLASH_BGX(24);
2372+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
2373+ SPLASH_BGX(28);
2374+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
2375+ }
2376+ splashbgx += splash_bytes;
2377+ }
2378+
2379+ dest0 += fontwidth(p)*2;
2380+ splashbgx0 += fontwidth(p) * 2;
2381+ }
2382+
2383+ break;
2384+ }
2385+}
2386+
2387+void fbcon_splash16_revc(struct display *p, int xx, int yy)
2388+{
2389+ u8 *dest;
2390+ int bytes = p->next_line, rows;
2391+
2392+ dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
2393+ dest += splash_data.splash_text_yo * bytes + splash_data.splash_text_xo * 2;
2394+
2395+ for (rows = fontheight(p); rows--; dest += bytes) {
2396+ switch (fontwidth(p)) {
2397+ case 16:
2398+ fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
2399+ fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
2400+ /* FALL THROUGH */
2401+ case 12:
2402+ fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
2403+ fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
2404+ /* FALL THROUGH */
2405+ case 8:
2406+ fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
2407+ fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
2408+ /* FALL THROUGH */
2409+ case 4:
2410+ fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
2411+ fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
2412+ }
2413+ }
2414+}
2415+
2416+void fbcon_splash16_clear_margins(struct vc_data *conp, struct display *p,
2417+ int bottom_only)
2418+{
2419+ int bytes = p->next_line;
2420+ u32 bgx;
2421+
2422+ unsigned int right_start = conp->vc_cols*fontwidth(p);
2423+ unsigned int bottom_start = conp->vc_rows*fontheight(p);
2424+ unsigned int right_width, bottom_width;
2425+
2426+ int left_margin_width = splash_data.splash_text_xo;
2427+ int text_width = conp->vc_cols * fontwidth(p);
2428+ int right_margin_width = p->var.xres - text_width - left_margin_width;
2429+ int top_margin_height = splash_data.splash_text_yo;
2430+ int text_height = conp->vc_rows * fontheight(p);
2431+ int bottom_margin_height = p->var.yres - text_height - top_margin_height;
2432+
2433+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
2434+
2435+ if (bottom_only == -1) {
2436+ printk(KERN_DEBUG "Called with bottom-only\n");
2437+ splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, bytes, splash_bytes);
2438+ return;
2439+ }
2440+
2441+ if (!bottom_only && (right_width = p->var.xres-right_start)) {
2442+ /* left margin */
2443+ splashfill(p->screen_base + top_margin_height * bytes,
2444+ linux_splash + top_margin_height *
2445+ splash_bytes, left_margin_width,
2446+ text_height, bytes, splash_bytes);
2447+
2448+ /* right margin */
2449+ splashfill(p->screen_base + left_margin_width*2 + text_width*2 +
2450+ top_margin_height * bytes, linux_splash +
2451+ left_margin_width*2 + text_width*2 + top_margin_height *
2452+ splash_bytes, right_margin_width, text_height,
2453+ bytes, splash_bytes);
2454+ }
2455+
2456+ if ((bottom_width = p->var.yres-bottom_start))
2457+ /* bottom margin */
2458+ splashfill(p->screen_base + (top_margin_height + text_height) *
2459+ bytes, linux_splash + (top_margin_height +
2460+ text_height) * splash_bytes, p->var.xres,
2461+ bottom_margin_height, bytes, splash_bytes);
2462+
2463+ /* top margin */
2464+ splashfill(p->screen_base, linux_splash,
2465+ p->var.xres, top_margin_height,
2466+ bytes, splash_bytes);
2467+
2468+ /* leave function if work is done */
2469+ return;
2470+}
2471+
2472+
2473+ /*
2474+ * `switch' for the low level operations
2475+ */
2476+
2477+struct display_switch fbcon_splash16 = {
2478+ bmove: fbcon_splash16_bmove,
2479+ clear: fbcon_splash16_clear,
2480+ putc: fbcon_splash16_putc,
2481+ putcs: fbcon_splash16_putcs,
2482+ revc: fbcon_splash16_revc,
2483+ clear_margins: fbcon_splash16_clear_margins,
2484+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
2485+};
2486+
2487+
2488+#ifdef MODULE
2489+MODULE_LICENSE("GPL");
2490+
2491+int init_module(void)
2492+{
2493+ return 0;
2494+}
2495+
2496+void cleanup_module(void)
2497+{}
2498+#endif /* MODULE */
2499+
2500+
2501+ /*
2502+ * Visible symbols for modules
2503+ */
2504+
2505+EXPORT_SYMBOL(fbcon_splash16);
2506+EXPORT_SYMBOL(fbcon_splash16_bmove);
2507+EXPORT_SYMBOL(fbcon_splash16_clear);
2508+EXPORT_SYMBOL(fbcon_splash16_putc);
2509+EXPORT_SYMBOL(fbcon_splash16_putcs);
2510+EXPORT_SYMBOL(fbcon_splash16_revc);
2511+EXPORT_SYMBOL(fbcon_splash16_clear_margins);
2512diff -ruN linux-2.4.31/drivers/video/fbcon.c linux-2.4.31-bs/drivers/video/fbcon.c
2513--- linux-2.4.31/drivers/video/fbcon.c 2004-11-17 11:54:21.000000000 +0000
2514+++ linux-2.4.31-bs/drivers/video/fbcon.c 2005-05-06 11:21:29.000000000 +0100
2515@@ -76,6 +76,7 @@
2516 #include <linux/smp.h>
2517 #include <linux/init.h>
2518 #include <linux/pm.h>
2519+#include <linux/vmalloc.h>
2520
2521 #include <asm/irq.h>
2522 #include <asm/system.h>
2523@@ -104,6 +105,23 @@
2524 #include <video/fbcon-mac.h> /* for 6x11 font on mac */
2525 #include <video/font.h>
2526
2527+#ifdef CONFIG_FBCON_SPLASHSCREEN
2528+#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */
2529+#include "fbcon-splash.h"
2530+
2531+extern void con_remap_def_color(int currcons, int new_color);
2532+
2533+extern int splash_default;
2534+extern int splash_shown;
2535+
2536+extern struct display_switch fbcon_splash16;
2537+
2538+#ifdef CONFIG_PROC_FS
2539+int splash_proc_register(void);
2540+int splash_proc_unregister(void);
2541+#endif
2542+#endif
2543+
2544 #ifdef FBCONDEBUG
2545 # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
2546 #else
2547@@ -478,6 +496,10 @@
2548 }
2549
2550
2551+#ifdef CONFIG_FBCON_SPLASHSCREEN
2552+static int splash_registered=0;
2553+#endif
2554+
2555 static void fbcon_init(struct vc_data *conp, int init)
2556 {
2557 int unit = conp->vc_num;
2558@@ -501,6 +523,26 @@
2559 fb_display[unit].cmap.green = 0;
2560 fb_display[unit].cmap.blue = 0;
2561 fb_display[unit].cmap.transp = 0;
2562+
2563+#ifdef CONFIG_FBCON_SPLASHSCREEN
2564+ if (!splash_registered && fb_display[unit].var.bits_per_pixel == 16 ) {
2565+ if (unit == 0 && !fb_display[unit].splash_data) {
2566+ extern unsigned long initrd_start, initrd_end;
2567+
2568+ if (initrd_start && !splash_getraw((unsigned char *)initrd_start, (unsigned char *)initrd_end) && fb_display[unit].splash_data)
2569+ fb_display[unit].splash_data->splash_state = splash_default & 1;
2570+ }
2571+ splash_registered = 1;
2572+#ifdef CONFIG_PROC_FS
2573+ splash_proc_register();
2574+#endif
2575+ }
2576+ if (fb_display[unit].splash_data && fb_display[unit].var.bits_per_pixel != 16 ) {
2577+ vfree(fb_display[unit].splash_data);
2578+ fb_display[unit].splash_data = 0;
2579+ }
2580+#endif
2581+
2582 fbcon_setup(unit, init, !init);
2583 /* Must be done after fbcon_setup to prevent excess updates */
2584 conp->vc_display_fg = &info->display_fg;
2585@@ -517,6 +559,15 @@
2586 fbcon_free_font(p);
2587 p->dispsw = &fbcon_dummy;
2588 p->conp = 0;
2589+#ifdef CONFIG_FBCON_SPLASHSCREEN
2590+ if (splash_registered) {
2591+#ifdef CONFIG_PROC_FS
2592+ splash_proc_unregister();
2593+#endif
2594+ splash_registered = 0;
2595+ }
2596+#endif
2597+
2598 }
2599
2600
2601@@ -658,6 +709,14 @@
2602 nr_cols = p->var.xres/fontwidth(p);
2603 nr_rows = p->var.yres/fontheight(p);
2604
2605+#ifdef CONFIG_FBCON_SPLASHSCREEN
2606+ if (p->splash_data && p->splash_data->splash_state) {
2607+ nr_cols = p->splash_data->splash_text_wi / fontwidth(p);
2608+ nr_rows = p->splash_data->splash_text_he / fontheight(p);
2609+ logo = 0;
2610+ }
2611+#endif
2612+
2613 if (logo) {
2614 /* Need to make room for the logo */
2615 int cnt, step, erase_char;
2616@@ -735,6 +794,12 @@
2617 p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
2618 p->bgcol = 0;
2619
2620+#ifdef CONFIG_FBCON_SPLASHSCREEN
2621+ if(p->splash_data && p->splash_data->splash_state)
2622+ con_remap_def_color(con, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
2623+#endif
2624+
2625+
2626 if (!init) {
2627 if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)
2628 vc_resize_con(nr_rows, nr_cols, con);
2629@@ -1324,6 +1389,9 @@
2630 if (softback_top)
2631 fbcon_softback_note(conp, t, count);
2632 if (logo_shown >= 0) goto redraw_up;
2633+#ifdef CONFIG_FBCON_SPLASHSCREEN
2634+ if (splash_shown) goto redraw_up;
2635+#endif
2636 switch (p->scrollmode & __SCROLL_YMASK) {
2637 case __SCROLL_YMOVE:
2638 p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
2639@@ -1384,6 +1452,9 @@
2640 case SM_DOWN:
2641 if (count > conp->vc_rows) /* Maximum realistic size */
2642 count = conp->vc_rows;
2643+#ifdef CONFIG_FBCON_SPLASHSCREEN
2644+ if (splash_shown) goto redraw_down;
2645+#endif
2646 switch (p->scrollmode & __SCROLL_YMASK) {
2647 case __SCROLL_YMOVE:
2648 p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
2649@@ -1500,6 +1571,13 @@
2650 }
2651 return;
2652 }
2653+#ifdef CONFIG_FBCON_SPLASHSCREEN
2654+ if (splash_shown && sy == dy) {
2655+ /* must use slower redraw bmove to keep background pic intact */
2656+ fbcon_redraw_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
2657+ return;
2658+ }
2659+#endif
2660 p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
2661 }
2662
2663@@ -1510,6 +1588,10 @@
2664 struct display *p = &fb_display[unit];
2665 struct fb_info *info = p->fb_info;
2666
2667+#ifdef CONFIG_FBCON_SPLASHSCREEN
2668+ splash_prepare(p);
2669+#endif
2670+
2671 if (softback_top) {
2672 int l = fbcon_softback_size / conp->vc_size_row;
2673 if (softback_lines)
2674@@ -1570,13 +1652,40 @@
2675 struct display *p = &fb_display[conp->vc_num];
2676 struct fb_info *info = p->fb_info;
2677
2678+#ifdef CONFIG_FBCON_SPLASHSCREEN
2679+ struct display_switch *olddispsw=NULL;
2680+ char *oldscreen_base=NULL;
2681+#endif
2682+
2683 if (blank < 0) /* Entering graphics mode */
2684 return 0;
2685
2686+#ifdef CONFIG_FBCON_SPLASHSCREEN
2687+
2688+ if (p->splash_data && p->splash_data->oldscreen_base) {
2689+ oldscreen_base = p->screen_base;
2690+ p->screen_base = p->splash_data->oldscreen_base;
2691+ }
2692+ if (p->splash_data && p->splash_data->olddispsw) {
2693+ olddispsw = p->dispsw;
2694+ p->dispsw = p->splash_data->olddispsw;
2695+ }
2696+#endif
2697+
2698 fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
2699
2700 if (!p->can_soft_blank) {
2701 if (blank) {
2702+#ifdef CONFIG_FBCON_SPLASHSCREEN
2703+ if (p->splash_data && p->splash_data->oldscreen_base) {
2704+ oldscreen_base = p->screen_base;
2705+ p->screen_base = p->splash_data->oldscreen_base;
2706+ }
2707+ if (p->splash_data && p->splash_data->olddispsw) {
2708+ olddispsw = p->dispsw;
2709+ p->dispsw = p->splash_data->olddispsw;
2710+ }
2711+#endif
2712 if (p->visual == FB_VISUAL_MONO01) {
2713 if (p->screen_base)
2714 fb_memset255(p->screen_base,
2715@@ -1584,20 +1693,33 @@
2716 p->var.bits_per_pixel>>3);
2717 } else {
2718 unsigned short oldc;
2719- u_int height;
2720+ u_int height, width;
2721 u_int y_break;
2722
2723 oldc = conp->vc_video_erase_char;
2724 conp->vc_video_erase_char &= p->charmask;
2725 height = conp->vc_rows;
2726+ width = conp->vc_cols;
2727 y_break = p->vrows-p->yscroll;
2728+#ifdef CONFIG_FBCON_SPLASHSCREEN
2729+ if (splash_shown) {
2730+ width=p->var.xres/fontwidth(p);
2731+ height=p->var.yres/fontheight(p);
2732+ }
2733+#endif
2734 if (height > y_break) {
2735- p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);
2736- p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);
2737+ p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, width);
2738+ p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, width);
2739 } else
2740- p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);
2741+ p->dispsw->clear(conp, p, real_y(p, 0), 0, height, width);
2742 conp->vc_video_erase_char = oldc;
2743 }
2744+#ifdef CONFIG_FBCON_SPLASHSCREEN
2745+ if(oldscreen_base)
2746+ p->screen_base=oldscreen_base;
2747+ if(olddispsw)
2748+ p->dispsw=olddispsw;
2749+#endif
2750 return 0;
2751 } else {
2752 /* Tell console.c that it has to restore the screen itself */
2753@@ -1763,13 +1885,21 @@
2754
2755 if (resize) {
2756 struct vc_data *conp = p->conp;
2757+ __u32 xres = p->var.xres, yres = p->var.yres;
2758+
2759 /* reset wrap/pan */
2760 p->var.xoffset = p->var.yoffset = p->yscroll = 0;
2761 p->vrows = p->var.yres_virtual/h;
2762- if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
2763+#ifdef CONFIG_FBCON_SPLASHSCREEN
2764+ if (p->splash_data && p->splash_data->splash_state) {
2765+ xres = p->splash_data->splash_text_wi;
2766+ yres = p->splash_data->splash_text_he;
2767+ }
2768+#endif
2769+ if ((yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
2770 p->vrows--;
2771 updatescrollmode(p);
2772- vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
2773+ vc_resize_con( yres/h, xres/w, unit );
2774 if (CON_IS_VISIBLE(conp) && softback_buf) {
2775 int l = fbcon_softback_size / conp->vc_size_row;
2776 if (l > 5)
2777@@ -2193,6 +2323,9 @@
2778 if (p->fb_info->fbops->fb_rasterimg)
2779 p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
2780
2781+#ifdef CONFIG_FBCON_SPLASHSCREEN
2782+ if (!splash_shown) {
2783+#endif
2784 for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
2785 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
2786
2787@@ -2454,7 +2587,9 @@
2788 }
2789 #endif
2790 }
2791-
2792+#ifdef CONFIG_FBCON_SPLASHSCREEN
2793+ }
2794+#endif
2795 if (p->fb_info->fbops->fb_rasterimg)
2796 p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
2797
2798diff -ruN linux-2.4.31/include/video/fbcon.h linux-2.4.31-bs/include/video/fbcon.h
2799--- linux-2.4.31/include/video/fbcon.h 2003-08-25 12:44:44.000000000 +0100
2800+++ linux-2.4.31-bs/include/video/fbcon.h 2005-05-18 11:02:36.000000000 +0100
2801@@ -42,6 +42,35 @@
2802 unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
2803 };
2804
2805+#ifdef CONFIG_FBCON_SPLASHSCREEN
2806+struct splash_data {
2807+ int splash_state; /* show splash? */
2808+ int splash_color; /* transparent color */
2809+ int splash_fg_color; /* foreground color */
2810+ int splash_width; /* width of image */
2811+ int splash_height; /* height of image */
2812+ int splash_text_xo; /* text area origin */
2813+ int splash_text_yo;
2814+ int splash_text_wi; /* text area size */
2815+ int splash_text_he;
2816+ int splash_showtext; /* silent/verbose mode */
2817+ int splash_boxcount;
2818+ int splash_percent;
2819+ int splash_overpaintok; /* is it ok to overpaint boxes */
2820+ int splash_palcnt;
2821+ struct display_switch *olddispsw; /* old dispsw, normally &fbcon_cfb16*/
2822+ char *oldscreen_base; /* pointer to top of virtual screen */
2823+ unsigned char *splash_boxes;
2824+ unsigned char *splash_jpeg; /* jpeg */
2825+ unsigned char *splash_palette; /* palette for 8-bit */
2826+
2827+ int splash_dosilent; /* show silent jpeg */
2828+ unsigned char *splash_silentjpeg;
2829+ unsigned char *splash_sboxes;
2830+ int splash_sboxcount;
2831+};
2832+#endif
2833+
2834 extern struct display_switch fbcon_dummy;
2835
2836 /*
2837@@ -95,6 +124,11 @@
2838 short yscroll; /* Hardware scrolling */
2839 unsigned char fgshift, bgshift;
2840 unsigned short charmask; /* 0xff or 0x1ff */
2841+
2842+#ifdef CONFIG_FBCON_SPLASHSCREEN
2843+ struct splash_data *splash_data;
2844+#endif
2845+
2846 };
2847
2848 /* drivers/video/fbcon.c */
2849diff -ruN linux-2.4.31/kernel/panic.c linux-2.4.31-bs/kernel/panic.c
2850--- linux-2.4.31/kernel/panic.c 2004-11-17 11:54:22.000000000 +0000
2851+++ linux-2.4.31-bs/kernel/panic.c 2005-05-18 11:08:01.000000000 +0100
2852@@ -83,6 +83,13 @@
2853 * We can't use the "normal" timers since we just panicked..
2854 */
2855 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
2856+
2857+#ifdef CONFIG_FBCON_SPLASHSCREEN
2858+ {
2859+ extern int splash_verbose(void);
2860+ (void)splash_verbose();
2861+ }
2862+#endif
2863 mdelay(panic_timeout*1000);
2864 /*
2865 * Should we run the reboot notifier. For the moment Im
2866@@ -103,6 +110,12 @@
2867 disabled_wait(caller);
2868 #endif
2869 sti();
2870+#ifdef CONFIG_FBCON_SPLASHSCREEN
2871+ {
2872+ extern int splash_verbose(void);
2873+ (void)splash_verbose();
2874+ }
2875+#endif
2876 for(;;) {
2877 #if defined(CONFIG_X86) && defined(CONFIG_VT)
2878 extern void panic_blink(void);