aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2013-11-06 17:38:59 -0500
committerHelge Deller <deller@gmx.de>2013-11-07 16:46:20 -0500
commit0219132fe7c26574371232b50db085573f6fbd3f (patch)
tree48e186aff406365fe45922b9b0bc06e7ef4cc7f9
parent1f2048fd8bc4219db821611da305a74f4b72b3c3 (diff)
parisc: sticon - unbreak on 64bit kernel
STI text console (sticon) was broken on 64bit machines with more than 4GB RAM and this lead in some cases to a kernel crash. Since sticon uses the 32bit STI API it needs to keep pointers to memory below 4GB. But on a 64bit kernel some memory regions (e.g. the kernel stack) might be above 4GB which then may crash the kernel in the STI functions. Additionally sticon didn't selected the built-in framebuffer fonts by default. This is now fixed. On a side-note: Theoretically we could enhance the sticon driver to use the 64bit STI API. But - beside the fact that some machines don't provide a 64bit STI ROM - this would just add complexity. Signed-off-by: Helge Deller <deller@gmx.de> Cc: stable@vger.kernel.org # 3.8+
-rw-r--r--drivers/video/console/sticore.c166
-rw-r--r--drivers/video/sticore.h62
-rw-r--r--drivers/video/stifb.c10
3 files changed, 158 insertions, 80 deletions
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 35687fd56456..4ad24f2c6472 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -3,7 +3,7 @@
3 * core code for console driver using HP's STI firmware 3 * core code for console driver using HP's STI firmware
4 * 4 *
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 * Copyright (C) 2001-2003 Helge Deller <deller@gmx.de> 6 * Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>
7 * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de> 7 * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
8 * 8 *
9 * TODO: 9 * TODO:
@@ -30,7 +30,7 @@
30 30
31#include "../sticore.h" 31#include "../sticore.h"
32 32
33#define STI_DRIVERVERSION "Version 0.9a" 33#define STI_DRIVERVERSION "Version 0.9b"
34 34
35static struct sti_struct *default_sti __read_mostly; 35static struct sti_struct *default_sti __read_mostly;
36 36
@@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = {
73 73
74static int sti_init_graph(struct sti_struct *sti) 74static int sti_init_graph(struct sti_struct *sti)
75{ 75{
76 struct sti_init_inptr_ext inptr_ext = { 0, }; 76 struct sti_init_inptr *inptr = &sti->sti_data->init_inptr;
77 struct sti_init_inptr inptr = { 77 struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext;
78 .text_planes = 3, /* # of text planes (max 3 for STI) */ 78 struct sti_init_outptr *outptr = &sti->sti_data->init_outptr;
79 .ext_ptr = STI_PTR(&inptr_ext)
80 };
81 struct sti_init_outptr outptr = { 0, };
82 unsigned long flags; 79 unsigned long flags;
83 int ret; 80 int ret, err;
84 81
85 spin_lock_irqsave(&sti->lock, flags); 82 spin_lock_irqsave(&sti->lock, flags);
86 83
87 ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr, 84 memset(inptr, 0, sizeof(*inptr));
88 &outptr, sti->glob_cfg); 85 inptr->text_planes = 3; /* # of text planes (max 3 for STI) */
86 memset(inptr_ext, 0, sizeof(*inptr_ext));
87 inptr->ext_ptr = STI_PTR(inptr_ext);
88 outptr->errno = 0;
89
90 ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr,
91 outptr, sti->glob_cfg);
92
93 if (ret >= 0)
94 sti->text_planes = outptr->text_planes;
95 err = outptr->errno;
89 96
90 spin_unlock_irqrestore(&sti->lock, flags); 97 spin_unlock_irqrestore(&sti->lock, flags);
91 98
92 if (ret < 0) { 99 if (ret < 0) {
93 printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno); 100 pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);
94 return -1; 101 return -1;
95 } 102 }
96 103
97 sti->text_planes = outptr.text_planes;
98 return 0; 104 return 0;
99} 105}
100 106
@@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = {
104 110
105static void sti_inq_conf(struct sti_struct *sti) 111static void sti_inq_conf(struct sti_struct *sti)
106{ 112{
107 struct sti_conf_inptr inptr = { 0, }; 113 struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr;
114 struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr;
108 unsigned long flags; 115 unsigned long flags;
109 s32 ret; 116 s32 ret;
110 117
111 sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext); 118 outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);
112 119
113 do { 120 do {
114 spin_lock_irqsave(&sti->lock, flags); 121 spin_lock_irqsave(&sti->lock, flags);
115 ret = STI_CALL(sti->inq_conf, &default_conf_flags, 122 memset(inptr, 0, sizeof(*inptr));
116 &inptr, &sti->outptr, sti->glob_cfg); 123 ret = sti_call(sti, sti->inq_conf, &default_conf_flags,
124 inptr, outptr, sti->glob_cfg);
117 spin_unlock_irqrestore(&sti->lock, flags); 125 spin_unlock_irqrestore(&sti->lock, flags);
118 } while (ret == 1); 126 } while (ret == 1);
119} 127}
@@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = {
126void 134void
127sti_putc(struct sti_struct *sti, int c, int y, int x) 135sti_putc(struct sti_struct *sti, int c, int y, int x)
128{ 136{
129 struct sti_font_inptr inptr = { 137 struct sti_font_inptr *inptr = &sti->sti_data->font_inptr;
138 struct sti_font_inptr inptr_default = {
130 .font_start_addr= STI_PTR(sti->font->raw), 139 .font_start_addr= STI_PTR(sti->font->raw),
131 .index = c_index(sti, c), 140 .index = c_index(sti, c),
132 .fg_color = c_fg(sti, c), 141 .fg_color = c_fg(sti, c),
@@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x)
134 .dest_x = x * sti->font_width, 143 .dest_x = x * sti->font_width,
135 .dest_y = y * sti->font_height, 144 .dest_y = y * sti->font_height,
136 }; 145 };
137 struct sti_font_outptr outptr = { 0, }; 146 struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;
138 s32 ret; 147 s32 ret;
139 unsigned long flags; 148 unsigned long flags;
140 149
141 do { 150 do {
142 spin_lock_irqsave(&sti->lock, flags); 151 spin_lock_irqsave(&sti->lock, flags);
143 ret = STI_CALL(sti->font_unpmv, &default_font_flags, 152 *inptr = inptr_default;
144 &inptr, &outptr, sti->glob_cfg); 153 ret = sti_call(sti, sti->font_unpmv, &default_font_flags,
154 inptr, outptr, sti->glob_cfg);
145 spin_unlock_irqrestore(&sti->lock, flags); 155 spin_unlock_irqrestore(&sti->lock, flags);
146 } while (ret == 1); 156 } while (ret == 1);
147} 157}
@@ -156,7 +166,8 @@ void
156sti_set(struct sti_struct *sti, int src_y, int src_x, 166sti_set(struct sti_struct *sti, int src_y, int src_x,
157 int height, int width, u8 color) 167 int height, int width, u8 color)
158{ 168{
159 struct sti_blkmv_inptr inptr = { 169 struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
170 struct sti_blkmv_inptr inptr_default = {
160 .fg_color = color, 171 .fg_color = color,
161 .bg_color = color, 172 .bg_color = color,
162 .src_x = src_x, 173 .src_x = src_x,
@@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
166 .width = width, 177 .width = width,
167 .height = height, 178 .height = height,
168 }; 179 };
169 struct sti_blkmv_outptr outptr = { 0, }; 180 struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
170 s32 ret; 181 s32 ret;
171 unsigned long flags; 182 unsigned long flags;
172 183
173 do { 184 do {
174 spin_lock_irqsave(&sti->lock, flags); 185 spin_lock_irqsave(&sti->lock, flags);
175 ret = STI_CALL(sti->block_move, &clear_blkmv_flags, 186 *inptr = inptr_default;
176 &inptr, &outptr, sti->glob_cfg); 187 ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
188 inptr, outptr, sti->glob_cfg);
177 spin_unlock_irqrestore(&sti->lock, flags); 189 spin_unlock_irqrestore(&sti->lock, flags);
178 } while (ret == 1); 190 } while (ret == 1);
179} 191}
@@ -182,7 +194,8 @@ void
182sti_clear(struct sti_struct *sti, int src_y, int src_x, 194sti_clear(struct sti_struct *sti, int src_y, int src_x,
183 int height, int width, int c) 195 int height, int width, int c)
184{ 196{
185 struct sti_blkmv_inptr inptr = { 197 struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
198 struct sti_blkmv_inptr inptr_default = {
186 .fg_color = c_fg(sti, c), 199 .fg_color = c_fg(sti, c),
187 .bg_color = c_bg(sti, c), 200 .bg_color = c_bg(sti, c),
188 .src_x = src_x * sti->font_width, 201 .src_x = src_x * sti->font_width,
@@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
192 .width = width * sti->font_width, 205 .width = width * sti->font_width,
193 .height = height* sti->font_height, 206 .height = height* sti->font_height,
194 }; 207 };
195 struct sti_blkmv_outptr outptr = { 0, }; 208 struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
196 s32 ret; 209 s32 ret;
197 unsigned long flags; 210 unsigned long flags;
198 211
199 do { 212 do {
200 spin_lock_irqsave(&sti->lock, flags); 213 spin_lock_irqsave(&sti->lock, flags);
201 ret = STI_CALL(sti->block_move, &clear_blkmv_flags, 214 *inptr = inptr_default;
202 &inptr, &outptr, sti->glob_cfg); 215 ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
216 inptr, outptr, sti->glob_cfg);
203 spin_unlock_irqrestore(&sti->lock, flags); 217 spin_unlock_irqrestore(&sti->lock, flags);
204 } while (ret == 1); 218 } while (ret == 1);
205} 219}
@@ -212,7 +226,8 @@ void
212sti_bmove(struct sti_struct *sti, int src_y, int src_x, 226sti_bmove(struct sti_struct *sti, int src_y, int src_x,
213 int dst_y, int dst_x, int height, int width) 227 int dst_y, int dst_x, int height, int width)
214{ 228{
215 struct sti_blkmv_inptr inptr = { 229 struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
230 struct sti_blkmv_inptr inptr_default = {
216 .src_x = src_x * sti->font_width, 231 .src_x = src_x * sti->font_width,
217 .src_y = src_y * sti->font_height, 232 .src_y = src_y * sti->font_height,
218 .dest_x = dst_x * sti->font_width, 233 .dest_x = dst_x * sti->font_width,
@@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,
220 .width = width * sti->font_width, 235 .width = width * sti->font_width,
221 .height = height* sti->font_height, 236 .height = height* sti->font_height,
222 }; 237 };
223 struct sti_blkmv_outptr outptr = { 0, }; 238 struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
224 s32 ret; 239 s32 ret;
225 unsigned long flags; 240 unsigned long flags;
226 241
227 do { 242 do {
228 spin_lock_irqsave(&sti->lock, flags); 243 spin_lock_irqsave(&sti->lock, flags);
229 ret = STI_CALL(sti->block_move, &default_blkmv_flags, 244 *inptr = inptr_default;
230 &inptr, &outptr, sti->glob_cfg); 245 ret = sti_call(sti, sti->block_move, &default_blkmv_flags,
246 inptr, outptr, sti->glob_cfg);
231 spin_unlock_irqrestore(&sti->lock, flags); 247 spin_unlock_irqrestore(&sti->lock, flags);
232 } while (ret == 1); 248 } while (ret == 1);
233} 249}
@@ -284,7 +300,7 @@ __setup("sti=", sti_setup);
284 300
285 301
286 302
287static char *font_name[MAX_STI_ROMS] = { "VGA8x16", }; 303static char *font_name[MAX_STI_ROMS];
288static int font_index[MAX_STI_ROMS], 304static int font_index[MAX_STI_ROMS],
289 font_height[MAX_STI_ROMS], 305 font_height[MAX_STI_ROMS],
290 font_width[MAX_STI_ROMS]; 306 font_width[MAX_STI_ROMS];
@@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti)
389 "%d used bits\n" 405 "%d used bits\n"
390 "%d planes\n" 406 "%d planes\n"
391 "attributes %08x\n", 407 "attributes %08x\n",
392 sti->outptr.bits_per_pixel, 408 sti->sti_data->inq_outptr.bits_per_pixel,
393 sti->outptr.bits_used, 409 sti->sti_data->inq_outptr.bits_used,
394 sti->outptr.planes, 410 sti->sti_data->inq_outptr.planes,
395 sti->outptr.attributes)); 411 sti->sti_data->inq_outptr.attributes));
396} 412}
397 413
398static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, 414static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
@@ -402,24 +418,21 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
402 struct sti_glob_cfg_ext *glob_cfg_ext; 418 struct sti_glob_cfg_ext *glob_cfg_ext;
403 void *save_addr; 419 void *save_addr;
404 void *sti_mem_addr; 420 void *sti_mem_addr;
405 const int save_addr_size = 1024; /* XXX */ 421 int i, size;
406 int i;
407 422
408 if (!sti->sti_mem_request) 423 if (sti->sti_mem_request < 256)
409 sti->sti_mem_request = 256; /* STI default */ 424 sti->sti_mem_request = 256; /* STI default */
410 425
411 glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); 426 size = sizeof(struct sti_all_data) + sti->sti_mem_request - 256;
412 glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
413 save_addr = kzalloc(save_addr_size, GFP_KERNEL);
414 sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL);
415 427
416 if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { 428 sti->sti_data = kzalloc(size, STI_LOWMEM);
417 kfree(glob_cfg); 429 if (!sti->sti_data)
418 kfree(glob_cfg_ext);
419 kfree(save_addr);
420 kfree(sti_mem_addr);
421 return -ENOMEM; 430 return -ENOMEM;
422 } 431
432 glob_cfg = &sti->sti_data->glob_cfg;
433 glob_cfg_ext = &sti->sti_data->glob_cfg_ext;
434 save_addr = &sti->sti_data->save_addr;
435 sti_mem_addr = &sti->sti_data->sti_mem_addr;
423 436
424 glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); 437 glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
425 glob_cfg->save_addr = STI_PTR(save_addr); 438 glob_cfg->save_addr = STI_PTR(save_addr);
@@ -475,32 +488,31 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
475 return 0; 488 return 0;
476} 489}
477 490
478#ifdef CONFIG_FB 491#ifdef CONFIG_FONTS
479static struct sti_cooked_font * 492static struct sti_cooked_font *
480sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) 493sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
481{ 494{
482 const struct font_desc *fbfont; 495 const struct font_desc *fbfont = NULL;
483 unsigned int size, bpc; 496 unsigned int size, bpc;
484 void *dest; 497 void *dest;
485 struct sti_rom_font *nf; 498 struct sti_rom_font *nf;
486 struct sti_cooked_font *cooked_font; 499 struct sti_cooked_font *cooked_font;
487 500
488 if (!fbfont_name || !strlen(fbfont_name)) 501 if (fbfont_name && strlen(fbfont_name))
489 return NULL; 502 fbfont = find_font(fbfont_name);
490 fbfont = find_font(fbfont_name);
491 if (!fbfont) 503 if (!fbfont)
492 fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0); 504 fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
493 if (!fbfont) 505 if (!fbfont)
494 return NULL; 506 return NULL;
495 507
496 DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n", 508 pr_info("STI selected %dx%d framebuffer font %s for sticon\n",
497 fbfont->width, fbfont->height, fbfont->name)); 509 fbfont->width, fbfont->height, fbfont->name);
498 510
499 bpc = ((fbfont->width+7)/8) * fbfont->height; 511 bpc = ((fbfont->width+7)/8) * fbfont->height;
500 size = bpc * 256; 512 size = bpc * 256;
501 size += sizeof(struct sti_rom_font); 513 size += sizeof(struct sti_rom_font);
502 514
503 nf = kzalloc(size, GFP_KERNEL); 515 nf = kzalloc(size, STI_LOWMEM);
504 if (!nf) 516 if (!nf)
505 return NULL; 517 return NULL;
506 518
@@ -637,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f)
637 unsigned char *n, *p, *q; 649 unsigned char *n, *p, *q;
638 int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); 650 int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
639 651
640 n = kzalloc (4*size, GFP_KERNEL); 652 n = kzalloc(4*size, STI_LOWMEM);
641 if (!n) 653 if (!n)
642 return NULL; 654 return NULL;
643 p = n + 3; 655 p = n + 3;
@@ -673,7 +685,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address)
673 sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size); 685 sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);
674 686
675 size = (size+3) / 4; 687 size = (size+3) / 4;
676 raw = kmalloc(size, GFP_KERNEL); 688 raw = kmalloc(size, STI_LOWMEM);
677 if (raw) { 689 if (raw) {
678 sti_bmode_rom_copy(address, size, raw); 690 sti_bmode_rom_copy(address, size, raw);
679 memmove (&raw->res004, &raw->type[0], 0x3c); 691 memmove (&raw->res004, &raw->type[0], 0x3c);
@@ -707,7 +719,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address)
707 /* read the ROM size directly from the struct in ROM */ 719 /* read the ROM size directly from the struct in ROM */
708 size = gsc_readl(address + offsetof(struct sti_rom,last_addr)); 720 size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
709 721
710 raw = kmalloc(size, GFP_KERNEL); 722 raw = kmalloc(size, STI_LOWMEM);
711 if (raw) 723 if (raw)
712 sti_rom_copy(address, size, raw); 724 sti_rom_copy(address, size, raw);
713 725
@@ -743,6 +755,10 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
743 755
744 address = (unsigned long) STI_PTR(raw); 756 address = (unsigned long) STI_PTR(raw);
745 757
758 pr_info("STI ROM supports 32 %sbit firmware functions.\n",
759 raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64
760 ? "and 64 " : "");
761
746 sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff); 762 sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff);
747 sti->block_move = address + (raw->block_move & 0x03ffffff); 763 sti->block_move = address + (raw->block_move & 0x03ffffff);
748 sti->init_graph = address + (raw->init_graph & 0x03ffffff); 764 sti->init_graph = address + (raw->init_graph & 0x03ffffff);
@@ -901,7 +917,8 @@ test_rom:
901 sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request); 917 sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
902 sti_dump_outptr(sti); 918 sti_dump_outptr(sti);
903 919
904 printk(KERN_INFO " graphics card name: %s\n", sti->outptr.dev_name ); 920 pr_info(" graphics card name: %s\n",
921 sti->sti_data->inq_outptr.dev_name);
905 922
906 sti_roms[num_sti_roms] = sti; 923 sti_roms[num_sti_roms] = sti;
907 num_sti_roms++; 924 num_sti_roms++;
@@ -1073,6 +1090,29 @@ struct sti_struct * sti_get_rom(unsigned int index)
1073} 1090}
1074EXPORT_SYMBOL(sti_get_rom); 1091EXPORT_SYMBOL(sti_get_rom);
1075 1092
1093
1094int sti_call(const struct sti_struct *sti, unsigned long func,
1095 const void *flags, void *inptr, void *outptr,
1096 struct sti_glob_cfg *glob_cfg)
1097{
1098 unsigned long _flags = STI_PTR(flags);
1099 unsigned long _inptr = STI_PTR(inptr);
1100 unsigned long _outptr = STI_PTR(outptr);
1101 unsigned long _glob_cfg = STI_PTR(glob_cfg);
1102 int ret;
1103
1104#ifdef CONFIG_64BIT
1105 /* Check for overflow when using 32bit STI on 64bit kernel. */
1106 if (WARN_ONCE(_flags>>32 || _inptr>>32 || _outptr>>32 || _glob_cfg>>32,
1107 "Out of 32bit-range pointers!"))
1108 return -1;
1109#endif
1110
1111 ret = pdc_sti_call(func, _flags, _inptr, _outptr, _glob_cfg);
1112
1113 return ret;
1114}
1115
1076MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); 1116MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");
1077MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); 1117MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");
1078MODULE_LICENSE("GPL v2"); 1118MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h
index addf7b615ef8..af1619536ac8 100644
--- a/drivers/video/sticore.h
+++ b/drivers/video/sticore.h
@@ -18,6 +18,9 @@
18#define STI_FONT_HPROMAN8 1 18#define STI_FONT_HPROMAN8 1
19#define STI_FONT_KANA8 2 19#define STI_FONT_KANA8 2
20 20
21#define ALT_CODE_TYPE_UNKNOWN 0x00 /* alt code type values */
22#define ALT_CODE_TYPE_PA_RISC_64 0x01
23
21/* The latency of the STI functions cannot really be reduced by setting 24/* The latency of the STI functions cannot really be reduced by setting
22 * this to 0; STI doesn't seem to be designed to allow calling a different 25 * this to 0; STI doesn't seem to be designed to allow calling a different
23 * function (or the same function with different arguments) after a 26 * function (or the same function with different arguments) after a
@@ -40,14 +43,6 @@
40 43
41#define STI_PTR(p) ( virt_to_phys(p) ) 44#define STI_PTR(p) ( virt_to_phys(p) )
42#define PTR_STI(p) ( phys_to_virt((unsigned long)p) ) 45#define PTR_STI(p) ( phys_to_virt((unsigned long)p) )
43#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
44 ({ \
45 pdc_sti_call( func, STI_PTR(flags), \
46 STI_PTR(inptr), \
47 STI_PTR(outptr), \
48 STI_PTR(glob_cfg)); \
49 })
50
51 46
52#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) 47#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
53#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) 48#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
@@ -56,6 +51,12 @@
56#define sti_font_x(sti) (PTR_STI(sti->font)->width) 51#define sti_font_x(sti) (PTR_STI(sti->font)->width)
57#define sti_font_y(sti) (PTR_STI(sti->font)->height) 52#define sti_font_y(sti) (PTR_STI(sti->font)->height)
58 53
54#ifdef CONFIG_64BIT
55#define STI_LOWMEM (GFP_KERNEL | GFP_DMA)
56#else
57#define STI_LOWMEM (GFP_KERNEL)
58#endif
59
59 60
60/* STI function configuration structs */ 61/* STI function configuration structs */
61 62
@@ -306,6 +307,34 @@ struct sti_blkmv_outptr {
306}; 307};
307 308
308 309
310/* sti_all_data is an internal struct which needs to be allocated in
311 * low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */
312
313struct sti_all_data {
314 struct sti_glob_cfg glob_cfg;
315 struct sti_glob_cfg_ext glob_cfg_ext;
316
317 struct sti_conf_inptr inq_inptr;
318 struct sti_conf_outptr inq_outptr; /* configuration */
319 struct sti_conf_outptr_ext inq_outptr_ext;
320
321 struct sti_init_inptr_ext init_inptr_ext;
322 struct sti_init_inptr init_inptr;
323 struct sti_init_outptr init_outptr;
324
325 struct sti_blkmv_inptr blkmv_inptr;
326 struct sti_blkmv_outptr blkmv_outptr;
327
328 struct sti_font_inptr font_inptr;
329 struct sti_font_outptr font_outptr;
330
331 /* leave as last entries */
332 unsigned long save_addr[1024 / sizeof(unsigned long)];
333 /* min 256 bytes which is STI default, max sti->sti_mem_request */
334 unsigned long sti_mem_addr[256 / sizeof(unsigned long)];
335 /* do not add something below here ! */
336};
337
309/* internal generic STI struct */ 338/* internal generic STI struct */
310 339
311struct sti_struct { 340struct sti_struct {
@@ -330,11 +359,9 @@ struct sti_struct {
330 region_t regions[STI_REGION_MAX]; 359 region_t regions[STI_REGION_MAX];
331 unsigned long regions_phys[STI_REGION_MAX]; 360 unsigned long regions_phys[STI_REGION_MAX];
332 361
333 struct sti_glob_cfg *glob_cfg; 362 struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */
334 struct sti_cooked_font *font; /* ptr to selected font (cooked) */
335 363
336 struct sti_conf_outptr outptr; /* configuration */ 364 struct sti_cooked_font *font; /* ptr to selected font (cooked) */
337 struct sti_conf_outptr_ext outptr_ext;
338 365
339 struct pci_dev *pd; 366 struct pci_dev *pd;
340 367
@@ -343,6 +370,9 @@ struct sti_struct {
343 370
344 /* pointer to the fb_info where this STI device is used */ 371 /* pointer to the fb_info where this STI device is used */
345 struct fb_info *info; 372 struct fb_info *info;
373
374 /* pointer to all internal data */
375 struct sti_all_data *sti_data;
346}; 376};
347 377
348 378
@@ -350,6 +380,14 @@ struct sti_struct {
350 380
351struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ 381struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
352 382
383
384/* sticore main function to call STI firmware */
385
386int sti_call(const struct sti_struct *sti, unsigned long func,
387 const void *flags, void *inptr, void *outptr,
388 struct sti_glob_cfg *glob_cfg);
389
390
353/* functions to call the STI ROM directly */ 391/* functions to call the STI ROM directly */
354 392
355void sti_putc(struct sti_struct *sti, int c, int y, int x); 393void sti_putc(struct sti_struct *sti, int c, int y, int x);
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 876648e15e9d..019a1feef995 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1101 var = &info->var; 1101 var = &info->var;
1102 1102
1103 fb->sti = sti; 1103 fb->sti = sti;
1104 dev_name = sti->sti_data->inq_outptr.dev_name;
1104 /* store upper 32bits of the graphics id */ 1105 /* store upper 32bits of the graphics id */
1105 fb->id = fb->sti->graphics_id[0]; 1106 fb->id = fb->sti->graphics_id[0];
1106 1107
@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1114 Since this driver only supports standard mode, we check 1115 Since this driver only supports standard mode, we check
1115 if the device name contains the string "DX" and tell the 1116 if the device name contains the string "DX" and tell the
1116 user how to reconfigure the card. */ 1117 user how to reconfigure the card. */
1117 if (strstr(sti->outptr.dev_name, "DX")) { 1118 if (strstr(dev_name, "DX")) {
1118 printk(KERN_WARNING 1119 printk(KERN_WARNING
1119"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n" 1120"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
1120"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", 1121"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
1121 sti->outptr.dev_name); 1122 dev_name);
1122 goto out_err0; 1123 goto out_err0;
1123 } 1124 }
1124 /* fall though */ 1125 /* fall though */
@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1130 break; 1131 break;
1131 default: 1132 default:
1132 printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n", 1133 printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
1133 sti->outptr.dev_name, fb->id); 1134 dev_name, fb->id);
1134 goto out_err0; 1135 goto out_err0;
1135 } 1136 }
1136 1137
@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1154 fb->id = S9000_ID_A1659A; 1155 fb->id = S9000_ID_A1659A;
1155 break; 1156 break;
1156 case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */ 1157 case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
1157 dev_name = fb->sti->outptr.dev_name;
1158 if (strstr(dev_name, "GRAYSCALE") || 1158 if (strstr(dev_name, "GRAYSCALE") ||
1159 strstr(dev_name, "Grayscale") || 1159 strstr(dev_name, "Grayscale") ||
1160 strstr(dev_name, "grayscale")) 1160 strstr(dev_name, "grayscale"))
@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1290 var->xres, 1290 var->xres,
1291 var->yres, 1291 var->yres,
1292 var->bits_per_pixel, 1292 var->bits_per_pixel,
1293 sti->outptr.dev_name, 1293 dev_name,
1294 fb->id, 1294 fb->id,
1295 fix->mmio_start); 1295 fix->mmio_start);
1296 1296