Commit e4b7f0f6 authored by James Simmons's avatar James Simmons

Updates from Helge Deller for the console/fbdev drivers for the PARISC...

Updates from Helge Deller for the console/fbdev drivers for the PARISC platform. Small fix for clearing the screen and a string typo for the Voodoo 1/2 driver.
parent 487cb474
......@@ -295,7 +295,7 @@ config FB_VGA16
vga16fb.o.
config FB_STI
bool "HP STI frame buffer device support"
tristate "HP STI frame buffer device support"
depends on FB && PARISC
default y
---help---
......
......@@ -66,25 +66,25 @@ config SGI_NEWPORT_CONSOLE
# bool 'IODC console' CONFIG_IODC_CONSOLE
config STI_CONSOLE
bool "STI text console"
tristate "STI text console"
depends on PARISC
default y
help
help
The STI console is the builtin display/keyboard on HP-PARISC
machines. Say Y here to build support for it into your kernel.
The alternative is to use your primary serial port as a console.
config DUMMY_CONSOLE_COLUMNS
int "Initial number of STI console screen columns" if STI_CONSOLE
depends on STI_CONSOLE || FB_STI
int "Initial number of console screen columns" if STI_CONSOLE
depends on PARISC
default "160"
help
The default value is 160, which should fit a 1280x1024 monitor.
Select 80 if you use a 640x480 resolution by default.
config DUMMY_CONSOLE_ROWS
int "Initial number of STI console screen rows" if STI_CONSOLE
depends on STI_CONSOLE || FB_STI
int "Initial number of console screen rows" if STI_CONSOLE
depends on PARISC
default "64"
help
The default value is 64, which should fit a 1280x1024 monitor.
......@@ -99,7 +99,7 @@ config PROM_CONSOLE
config DUMMY_CONSOLE
bool
depends on !PROM_CONSOLE=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y || !IODC_CONSOLE && GSC_PS2
depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
default y
config FRAMEBUFFER_CONSOLE
......
......@@ -43,6 +43,7 @@
#include <linux/vt_kern.h>
#include <linux/kd.h>
#include <linux/selection.h>
#include <linux/module.h>
#include <asm/io.h>
......@@ -52,17 +53,16 @@
#define BLANK 0
static int vga_is_gfx;
/* this is the sti_struct used for this console */
static struct sti_struct *sticon_sti;
/* Software scrollback */
static unsigned long softback_buf, softback_curr;
static unsigned long softback_in;
static unsigned long /* softback_top, */ softback_end;
static int softback_lines;
/* software cursor */
static int cursor_drawn;
#define CURSOR_DRAW_DELAY (1)
#define DEFAULT_CURSOR_BLINK_RATE (20)
......@@ -75,7 +75,6 @@ static inline void cursor_undrawn(void)
cursor_drawn = 0;
}
static const char *__init sticon_startup(void)
{
return "STI console";
......@@ -108,7 +107,7 @@ static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
}
#endif
sti_putc(default_sti, c, ypos, xpos);
sti_putc(sticon_sti, c, ypos, xpos);
if (redraw_cursor)
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
......@@ -135,7 +134,7 @@ static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
#endif
while (count--) {
sti_putc(default_sti, scr_readw(s++), ypos, xpos++);
sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++);
}
if (redraw_cursor)
......@@ -149,7 +148,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols];
switch (mode) {
case CM_ERASE:
sti_putc(default_sti, car1, conp->vc_y, conp->vc_x);
sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x);
break;
case CM_MOVE:
case CM_DRAW:
......@@ -159,7 +158,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
case CUR_LOWER_HALF:
case CUR_TWO_THIRDS:
case CUR_BLOCK:
sti_putc(default_sti, (car1 & 255) + (0 << 8) + (7 << 11),
sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
conp->vc_y, conp->vc_x);
break;
}
......@@ -167,10 +166,9 @@ static void sticon_cursor(struct vc_data *conp, int mode)
}
}
static int
sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
{
struct sti_struct *sti = default_sti;
struct sti_struct *sti = sticon_sti;
if (vga_is_gfx)
return 0;
......@@ -192,9 +190,8 @@ sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
return 0;
}
static void
sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
int height, int width)
static void sticon_bmove(struct vc_data *conp, int sy, int sx,
int dy, int dx, int height, int width)
{
if (!width || !height)
return;
......@@ -206,12 +203,12 @@ sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/);
#endif
sti_bmove(default_sti, sy, sx, dy, dx, height, width);
sti_bmove(sticon_sti, sy, sx, dy, dx, height, width);
}
static void sticon_init(struct vc_data *c, int init)
{
struct sti_struct *sti = default_sti;
struct sti_struct *sti = sticon_sti;
int vc_cols, vc_rows;
sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
......@@ -240,7 +237,7 @@ static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
if (!height || !width)
return;
sti_clear(default_sti, sy, sx, height, width, conp->vc_video_erase_char);
sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char);
}
static int sticon_switch(struct vc_data *conp)
......@@ -265,10 +262,10 @@ static int sticon_blank(struct vc_data *c, int blank)
if (vga_is_gfx)
return 0;
sticon_set_origin(c);
sti_clear(default_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
return 1;
case -1: /* Entering graphic mode */
sti_clear(default_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
vga_is_gfx = 1;
return 1;
}
......@@ -344,7 +341,7 @@ static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
return attr;
}
void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
{
int col = 1; /* vga_can_do_color; */
......@@ -360,11 +357,11 @@ void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
}
}
void sticon_save_screen(struct vc_data *conp)
static void sticon_save_screen(struct vc_data *conp)
{
}
struct consw sti_con = {
static struct consw sti_con = {
.con_startup = sticon_startup,
.con_init = sticon_init,
.con_deinit = sticon_deinit,
......@@ -391,14 +388,20 @@ struct consw sti_con = {
int __init sticonsole_init(void)
{
if (sti_init_roms()) {
if (conswitchp == &dummy_con) {
printk(KERN_INFO "sticon: Initializing STI text console.\n");
take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1);
}
return 0;
} else
/* already initialized ? */
if (sticon_sti)
return 0;
sticon_sti = sti_get_rom(0);
if (!sticon_sti)
return -ENODEV;
if (conswitchp == &dummy_con) {
printk(KERN_INFO "sticon: Initializing STI text console.\n");
take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1);
}
return 0;
}
module_init(sticonsole_init);
MODULE_LICENSE("GPL");
......@@ -3,14 +3,13 @@
* core code for console driver using HP's STI firmware
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Portions Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
* Portions Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
* Copyright (C) 2001-2003 Helge Deller <deller@gmx.de>
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*
* TODO:
* - call STI in virtual mode rather than in real mode
* - screen blanking with state_mgmt() in text mode STI ?
* - try to make it work on m68k hp workstations ;)
* - clean up the cache flushing functions
*
*/
......@@ -25,10 +24,12 @@
#include <asm/pgalloc.h>
#include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/cacheflush.h>
#include "../sticore.h"
#define STI_DRIVERVERSION "0.9"
#define STI_DRIVERVERSION "Version 0.9a"
struct sti_struct *default_sti;
......@@ -73,8 +74,8 @@ sti_init_graph(struct sti_struct *sti)
{
struct sti_init_inptr_ext inptr_ext = { 0, };
struct sti_init_inptr inptr = {
3, /* # of text planes (3 is maximum for STI) */
STI_PTR(&inptr_ext)
.text_planes = 3, /* # of text planes (max 3 for STI) */
.ext_ptr = STI_PTR(&inptr_ext)
};
struct sti_init_outptr outptr = { 0, };
unsigned long flags;
......@@ -103,7 +104,7 @@ static const struct sti_conf_flags default_conf_flags = {
void
sti_inq_conf(struct sti_struct *sti)
{
struct sti_conf_inptr inptr = { 0 };
struct sti_conf_inptr inptr = { 0, };
unsigned long flags;
s32 ret;
......@@ -126,9 +127,12 @@ void
sti_putc(struct sti_struct *sti, int c, int y, int x)
{
struct sti_font_inptr inptr = {
STI_PTR(sti->font->raw),
c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
x * sti->font_width, y * sti->font_height, 0
.font_start_addr= STI_PTR(sti->font->raw),
.index = c_index(sti, c),
.fg_color = c_fg(sti, c),
.bg_color = c_bg(sti, c),
.dest_x = x * sti->font_width,
.dest_y = y * sti->font_height,
};
struct sti_font_outptr outptr = { 0, };
s32 ret;
......@@ -153,11 +157,14 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
int height, int width, u8 color)
{
struct sti_blkmv_inptr inptr = {
color, color,
src_x, src_y ,
src_x, src_y ,
width, height,
0
.fg_color = color,
.bg_color = color,
.src_x = src_x,
.src_y = src_y,
.dest_x = src_x,
.dest_y = src_y,
.width = width,
.height = height,
};
struct sti_blkmv_outptr outptr = { 0, };
s32 ret;
......@@ -176,11 +183,14 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
int height, int width, int c)
{
struct sti_blkmv_inptr inptr = {
c_fg(sti, c), c_bg(sti, c),
src_x * sti->font_width, src_y * sti->font_height,
src_x * sti->font_width, src_y * sti->font_height,
width * sti->font_width, height* sti->font_height,
0
.fg_color = c_fg(sti, c),
.bg_color = c_bg(sti, c),
.src_x = src_x * sti->font_width,
.src_y = src_y * sti->font_height,
.dest_x = src_x * sti->font_width,
.dest_y = src_y * sti->font_height,
.width = width * sti->font_width,
.height = height* sti->font_height,
};
struct sti_blkmv_outptr outptr = { 0, };
s32 ret;
......@@ -195,7 +205,7 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
}
static const struct sti_blkmv_flags default_blkmv_flags = {
.wait = STI_WAIT,
.wait = STI_WAIT,
};
void
......@@ -203,11 +213,12 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,
int dst_y, int dst_x, int height, int width)
{
struct sti_blkmv_inptr inptr = {
0, 0,
src_x * sti->font_width, src_y * sti->font_height,
dst_x * sti->font_width, dst_y * sti->font_height,
width * sti->font_width, height* sti->font_height,
0
.src_x = src_x * sti->font_width,
.src_y = src_y * sti->font_height,
.dest_x = dst_x * sti->font_width,
.dest_y = dst_y * sti->font_height,
.width = width * sti->font_width,
.height = height* sti->font_height,
};
struct sti_blkmv_outptr outptr = { 0, };
s32 ret;
......@@ -222,6 +233,14 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,
}
/* FIXME: Do we have another solution for this ? */
static void sti_flush(unsigned long from, unsigned long len)
{
flush_data_cache();
flush_kernel_dcache_range(from, len);
flush_icache_range(from, from+len);
}
void __init
sti_rom_copy(unsigned long base, unsigned long count, void *dest)
{
......@@ -242,7 +261,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest)
dest++;
}
sti_flush(dest_start, dest_len); /* XXX */
sti_flush(dest_start, dest_len);
}
......@@ -250,8 +269,8 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest)
static char default_sti_path[21];
static int __init
sti_setup(char *str)
#ifndef MODULE
static int __init sti_setup(char *str)
{
if (str)
strncpy (default_sti_path, str, sizeof (default_sti_path));
......@@ -266,6 +285,7 @@ sti_setup(char *str)
* STI screen.
*/
__setup("sti=", sti_setup);
#endif
......@@ -273,7 +293,7 @@ static char __initdata *font_name[MAX_STI_ROMS] = { "VGA8x16", };
static int __initdata font_index[MAX_STI_ROMS],
font_height[MAX_STI_ROMS],
font_width[MAX_STI_ROMS];
#ifndef MODULE
static int __init sti_font_setup(char *str)
{
char *x;
......@@ -323,10 +343,11 @@ static int __init sti_font_setup(char *str)
* found, sticon will use the default 8x8 font.
*/
__setup("sti_font=", sti_font_setup);
#endif
void __init
static void __init
sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
{
struct sti_glob_cfg_ext *cfg;
......@@ -366,7 +387,7 @@ sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
cfg->sti_mem_addr, sti_mem_request));
}
void __init
static void __init
sti_dump_outptr(struct sti_struct *sti)
{
DPRINTK((KERN_INFO
......@@ -380,7 +401,7 @@ sti_dump_outptr(struct sti_struct *sti)
sti->outptr.attributes));
}
int __init
static int __init
sti_init_glob_cfg(struct sti_struct *sti,
unsigned long rom_address, unsigned long hpa)
{
......@@ -399,8 +420,13 @@ sti_init_glob_cfg(struct sti_struct *sti,
save_addr = kmalloc(save_addr_size, GFP_KERNEL);
sti_mem_addr = kmalloc(sti->sti_mem_request, GFP_KERNEL);
if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr))
if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) {
kfree(glob_cfg);
kfree(glob_cfg_ext);
kfree(save_addr);
kfree(sti_mem_addr);
return -ENOMEM;
}
memset(glob_cfg, 0, sizeof(*glob_cfg));
memset(glob_cfg_ext, 0, sizeof(*glob_cfg_ext));
......@@ -659,10 +685,10 @@ sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest)
base += 4;
dest++;
}
sti_flush(dest_start, dest_len); /* XXX */
sti_flush(dest_start, dest_len);
}
struct sti_rom * __init
static struct sti_rom * __init
sti_get_bmode_rom (unsigned long address)
{
struct sti_rom *raw;
......@@ -889,7 +915,7 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd
return NULL;
}
static void __init sticore_check_for_default_sti (struct sti_struct *sti, char *path)
static void __init sticore_check_for_default_sti(struct sti_struct *sti, char *path)
{
if (strcmp (path, default_sti_path) == 0)
default_sti = sti;
......@@ -1002,58 +1028,53 @@ static struct parisc_device_id sti_pa_tbl[] = {
{ 0, }
};
struct parisc_driver pa_sti_driver = {
static struct parisc_driver pa_sti_driver = {
.name = "sti (native)",
.id_table = sti_pa_tbl,
.probe = sticore_pa_init,
};
struct sti_struct * __init sti_init_roms(void)
/*
* sti_init_roms() - detects all STI ROMs and stores them in sti_roms[]
*/
static int sticore_initialized;
static void __init sti_init_roms(void)
{
static int initialized;
if (sticore_initialized)
return;
if (initialized)
goto out;
sticore_initialized = 1;
printk(KERN_INFO "STI GSC/PCI graphics driver version %s\n",
STI_DRIVERVERSION);
printk(KERN_INFO "STI GSC/PCI core graphics driver "
STI_DRIVERVERSION "\n");
/* Register drivers for native & PCI cards */
register_parisc_driver(&pa_sti_driver);
pci_module_init (&pci_sti_driver);
pci_module_init(&pci_sti_driver);
/* if we didn't find the given default sti, take the first one */
if (!default_sti)
default_sti = sti_roms[0];
out:
/* return default STI if available */
if (num_sti_roms && default_sti && default_sti->init_graph) {
initialized = 1;
return default_sti;
}
return NULL;
}
/*
* index = 0 gives default sti
* index > 0 gives other stis in detection order
*/
struct sti_struct * __init sti_get_rom(int index)
struct sti_struct * sti_get_rom(unsigned int index)
{
int i;
if (!sticore_initialized)
sti_init_roms();
if (index == 0)
return default_sti;
i = -1;
while (index > 0) {
i++;
if (i > num_sti_roms)
return NULL;
if (sti_roms[i] == default_sti)
continue;
index--;
}
return sti_roms[i];
if (index > num_sti_roms)
return NULL;
return sti_roms[index-1];
}
......@@ -377,7 +377,7 @@ static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t)
static void sstfb_clear_screen(struct fb_info *info)
{
/* clear screen */
memset_io(info->screen_base, 0, info->fix.smem_len);
fb_memset(info->screen_base, 0, info->fix.smem_len);
}
......@@ -1708,7 +1708,7 @@ MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based vide
MODULE_LICENSE("GPL");
MODULE_PARM(mem, "i");
MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 MB, default=autodetect)");
MODULE_PARM_DESC(mem, "Size of frame buffer memory in MB (1, 2, 4 MB, default=autodetect)");
MODULE_PARM(vgapass, "i");
MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough mode (0 or 1) (default=0)");
MODULE_PARM(clipping , "i");
......
......@@ -72,27 +72,6 @@ static inline int STI_CALL( unsigned long func,
#define sti_font_x(sti) (PTR_STI(sti->font)->width)
#define sti_font_y(sti) (PTR_STI(sti->font)->height)
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
extern struct sti_struct *sti_init_roms(void);
/* XXX: this probably should not be here, but we rely on STI being
initialized early and independently of stifb at the moment, so
there's no other way for stifb to find it. */
extern struct sti_struct *default_sti;
int sti_init_graph(struct sti_struct *sti);
void sti_inq_conf(struct sti_struct *sti);
void sti_putc(struct sti_struct *sti, int c, int y, int x);
void sti_set(struct sti_struct *sti, int src_y, int src_x,
int height, int width, u8 color);
void sti_clear(struct sti_struct *sti, int src_y, int src_x,
int height, int width, int c);
void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
int dst_y, int dst_x, int height, int width);
/* STI function configuration structs */
......@@ -170,7 +149,7 @@ struct sti_init_inptr_ext {
struct sti_init_inptr {
s32 text_planes; /* number of planes to use for text */
u32 ext_ptr; /* pointer to extended init_graph inptr data structure*/
u32 ext_ptr; /* pointer to extended init_graph inptr data structure*/
};
......@@ -382,27 +361,20 @@ struct sti_struct {
};
/* sticore interface functions */
/* helper functions */
struct sti_struct *sti_init_roms(void);
struct sti_struct *sti_get_rom(int);
void sti_rom_copy(unsigned long base, unsigned long count, void *dest);
struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
int (*search_font_fnc) (struct sti_cooked_rom *,int,int) );
int sti_read_rom(int wordmode, struct sti_struct *sti,
unsigned long address);
struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
/* functions to call the STI ROM directly */
/* FIXME: Do we have another solution for this ? */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
static inline void sti_flush(unsigned long from, unsigned long len)
{
flush_data_cache();
flush_kernel_dcache_range(from, len);
flush_icache_range(from, from+len);
}
int sti_init_graph(struct sti_struct *sti);
void sti_inq_conf(struct sti_struct *sti);
void sti_putc(struct sti_struct *sti, int c, int y, int x);
void sti_set(struct sti_struct *sti, int src_y, int src_x,
int height, int width, u8 color);
void sti_clear(struct sti_struct *sti, int src_y, int src_x,
int height, int width, int c);
void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
int dst_y, int dst_x, int height, int width);
#endif /* STICORE_H */
......@@ -111,7 +111,7 @@ struct stifb_info {
int deviceSpecificConfig;
};
static int stifb_force_bpp[MAX_STI_ROMS] = {0, };
static int __initdata stifb_force_bpp[MAX_STI_ROMS];
/* ------------------- chipset specific functions -------------------------- */
......@@ -487,8 +487,7 @@ rattlerSetupPlanes(struct stifb_info *fb)
SETUP_HW(fb);
WRITE_BYTE(1, fb, REG_16b1);
/* XXX: replace by fb_setmem(), smem_start or screen_base ? */
memset_io(fb->info.fix.smem_start, 0xff,
fb_memset(fb->info.fix.smem_start, 0xff,
fb->info.var.yres*fb->info.fix.line_length);
CRX24_SET_OVLY_MASK(fb);
......@@ -882,6 +881,82 @@ SETUP_HCRX(struct stifb_info *fb)
/* ------------------- driver specific functions --------------------------- */
#define TMPBUFLEN 2048
static ssize_t
stifb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_dentry->d_inode;
int fbidx = minor(inode->i_rdev);
struct fb_info *info = registered_fb[fbidx];
char tmpbuf[TMPBUFLEN];
if (!info || ! info->screen_base)
return -ENODEV;
if (p >= info->fix.smem_len)
return 0;
if (count >= info->fix.smem_len)
count = info->fix.smem_len;
if (count + p > info->fix.smem_len)
count = info->fix.smem_len - p;
if (count > sizeof(tmpbuf))
count = sizeof(tmpbuf);
if (count) {
char *base_addr;
base_addr = info->screen_base;
memcpy_fromio(&tmpbuf, base_addr+p, count);
count -= copy_to_user(buf, &tmpbuf, count);
if (!count)
return -EFAULT;
*ppos += count;
}
return count;
}
static ssize_t
stifb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
int fbidx = minor(inode->i_rdev);
struct fb_info *info = registered_fb[fbidx];
unsigned long p = *ppos;
size_t c;
int err;
char tmpbuf[TMPBUFLEN];
if (!info || !info->screen_base)
return -ENODEV;
if (p > info->fix.smem_len)
return -ENOSPC;
if (count >= info->fix.smem_len)
count = info->fix.smem_len;
err = 0;
if (count + p > info->fix.smem_len) {
count = info->fix.smem_len - p;
err = -ENOSPC;
}
p += (unsigned long)info->screen_base;
c = count;
while (c) {
int len = c > sizeof(tmpbuf) ? sizeof(tmpbuf) : c;
err = -EFAULT;
if (copy_from_user(&tmpbuf, buf, len))
break;
memcpy_toio(p, &tmpbuf, len);
c -= len;
p += len;
buf += len;
*ppos += len;
}
if (count-c)
return (count-c);
return err;
}
static int
stifb_setcolreg(u_int regno, u_int red, u_int green,
......@@ -1018,11 +1093,12 @@ stifb_init_display(struct stifb_info *fb)
SETUP_FB(fb);
}
/* ------------ Interfaces to hardware functions ------------ */
static struct fb_ops stifb_ops = {
.owner = THIS_MODULE,
.fb_read = stifb_read,
.fb_write = stifb_write,
.fb_setcolreg = stifb_setcolreg,
.fb_blank = stifb_blank,
.fb_fillrect = cfb_fillrect,
......@@ -1166,6 +1242,11 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
if (!fix->line_length)
fix->line_length = 2048; /* default */
/* limit fbsize to max visible screen size */
if (fix->smem_len > yres*fix->line_length)
fix->smem_len = yres*fix->line_length;
fix->accel = FB_ACCEL_NONE;
switch (bpp) {
......@@ -1206,7 +1287,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
fb_alloc_cmap(&info->cmap, 256, 0);
stifb_init_display(fb);
if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb")) {
if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {
printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
fix->smem_start, fix->smem_start+fix->smem_len);
goto out_err1;
......@@ -1252,15 +1333,11 @@ stifb_init(void)
struct sti_struct *sti;
int i;
if (sti_init_roms() == NULL)
return -ENXIO; /* no STI cards available */
for (i = 0; i < MAX_STI_ROMS; i++) {
for (i = 1; i < MAX_STI_ROMS; i++) {
sti = sti_get_rom(i);
if (sti)
stifb_init_fb(sti, stifb_force_bpp[i]);
else
if (!sti)
break;
stifb_init_fb(sti, stifb_force_bpp[i]);
}
return 0;
}
......@@ -1275,7 +1352,7 @@ stifb_cleanup(void)
struct sti_struct *sti;
int i;
for (i = 0; i < MAX_STI_ROMS; i++) {
for (i = 1; i < MAX_STI_ROMS; i++) {
sti = sti_get_rom(i);
if (!sti)
break;
......
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