Commit 0219132f authored by Helge Deller's avatar Helge Deller

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: default avatarHelge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org # 3.8+
parent 1f2048fd
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* core code for console driver using HP's STI firmware * core code for console driver using HP's STI firmware
* *
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2001-2003 Helge Deller <deller@gmx.de> * Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de> * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
* *
* TODO: * TODO:
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "../sticore.h" #include "../sticore.h"
#define STI_DRIVERVERSION "Version 0.9a" #define STI_DRIVERVERSION "Version 0.9b"
static struct sti_struct *default_sti __read_mostly; static struct sti_struct *default_sti __read_mostly;
...@@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = { ...@@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = {
static int sti_init_graph(struct sti_struct *sti) static int sti_init_graph(struct sti_struct *sti)
{ {
struct sti_init_inptr_ext inptr_ext = { 0, }; struct sti_init_inptr *inptr = &sti->sti_data->init_inptr;
struct sti_init_inptr inptr = { struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext;
.text_planes = 3, /* # of text planes (max 3 for STI) */ struct sti_init_outptr *outptr = &sti->sti_data->init_outptr;
.ext_ptr = STI_PTR(&inptr_ext)
};
struct sti_init_outptr outptr = { 0, };
unsigned long flags; unsigned long flags;
int ret; int ret, err;
spin_lock_irqsave(&sti->lock, flags); spin_lock_irqsave(&sti->lock, flags);
ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr, memset(inptr, 0, sizeof(*inptr));
&outptr, sti->glob_cfg); inptr->text_planes = 3; /* # of text planes (max 3 for STI) */
memset(inptr_ext, 0, sizeof(*inptr_ext));
inptr->ext_ptr = STI_PTR(inptr_ext);
outptr->errno = 0;
ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr,
outptr, sti->glob_cfg);
if (ret >= 0)
sti->text_planes = outptr->text_planes;
err = outptr->errno;
spin_unlock_irqrestore(&sti->lock, flags); spin_unlock_irqrestore(&sti->lock, flags);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno); pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);
return -1; return -1;
} }
sti->text_planes = outptr.text_planes;
return 0; return 0;
} }
...@@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = { ...@@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = {
static void sti_inq_conf(struct sti_struct *sti) static void sti_inq_conf(struct sti_struct *sti)
{ {
struct sti_conf_inptr inptr = { 0, }; struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr;
struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr;
unsigned long flags; unsigned long flags;
s32 ret; s32 ret;
sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext); outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);
do { do {
spin_lock_irqsave(&sti->lock, flags); spin_lock_irqsave(&sti->lock, flags);
ret = STI_CALL(sti->inq_conf, &default_conf_flags, memset(inptr, 0, sizeof(*inptr));
&inptr, &sti->outptr, sti->glob_cfg); ret = sti_call(sti, sti->inq_conf, &default_conf_flags,
inptr, outptr, sti->glob_cfg);
spin_unlock_irqrestore(&sti->lock, flags); spin_unlock_irqrestore(&sti->lock, flags);
} while (ret == 1); } while (ret == 1);
} }
...@@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = { ...@@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = {
void void
sti_putc(struct sti_struct *sti, int c, int y, int x) sti_putc(struct sti_struct *sti, int c, int y, int x)
{ {
struct sti_font_inptr inptr = { struct sti_font_inptr *inptr = &sti->sti_data->font_inptr;
struct sti_font_inptr inptr_default = {
.font_start_addr= STI_PTR(sti->font->raw), .font_start_addr= STI_PTR(sti->font->raw),
.index = c_index(sti, c), .index = c_index(sti, c),
.fg_color = c_fg(sti, c), .fg_color = c_fg(sti, c),
...@@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x) ...@@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x)
.dest_x = x * sti->font_width, .dest_x = x * sti->font_width,
.dest_y = y * sti->font_height, .dest_y = y * sti->font_height,
}; };
struct sti_font_outptr outptr = { 0, }; struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;
s32 ret; s32 ret;
unsigned long flags; unsigned long flags;
do { do {
spin_lock_irqsave(&sti->lock, flags); spin_lock_irqsave(&sti->lock, flags);
ret = STI_CALL(sti->font_unpmv, &default_font_flags, *inptr = inptr_default;
&inptr, &outptr, sti->glob_cfg); ret = sti_call(sti, sti->font_unpmv, &default_font_flags,
inptr, outptr, sti->glob_cfg);
spin_unlock_irqrestore(&sti->lock, flags); spin_unlock_irqrestore(&sti->lock, flags);
} while (ret == 1); } while (ret == 1);
} }
...@@ -156,7 +166,8 @@ void ...@@ -156,7 +166,8 @@ void
sti_set(struct sti_struct *sti, int src_y, int src_x, sti_set(struct sti_struct *sti, int src_y, int src_x,
int height, int width, u8 color) int height, int width, u8 color)
{ {
struct sti_blkmv_inptr inptr = { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
struct sti_blkmv_inptr inptr_default = {
.fg_color = color, .fg_color = color,
.bg_color = color, .bg_color = color,
.src_x = src_x, .src_x = src_x,
...@@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x, ...@@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
.width = width, .width = width,
.height = height, .height = height,
}; };
struct sti_blkmv_outptr outptr = { 0, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
s32 ret; s32 ret;
unsigned long flags; unsigned long flags;
do { do {
spin_lock_irqsave(&sti->lock, flags); spin_lock_irqsave(&sti->lock, flags);
ret = STI_CALL(sti->block_move, &clear_blkmv_flags, *inptr = inptr_default;
&inptr, &outptr, sti->glob_cfg); ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
inptr, outptr, sti->glob_cfg);
spin_unlock_irqrestore(&sti->lock, flags); spin_unlock_irqrestore(&sti->lock, flags);
} while (ret == 1); } while (ret == 1);
} }
...@@ -182,7 +194,8 @@ void ...@@ -182,7 +194,8 @@ void
sti_clear(struct sti_struct *sti, int src_y, int src_x, sti_clear(struct sti_struct *sti, int src_y, int src_x,
int height, int width, int c) int height, int width, int c)
{ {
struct sti_blkmv_inptr inptr = { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
struct sti_blkmv_inptr inptr_default = {
.fg_color = c_fg(sti, c), .fg_color = c_fg(sti, c),
.bg_color = c_bg(sti, c), .bg_color = c_bg(sti, c),
.src_x = src_x * sti->font_width, .src_x = src_x * sti->font_width,
...@@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x, ...@@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
.width = width * sti->font_width, .width = width * sti->font_width,
.height = height* sti->font_height, .height = height* sti->font_height,
}; };
struct sti_blkmv_outptr outptr = { 0, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
s32 ret; s32 ret;
unsigned long flags; unsigned long flags;
do { do {
spin_lock_irqsave(&sti->lock, flags); spin_lock_irqsave(&sti->lock, flags);
ret = STI_CALL(sti->block_move, &clear_blkmv_flags, *inptr = inptr_default;
&inptr, &outptr, sti->glob_cfg); ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
inptr, outptr, sti->glob_cfg);
spin_unlock_irqrestore(&sti->lock, flags); spin_unlock_irqrestore(&sti->lock, flags);
} while (ret == 1); } while (ret == 1);
} }
...@@ -212,7 +226,8 @@ void ...@@ -212,7 +226,8 @@ void
sti_bmove(struct sti_struct *sti, int src_y, int src_x, sti_bmove(struct sti_struct *sti, int src_y, int src_x,
int dst_y, int dst_x, int height, int width) int dst_y, int dst_x, int height, int width)
{ {
struct sti_blkmv_inptr inptr = { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
struct sti_blkmv_inptr inptr_default = {
.src_x = src_x * sti->font_width, .src_x = src_x * sti->font_width,
.src_y = src_y * sti->font_height, .src_y = src_y * sti->font_height,
.dest_x = dst_x * sti->font_width, .dest_x = dst_x * sti->font_width,
...@@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x, ...@@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,
.width = width * sti->font_width, .width = width * sti->font_width,
.height = height* sti->font_height, .height = height* sti->font_height,
}; };
struct sti_blkmv_outptr outptr = { 0, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
s32 ret; s32 ret;
unsigned long flags; unsigned long flags;
do { do {
spin_lock_irqsave(&sti->lock, flags); spin_lock_irqsave(&sti->lock, flags);
ret = STI_CALL(sti->block_move, &default_blkmv_flags, *inptr = inptr_default;
&inptr, &outptr, sti->glob_cfg); ret = sti_call(sti, sti->block_move, &default_blkmv_flags,
inptr, outptr, sti->glob_cfg);
spin_unlock_irqrestore(&sti->lock, flags); spin_unlock_irqrestore(&sti->lock, flags);
} while (ret == 1); } while (ret == 1);
} }
...@@ -284,7 +300,7 @@ __setup("sti=", sti_setup); ...@@ -284,7 +300,7 @@ __setup("sti=", sti_setup);
static char *font_name[MAX_STI_ROMS] = { "VGA8x16", }; static char *font_name[MAX_STI_ROMS];
static int font_index[MAX_STI_ROMS], static int font_index[MAX_STI_ROMS],
font_height[MAX_STI_ROMS], font_height[MAX_STI_ROMS],
font_width[MAX_STI_ROMS]; font_width[MAX_STI_ROMS];
...@@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti) ...@@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti)
"%d used bits\n" "%d used bits\n"
"%d planes\n" "%d planes\n"
"attributes %08x\n", "attributes %08x\n",
sti->outptr.bits_per_pixel, sti->sti_data->inq_outptr.bits_per_pixel,
sti->outptr.bits_used, sti->sti_data->inq_outptr.bits_used,
sti->outptr.planes, sti->sti_data->inq_outptr.planes,
sti->outptr.attributes)); sti->sti_data->inq_outptr.attributes));
} }
static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, static 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,24 +418,21 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
struct sti_glob_cfg_ext *glob_cfg_ext; struct sti_glob_cfg_ext *glob_cfg_ext;
void *save_addr; void *save_addr;
void *sti_mem_addr; void *sti_mem_addr;
const int save_addr_size = 1024; /* XXX */ int i, size;
int i;
if (!sti->sti_mem_request) if (sti->sti_mem_request < 256)
sti->sti_mem_request = 256; /* STI default */ sti->sti_mem_request = 256; /* STI default */
glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); size = sizeof(struct sti_all_data) + sti->sti_mem_request - 256;
glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
save_addr = kzalloc(save_addr_size, GFP_KERNEL);
sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL);
if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { sti->sti_data = kzalloc(size, STI_LOWMEM);
kfree(glob_cfg); if (!sti->sti_data)
kfree(glob_cfg_ext);
kfree(save_addr);
kfree(sti_mem_addr);
return -ENOMEM; return -ENOMEM;
}
glob_cfg = &sti->sti_data->glob_cfg;
glob_cfg_ext = &sti->sti_data->glob_cfg_ext;
save_addr = &sti->sti_data->save_addr;
sti_mem_addr = &sti->sti_data->sti_mem_addr;
glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
glob_cfg->save_addr = STI_PTR(save_addr); 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,32 +488,31 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
return 0; return 0;
} }
#ifdef CONFIG_FB #ifdef CONFIG_FONTS
static struct sti_cooked_font * static struct sti_cooked_font *
sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
{ {
const struct font_desc *fbfont; const struct font_desc *fbfont = NULL;
unsigned int size, bpc; unsigned int size, bpc;
void *dest; void *dest;
struct sti_rom_font *nf; struct sti_rom_font *nf;
struct sti_cooked_font *cooked_font; struct sti_cooked_font *cooked_font;
if (!fbfont_name || !strlen(fbfont_name)) if (fbfont_name && strlen(fbfont_name))
return NULL; fbfont = find_font(fbfont_name);
fbfont = find_font(fbfont_name);
if (!fbfont) if (!fbfont)
fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0); fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
if (!fbfont) if (!fbfont)
return NULL; return NULL;
DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n", pr_info("STI selected %dx%d framebuffer font %s for sticon\n",
fbfont->width, fbfont->height, fbfont->name)); fbfont->width, fbfont->height, fbfont->name);
bpc = ((fbfont->width+7)/8) * fbfont->height; bpc = ((fbfont->width+7)/8) * fbfont->height;
size = bpc * 256; size = bpc * 256;
size += sizeof(struct sti_rom_font); size += sizeof(struct sti_rom_font);
nf = kzalloc(size, GFP_KERNEL); nf = kzalloc(size, STI_LOWMEM);
if (!nf) if (!nf)
return NULL; return NULL;
...@@ -637,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f) ...@@ -637,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f)
unsigned char *n, *p, *q; unsigned char *n, *p, *q;
int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
n = kzalloc (4*size, GFP_KERNEL); n = kzalloc(4*size, STI_LOWMEM);
if (!n) if (!n)
return NULL; return NULL;
p = n + 3; p = n + 3;
...@@ -673,7 +685,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address) ...@@ -673,7 +685,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address)
sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size); sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);
size = (size+3) / 4; size = (size+3) / 4;
raw = kmalloc(size, GFP_KERNEL); raw = kmalloc(size, STI_LOWMEM);
if (raw) { if (raw) {
sti_bmode_rom_copy(address, size, raw); sti_bmode_rom_copy(address, size, raw);
memmove (&raw->res004, &raw->type[0], 0x3c); memmove (&raw->res004, &raw->type[0], 0x3c);
...@@ -707,7 +719,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address) ...@@ -707,7 +719,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address)
/* read the ROM size directly from the struct in ROM */ /* read the ROM size directly from the struct in ROM */
size = gsc_readl(address + offsetof(struct sti_rom,last_addr)); size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
raw = kmalloc(size, GFP_KERNEL); raw = kmalloc(size, STI_LOWMEM);
if (raw) if (raw)
sti_rom_copy(address, size, raw); sti_rom_copy(address, size, raw);
...@@ -743,6 +755,10 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, ...@@ -743,6 +755,10 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
address = (unsigned long) STI_PTR(raw); address = (unsigned long) STI_PTR(raw);
pr_info("STI ROM supports 32 %sbit firmware functions.\n",
raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64
? "and 64 " : "");
sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff); sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff);
sti->block_move = address + (raw->block_move & 0x03ffffff); sti->block_move = address + (raw->block_move & 0x03ffffff);
sti->init_graph = address + (raw->init_graph & 0x03ffffff); sti->init_graph = address + (raw->init_graph & 0x03ffffff);
...@@ -901,7 +917,8 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, ...@@ -901,7 +917,8 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request); sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
sti_dump_outptr(sti); sti_dump_outptr(sti);
printk(KERN_INFO " graphics card name: %s\n", sti->outptr.dev_name ); pr_info(" graphics card name: %s\n",
sti->sti_data->inq_outptr.dev_name);
sti_roms[num_sti_roms] = sti; sti_roms[num_sti_roms] = sti;
num_sti_roms++; num_sti_roms++;
...@@ -1073,6 +1090,29 @@ struct sti_struct * sti_get_rom(unsigned int index) ...@@ -1073,6 +1090,29 @@ struct sti_struct * sti_get_rom(unsigned int index)
} }
EXPORT_SYMBOL(sti_get_rom); EXPORT_SYMBOL(sti_get_rom);
int sti_call(const struct sti_struct *sti, unsigned long func,
const void *flags, void *inptr, void *outptr,
struct sti_glob_cfg *glob_cfg)
{
unsigned long _flags = STI_PTR(flags);
unsigned long _inptr = STI_PTR(inptr);
unsigned long _outptr = STI_PTR(outptr);
unsigned long _glob_cfg = STI_PTR(glob_cfg);
int ret;
#ifdef CONFIG_64BIT
/* Check for overflow when using 32bit STI on 64bit kernel. */
if (WARN_ONCE(_flags>>32 || _inptr>>32 || _outptr>>32 || _glob_cfg>>32,
"Out of 32bit-range pointers!"))
return -1;
#endif
ret = pdc_sti_call(func, _flags, _inptr, _outptr, _glob_cfg);
return ret;
}
MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");
MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#define STI_FONT_HPROMAN8 1 #define STI_FONT_HPROMAN8 1
#define STI_FONT_KANA8 2 #define STI_FONT_KANA8 2
#define ALT_CODE_TYPE_UNKNOWN 0x00 /* alt code type values */
#define ALT_CODE_TYPE_PA_RISC_64 0x01
/* The latency of the STI functions cannot really be reduced by setting /* The latency of the STI functions cannot really be reduced by setting
* this to 0; STI doesn't seem to be designed to allow calling a different * this to 0; STI doesn't seem to be designed to allow calling a different
* function (or the same function with different arguments) after a * function (or the same function with different arguments) after a
...@@ -40,14 +43,6 @@ ...@@ -40,14 +43,6 @@
#define STI_PTR(p) ( virt_to_phys(p) ) #define STI_PTR(p) ( virt_to_phys(p) )
#define PTR_STI(p) ( phys_to_virt((unsigned long)p) ) #define PTR_STI(p) ( phys_to_virt((unsigned long)p) )
#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
({ \
pdc_sti_call( func, STI_PTR(flags), \
STI_PTR(inptr), \
STI_PTR(outptr), \
STI_PTR(glob_cfg)); \
})
#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
...@@ -56,6 +51,12 @@ ...@@ -56,6 +51,12 @@
#define sti_font_x(sti) (PTR_STI(sti->font)->width) #define sti_font_x(sti) (PTR_STI(sti->font)->width)
#define sti_font_y(sti) (PTR_STI(sti->font)->height) #define sti_font_y(sti) (PTR_STI(sti->font)->height)
#ifdef CONFIG_64BIT
#define STI_LOWMEM (GFP_KERNEL | GFP_DMA)
#else
#define STI_LOWMEM (GFP_KERNEL)
#endif
/* STI function configuration structs */ /* STI function configuration structs */
...@@ -306,6 +307,34 @@ struct sti_blkmv_outptr { ...@@ -306,6 +307,34 @@ struct sti_blkmv_outptr {
}; };
/* sti_all_data is an internal struct which needs to be allocated in
* low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */
struct sti_all_data {
struct sti_glob_cfg glob_cfg;
struct sti_glob_cfg_ext glob_cfg_ext;
struct sti_conf_inptr inq_inptr;
struct sti_conf_outptr inq_outptr; /* configuration */
struct sti_conf_outptr_ext inq_outptr_ext;
struct sti_init_inptr_ext init_inptr_ext;
struct sti_init_inptr init_inptr;
struct sti_init_outptr init_outptr;
struct sti_blkmv_inptr blkmv_inptr;
struct sti_blkmv_outptr blkmv_outptr;
struct sti_font_inptr font_inptr;
struct sti_font_outptr font_outptr;
/* leave as last entries */
unsigned long save_addr[1024 / sizeof(unsigned long)];
/* min 256 bytes which is STI default, max sti->sti_mem_request */
unsigned long sti_mem_addr[256 / sizeof(unsigned long)];
/* do not add something below here ! */
};
/* internal generic STI struct */ /* internal generic STI struct */
struct sti_struct { struct sti_struct {
...@@ -330,11 +359,9 @@ struct sti_struct { ...@@ -330,11 +359,9 @@ struct sti_struct {
region_t regions[STI_REGION_MAX]; region_t regions[STI_REGION_MAX];
unsigned long regions_phys[STI_REGION_MAX]; unsigned long regions_phys[STI_REGION_MAX];
struct sti_glob_cfg *glob_cfg; struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */
struct sti_cooked_font *font; /* ptr to selected font (cooked) */
struct sti_conf_outptr outptr; /* configuration */ struct sti_cooked_font *font; /* ptr to selected font (cooked) */
struct sti_conf_outptr_ext outptr_ext;
struct pci_dev *pd; struct pci_dev *pd;
...@@ -343,6 +370,9 @@ struct sti_struct { ...@@ -343,6 +370,9 @@ struct sti_struct {
/* pointer to the fb_info where this STI device is used */ /* pointer to the fb_info where this STI device is used */
struct fb_info *info; struct fb_info *info;
/* pointer to all internal data */
struct sti_all_data *sti_data;
}; };
...@@ -350,6 +380,14 @@ struct sti_struct { ...@@ -350,6 +380,14 @@ struct sti_struct {
struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
/* sticore main function to call STI firmware */
int sti_call(const struct sti_struct *sti, unsigned long func,
const void *flags, void *inptr, void *outptr,
struct sti_glob_cfg *glob_cfg);
/* functions to call the STI ROM directly */ /* functions to call the STI ROM directly */
void sti_putc(struct sti_struct *sti, int c, int y, int x); void sti_putc(struct sti_struct *sti, int c, int y, int x);
......
...@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
var = &info->var; var = &info->var;
fb->sti = sti; fb->sti = sti;
dev_name = sti->sti_data->inq_outptr.dev_name;
/* store upper 32bits of the graphics id */ /* store upper 32bits of the graphics id */
fb->id = fb->sti->graphics_id[0]; fb->id = fb->sti->graphics_id[0];
...@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
Since this driver only supports standard mode, we check Since this driver only supports standard mode, we check
if the device name contains the string "DX" and tell the if the device name contains the string "DX" and tell the
user how to reconfigure the card. */ user how to reconfigure the card. */
if (strstr(sti->outptr.dev_name, "DX")) { if (strstr(dev_name, "DX")) {
printk(KERN_WARNING printk(KERN_WARNING
"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n" "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
sti->outptr.dev_name); dev_name);
goto out_err0; goto out_err0;
} }
/* fall though */ /* fall though */
...@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
break; break;
default: default:
printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n", printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
sti->outptr.dev_name, fb->id); dev_name, fb->id);
goto out_err0; goto out_err0;
} }
...@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb->id = S9000_ID_A1659A; fb->id = S9000_ID_A1659A;
break; break;
case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */ case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
dev_name = fb->sti->outptr.dev_name;
if (strstr(dev_name, "GRAYSCALE") || if (strstr(dev_name, "GRAYSCALE") ||
strstr(dev_name, "Grayscale") || strstr(dev_name, "Grayscale") ||
strstr(dev_name, "grayscale")) strstr(dev_name, "grayscale"))
...@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
var->xres, var->xres,
var->yres, var->yres,
var->bits_per_pixel, var->bits_per_pixel,
sti->outptr.dev_name, dev_name,
fb->id, fb->id,
fix->mmio_start); fix->mmio_start);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment