2019-05-19 15:08:20 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-17 02:20:36 +04:00
/*
* linux / drivers / video / console / sticore . c -
* core code for console driver using HP ' s STI firmware
*
* Copyright ( C ) 2000 Philipp Rumpf < prumpf @ tux . org >
2023-05-10 23:17:27 +03:00
* Copyright ( C ) 2001 - 2023 Helge Deller < deller @ gmx . de >
2005-04-17 02:20:36 +04:00
* Copyright ( C ) 2001 - 2002 Thomas Bogendoerfer < tsbogend @ alpha . franken . de >
2023-04-17 15:56:42 +03:00
*
2005-04-17 02:20:36 +04:00
* TODO :
* - call STI in virtual mode rather than in real mode
2023-04-17 15:56:42 +03:00
* - screen blanking with state_mgmt ( ) in text mode STI ?
2005-04-17 02:20:36 +04:00
* - try to make it work on m68k hp workstations ; )
2023-04-17 15:56:42 +03:00
*
2005-04-17 02:20:36 +04:00
*/
2020-10-12 11:44:52 +03:00
# define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME
2005-04-17 02:20:36 +04:00
# include <linux/module.h>
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/font.h>
# include <asm/hardware.h>
parisc: move definition of PAGE0 to asm/page.h
This was defined in asm/pdc.h which needs to include asm/page.h for
__PAGE_OFFSET. This leads to an include loop so that page.h eventually will
include pdc.h again. While this is no problem because of header guards, it is
a problem because some symbols may be undefined. Such an error is this:
In file included from include/linux/bitops.h:35:0,
from include/asm-generic/getorder.h:7,
from arch/parisc/include/asm/page.h:162,
from arch/parisc/include/asm/pdc.h:346,
from arch/parisc/include/asm/processor.h:16,
from arch/parisc/include/asm/spinlock.h:6,
from arch/parisc/include/asm/atomic.h:20,
from include/linux/atomic.h:4,
from include/linux/sysfs.h:20,
from include/linux/kobject.h:21,
from include/linux/device.h:17,
from include/linux/eisa.h:5,
from arch/parisc/kernel/pci.c:11:
arch/parisc/include/asm/bitops.h: In function ‘set_bit’:
arch/parisc/include/asm/bitops.h:82:2: error: implicit declaration of function ‘_atomic_spin_lock_irqsave’ [-Werror=implicit-function-declaration]
arch/parisc/include/asm/bitops.h:84:2: error: implicit declaration of function ‘_atomic_spin_unlock_irqrestore’ [-Werror=implicit-function-declaration]
Signed-off-by: Rolf Eike Beer <eike-kernel@sf-tec.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-05-11 01:08:17 +04:00
# include <asm/page.h>
2005-04-17 02:20:36 +04:00
# include <asm/parisc-device.h>
parisc: move definition of PAGE0 to asm/page.h
This was defined in asm/pdc.h which needs to include asm/page.h for
__PAGE_OFFSET. This leads to an include loop so that page.h eventually will
include pdc.h again. While this is no problem because of header guards, it is
a problem because some symbols may be undefined. Such an error is this:
In file included from include/linux/bitops.h:35:0,
from include/asm-generic/getorder.h:7,
from arch/parisc/include/asm/page.h:162,
from arch/parisc/include/asm/pdc.h:346,
from arch/parisc/include/asm/processor.h:16,
from arch/parisc/include/asm/spinlock.h:6,
from arch/parisc/include/asm/atomic.h:20,
from include/linux/atomic.h:4,
from include/linux/sysfs.h:20,
from include/linux/kobject.h:21,
from include/linux/device.h:17,
from include/linux/eisa.h:5,
from arch/parisc/kernel/pci.c:11:
arch/parisc/include/asm/bitops.h: In function ‘set_bit’:
arch/parisc/include/asm/bitops.h:82:2: error: implicit declaration of function ‘_atomic_spin_lock_irqsave’ [-Werror=implicit-function-declaration]
arch/parisc/include/asm/bitops.h:84:2: error: implicit declaration of function ‘_atomic_spin_unlock_irqrestore’ [-Werror=implicit-function-declaration]
Signed-off-by: Rolf Eike Beer <eike-kernel@sf-tec.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-05-11 01:08:17 +04:00
# include <asm/pdc.h>
2005-04-17 02:20:36 +04:00
# include <asm/cacheflush.h>
2008-07-30 09:33:01 +04:00
# include <asm/grfioctl.h>
2005-04-17 02:20:36 +04:00
2023-04-17 15:56:43 +03:00
# include <video/sticore.h>
2005-04-17 02:20:36 +04:00
2022-06-02 14:55:26 +03:00
# define STI_DRIVERVERSION "Version 0.9c"
2005-04-17 02:20:36 +04:00
2008-07-26 06:46:26 +04:00
static struct sti_struct * default_sti __read_mostly ;
2005-04-17 02:20:36 +04:00
2006-01-17 22:40:40 +03:00
/* number of STI ROMS found and their ptrs to each struct */
static int num_sti_roms __read_mostly ;
static struct sti_struct * sti_roms [ MAX_STI_ROMS ] __read_mostly ;
2005-04-17 02:20:36 +04:00
2023-05-10 23:17:27 +03:00
static void * store_sti_val ( struct sti_struct * sti , void * ptr , unsigned long val )
{
u32 * ptr32 = ptr ;
if ( IS_ENABLED ( CONFIG_64BIT ) & & sti - > do_call64 ) {
/* used for 64-bit STI ROM */
unsigned long * ptr64 = ptr ;
ptr64 = PTR_ALIGN ( ptr64 , sizeof ( void * ) ) ;
* ptr64 + + = val ;
return ptr64 ;
}
/* used for 32-bit STI ROM */
* ptr32 + + = val ;
return ptr32 ;
}
# define store_sti_ptr(sti, dest, ptr) \
store_sti_val ( sti , dest , STI_PTR ( ptr ) )
2005-04-17 02:20:36 +04:00
/* The colour indices used by STI are
* 0 - Black
* 1 - White
* 2 - Red
* 3 - Yellow / Brown
* 4 - Green
* 5 - Cyan
* 6 - Blue
* 7 - Magenta
*
* So we have the same colours as VGA ( basically one bit each for R , G , B ) ,
* but have to translate them , anyway . */
static const u8 col_trans [ 8 ] = {
0 , 6 , 4 , 5 ,
2 , 7 , 3 , 1
} ;
# define c_fg(sti, c) col_trans[((c>> 8) & 7)]
# define c_bg(sti, c) col_trans[((c>>11) & 7)]
# define c_index(sti, c) ((c) & 0xff)
static const struct sti_init_flags default_init_flags = {
2023-04-17 15:56:42 +03:00
. wait = STI_WAIT ,
2005-04-17 02:20:36 +04:00
. reset = 1 ,
2023-04-17 15:56:42 +03:00
. text = 1 ,
2005-04-17 02:20:36 +04:00
. nontext = 1 ,
2023-04-17 15:56:42 +03:00
. no_chg_bet = 1 ,
. no_chg_bei = 1 ,
2005-04-17 02:20:36 +04:00
. init_cmap_tx = 1 ,
} ;
2008-07-26 06:46:26 +04:00
static int sti_init_graph ( struct sti_struct * sti )
2005-04-17 02:20:36 +04:00
{
2013-11-07 02:38:59 +04:00
struct sti_init_inptr * inptr = & sti - > sti_data - > init_inptr ;
struct sti_init_inptr_ext * inptr_ext = & sti - > sti_data - > init_inptr_ext ;
struct sti_init_outptr * outptr = & sti - > sti_data - > init_outptr ;
2005-04-17 02:20:36 +04:00
unsigned long flags ;
2013-11-07 02:38:59 +04:00
int ret , err ;
2005-04-17 02:20:36 +04:00
spin_lock_irqsave ( & sti - > lock , flags ) ;
2013-11-07 02:38:59 +04:00
memset ( inptr , 0 , sizeof ( * inptr ) ) ;
inptr - > text_planes = 3 ; /* # of text planes (max 3 for STI) */
memset ( inptr_ext , 0 , sizeof ( * inptr_ext ) ) ;
2023-05-10 23:17:27 +03:00
store_sti_ptr ( sti , & inptr - > ext_ptr , inptr_ext ) ;
2013-11-07 02:38:59 +04:00
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 ;
2005-04-17 02:20:36 +04:00
spin_unlock_irqrestore ( & sti - > lock , flags ) ;
if ( ret < 0 ) {
2013-11-07 02:38:59 +04:00
pr_err ( " STI init_graph failed (ret %d, errno %d) \n " , ret , err ) ;
2005-04-17 02:20:36 +04:00
return - 1 ;
}
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
static const struct sti_conf_flags default_conf_flags = {
. wait = STI_WAIT ,
} ;
2008-07-26 06:46:26 +04:00
static void sti_inq_conf ( struct sti_struct * sti )
2005-04-17 02:20:36 +04:00
{
2013-11-07 02:38:59 +04:00
struct sti_conf_inptr * inptr = & sti - > sti_data - > inq_inptr ;
struct sti_conf_outptr * outptr = & sti - > sti_data - > inq_outptr ;
2005-04-17 02:20:36 +04:00
unsigned long flags ;
s32 ret ;
2023-05-10 23:17:27 +03:00
store_sti_ptr ( sti , & outptr - > ext_ptr , & sti - > sti_data - > inq_outptr_ext ) ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
do {
spin_lock_irqsave ( & sti - > lock , flags ) ;
2013-11-07 02:38:59 +04:00
memset ( inptr , 0 , sizeof ( * inptr ) ) ;
ret = sti_call ( sti , sti - > inq_conf , & default_conf_flags ,
inptr , outptr , sti - > glob_cfg ) ;
2005-04-17 02:20:36 +04:00
spin_unlock_irqrestore ( & sti - > lock , flags ) ;
} while ( ret = = 1 ) ;
}
static const struct sti_font_flags default_font_flags = {
. wait = STI_WAIT ,
. non_text = 0 ,
} ;
void
2020-10-12 11:44:52 +03:00
sti_putc ( struct sti_struct * sti , int c , int y , int x ,
struct sti_cooked_font * font )
2005-04-17 02:20:36 +04:00
{
2023-05-10 23:17:27 +03:00
struct sti_font_inptr * inptr ;
2013-11-07 02:38:59 +04:00
struct sti_font_inptr inptr_default = {
2023-05-10 23:17:27 +03:00
. font_start_addr = ( void * ) STI_PTR ( font - > raw ) ,
2005-04-17 02:20:36 +04:00
. index = c_index ( sti , c ) ,
. fg_color = c_fg ( sti , c ) ,
. bg_color = c_bg ( sti , c ) ,
2020-10-12 11:44:52 +03:00
. dest_x = x * font - > width ,
. dest_y = y * font - > height ,
2005-04-17 02:20:36 +04:00
} ;
2013-11-07 02:38:59 +04:00
struct sti_font_outptr * outptr = & sti - > sti_data - > font_outptr ;
2005-04-17 02:20:36 +04:00
s32 ret ;
unsigned long flags ;
do {
spin_lock_irqsave ( & sti - > lock , flags ) ;
2023-05-10 23:17:27 +03:00
inptr = & inptr_default ;
if ( IS_ENABLED ( CONFIG_64BIT ) & & ! sti - > do_call64 ) {
/* copy below 4G if calling 32-bit on LP64 kernel */
inptr = & sti - > sti_data - > font_inptr ;
* inptr = inptr_default ;
/* skip first 4 bytes for 32-bit STI call */
inptr = ( void * ) ( ( ( unsigned long ) inptr ) + sizeof ( u32 ) ) ;
}
2013-11-07 02:38:59 +04:00
ret = sti_call ( sti , sti - > font_unpmv , & default_font_flags ,
inptr , outptr , sti - > glob_cfg ) ;
2005-04-17 02:20:36 +04:00
spin_unlock_irqrestore ( & sti - > lock , flags ) ;
} while ( ret = = 1 ) ;
}
static const struct sti_blkmv_flags clear_blkmv_flags = {
2023-04-17 15:56:42 +03:00
. wait = STI_WAIT ,
. color = 1 ,
. clear = 1 ,
2005-04-17 02:20:36 +04:00
} ;
void
sti_set ( struct sti_struct * sti , int src_y , int src_x ,
int height , int width , u8 color )
{
2023-05-10 23:17:27 +03:00
struct sti_blkmv_inptr * inptr ;
2013-11-07 02:38:59 +04:00
struct sti_blkmv_inptr inptr_default = {
2005-04-17 02:20:36 +04:00
. 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 ,
} ;
2013-11-07 02:38:59 +04:00
struct sti_blkmv_outptr * outptr = & sti - > sti_data - > blkmv_outptr ;
2005-04-17 02:20:36 +04:00
s32 ret ;
unsigned long flags ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
do {
spin_lock_irqsave ( & sti - > lock , flags ) ;
2023-05-10 23:17:27 +03:00
inptr = & inptr_default ;
if ( IS_ENABLED ( CONFIG_64BIT ) & & ! sti - > do_call64 ) {
/* copy below 4G if calling 32-bit on LP64 kernel */
inptr = & sti - > sti_data - > blkmv_inptr ;
* inptr = inptr_default ;
}
2013-11-07 02:38:59 +04:00
ret = sti_call ( sti , sti - > block_move , & clear_blkmv_flags ,
inptr , outptr , sti - > glob_cfg ) ;
2005-04-17 02:20:36 +04:00
spin_unlock_irqrestore ( & sti - > lock , flags ) ;
} while ( ret = = 1 ) ;
}
void
sti_clear ( struct sti_struct * sti , int src_y , int src_x ,
2020-10-12 11:44:52 +03:00
int height , int width , int c , struct sti_cooked_font * font )
2005-04-17 02:20:36 +04:00
{
2023-05-10 23:17:27 +03:00
struct sti_blkmv_inptr * inptr ;
2013-11-07 02:38:59 +04:00
struct sti_blkmv_inptr inptr_default = {
2005-04-17 02:20:36 +04:00
. fg_color = c_fg ( sti , c ) ,
. bg_color = c_bg ( sti , c ) ,
2020-10-12 11:44:52 +03:00
. src_x = src_x * font - > width ,
. src_y = src_y * font - > height ,
. dest_x = src_x * font - > width ,
. dest_y = src_y * font - > height ,
. width = width * font - > width ,
. height = height * font - > height ,
2005-04-17 02:20:36 +04:00
} ;
2013-11-07 02:38:59 +04:00
struct sti_blkmv_outptr * outptr = & sti - > sti_data - > blkmv_outptr ;
2005-04-17 02:20:36 +04:00
s32 ret ;
unsigned long flags ;
do {
spin_lock_irqsave ( & sti - > lock , flags ) ;
2023-05-10 23:17:27 +03:00
inptr = & inptr_default ;
if ( IS_ENABLED ( CONFIG_64BIT ) & & ! sti - > do_call64 ) {
/* copy below 4G if calling 32-bit on LP64 kernel */
inptr = & sti - > sti_data - > blkmv_inptr ;
* inptr = inptr_default ;
}
2013-11-07 02:38:59 +04:00
ret = sti_call ( sti , sti - > block_move , & clear_blkmv_flags ,
inptr , outptr , sti - > glob_cfg ) ;
2005-04-17 02:20:36 +04:00
spin_unlock_irqrestore ( & sti - > lock , flags ) ;
} while ( ret = = 1 ) ;
}
static const struct sti_blkmv_flags default_blkmv_flags = {
2023-04-17 15:56:42 +03:00
. wait = STI_WAIT ,
2005-04-17 02:20:36 +04:00
} ;
void
sti_bmove ( struct sti_struct * sti , int src_y , int src_x ,
2020-10-12 11:44:52 +03:00
int dst_y , int dst_x , int height , int width ,
struct sti_cooked_font * font )
2005-04-17 02:20:36 +04:00
{
2023-05-10 23:17:27 +03:00
struct sti_blkmv_inptr * inptr ;
2013-11-07 02:38:59 +04:00
struct sti_blkmv_inptr inptr_default = {
2020-10-12 11:44:52 +03:00
. src_x = src_x * font - > width ,
. src_y = src_y * font - > height ,
. dest_x = dst_x * font - > width ,
. dest_y = dst_y * font - > height ,
. width = width * font - > width ,
. height = height * font - > height ,
2005-04-17 02:20:36 +04:00
} ;
2013-11-07 02:38:59 +04:00
struct sti_blkmv_outptr * outptr = & sti - > sti_data - > blkmv_outptr ;
2005-04-17 02:20:36 +04:00
s32 ret ;
unsigned long flags ;
do {
spin_lock_irqsave ( & sti - > lock , flags ) ;
2023-05-10 23:17:27 +03:00
inptr = & inptr_default ;
if ( IS_ENABLED ( CONFIG_64BIT ) & & ! sti - > do_call64 ) {
/* copy below 4G if calling 32-bit on LP64 kernel */
inptr = & sti - > sti_data - > blkmv_inptr ;
* inptr = inptr_default ;
}
2013-11-07 02:38:59 +04:00
ret = sti_call ( sti , sti - > block_move , & default_blkmv_flags ,
inptr , outptr , sti - > glob_cfg ) ;
2005-04-17 02:20:36 +04:00
spin_unlock_irqrestore ( & sti - > lock , flags ) ;
} while ( ret = = 1 ) ;
}
2007-06-29 10:17:50 +04:00
static void sti_flush ( unsigned long start , unsigned long end )
2005-04-17 02:20:36 +04:00
{
2007-06-29 10:17:50 +04:00
flush_icache_range ( start , end ) ;
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static void sti_rom_copy ( unsigned long base , unsigned long count , void * dest )
2005-04-17 02:20:36 +04:00
{
unsigned long dest_start = ( unsigned long ) dest ;
/* this still needs to be revisited (see arch/parisc/mm/init.c:246) ! */
while ( count > = 4 ) {
count - = 4 ;
* ( u32 * ) dest = gsc_readl ( base ) ;
base + = 4 ;
dest + = 4 ;
}
while ( count ) {
count - - ;
* ( u8 * ) dest = gsc_readb ( base ) ;
base + + ;
dest + + ;
}
2007-06-29 10:17:50 +04:00
sti_flush ( dest_start , ( unsigned long ) dest ) ;
2005-04-17 02:20:36 +04:00
}
2006-01-17 22:40:40 +03:00
static char default_sti_path [ 21 ] __read_mostly ;
2005-04-17 02:20:36 +04:00
# ifndef MODULE
2017-08-21 22:54:23 +03:00
static int __init sti_setup ( char * str )
2005-04-17 02:20:36 +04:00
{
if ( str )
2022-08-19 00:01:17 +03:00
strscpy ( default_sti_path , str , sizeof ( default_sti_path ) ) ;
2023-04-17 15:56:42 +03:00
2006-03-31 14:30:33 +04:00
return 1 ;
2005-04-17 02:20:36 +04:00
}
/* Assuming the machine has multiple STI consoles (=graphic cards) which
* all get detected by sticon , the user may define with the linux kernel
* parameter sti = < x > which of them will be the initial boot - console .
2023-04-17 15:56:42 +03:00
* < x > is a number between 0 and MAX_STI_ROMS , with 0 as the default
2005-04-17 02:20:36 +04:00
* STI screen .
*/
__setup ( " sti= " , sti_setup ) ;
# endif
2020-10-12 11:44:52 +03:00
static char * font_name ;
static int font_index ,
font_height ,
font_width ;
2005-04-17 02:20:36 +04:00
# ifndef MODULE
2012-12-22 01:07:39 +04:00
static int sti_font_setup ( char * str )
2005-04-17 02:20:36 +04:00
{
2020-10-12 11:44:52 +03:00
/*
* The default font can be selected in various ways .
* a ) sti_font = VGA8x16 , sti_font = 10 x20 , sti_font = 10 * 20 selects
* an built - in Linux framebuffer font .
* b ) sti_font = < index > , where index is ( 1. . x ) with 1 selecting
* the first HP STI ROM built - in font . .
*/
2005-04-17 02:20:36 +04:00
2020-10-12 11:44:52 +03:00
if ( * str > = ' 0 ' & & * str < = ' 9 ' ) {
char * x ;
2005-04-17 02:20:36 +04:00
2020-10-12 11:44:52 +03:00
if ( ( x = strchr ( str , ' x ' ) ) | | ( x = strchr ( str , ' * ' ) ) ) {
font_height = simple_strtoul ( str , NULL , 0 ) ;
font_width = simple_strtoul ( x + 1 , NULL , 0 ) ;
2005-04-17 02:20:36 +04:00
} else {
2020-10-12 11:44:52 +03:00
font_index = simple_strtoul ( str , NULL , 0 ) ;
2005-04-17 02:20:36 +04:00
}
2020-10-12 11:44:52 +03:00
} else {
font_name = str ; /* fb font name */
2005-04-17 02:20:36 +04:00
}
2006-03-31 14:30:33 +04:00
return 1 ;
2005-04-17 02:20:36 +04:00
}
/* The optional linux kernel parameter "sti_font" defines which font
* should be used by the sticon driver to draw characters to the screen .
* Possible values are :
* - sti_font = < fb_fontname > :
2023-04-17 15:56:42 +03:00
* < fb_fontname > is the name of one of the linux - kernel built - in
* framebuffer font names ( e . g . VGA8x16 , SUN22x18 ) .
* This is only available if the fonts have been statically compiled
2005-04-17 02:20:36 +04:00
* in with e . g . the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options .
2020-10-12 11:44:52 +03:00
* - sti_font = < number > ( < number > = 1 , 2 , 3 , . . . )
2005-04-17 02:20:36 +04:00
* most STI ROMs have built - in HP specific fonts , which can be selected
2023-04-17 15:56:42 +03:00
* by giving the desired number to the sticon driver .
2005-04-17 02:20:36 +04:00
* NOTE : This number is machine and STI ROM dependend .
* - sti_font = < height > x < width > ( e . g . sti_font = 16 x8 )
* < height > and < width > gives hints to the height and width of the
* font which the user wants . The sticon driver will try to use
* a font with this height and width , but if no suitable font is
* found , sticon will use the default 8 x8 font .
*/
__setup ( " sti_font= " , sti_font_setup ) ;
# endif
2023-04-17 15:56:42 +03:00
2023-05-10 23:17:27 +03:00
static void sti_dump_globcfg ( struct sti_struct * sti )
2005-04-17 02:20:36 +04:00
{
2023-05-10 23:17:27 +03:00
struct sti_glob_cfg * glob_cfg = sti - > glob_cfg ;
struct sti_glob_cfg_ext * cfg = & sti - > sti_data - > glob_cfg_ext ;
2023-04-17 15:56:42 +03:00
2020-10-12 11:44:52 +03:00
pr_debug ( " %d text planes \n "
2005-04-17 02:20:36 +04:00
" %4d x %4d screen resolution \n "
" %4d x %4d offscreen \n "
2023-05-10 23:17:27 +03:00
" %4d x %4d layout \n " ,
2005-04-17 02:20:36 +04:00
glob_cfg - > text_planes ,
glob_cfg - > onscreen_x , glob_cfg - > onscreen_y ,
glob_cfg - > offscreen_x , glob_cfg - > offscreen_y ,
2023-05-10 23:17:27 +03:00
glob_cfg - > total_x , glob_cfg - > total_y ) ;
2005-04-17 02:20:36 +04:00
2023-04-17 15:56:42 +03:00
/* dump extended cfg */
2020-10-12 11:44:52 +03:00
pr_debug ( " monitor %d \n "
2005-04-17 02:20:36 +04:00
" in friendly mode: %d \n "
" power consumption %d watts \n "
" freq ref %d \n "
2023-05-10 23:17:27 +03:00
" sti_mem_addr %px (size=%d bytes) \n " ,
2005-04-17 02:20:36 +04:00
cfg - > curr_mon ,
cfg - > friendly_boot ,
cfg - > power ,
cfg - > freq_ref ,
2023-05-10 23:17:27 +03:00
cfg - > sti_mem_addr , sti - > sti_mem_request ) ;
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static void sti_dump_outptr ( struct sti_struct * sti )
2005-04-17 02:20:36 +04:00
{
2020-10-12 11:44:52 +03:00
pr_debug ( " %d bits per pixel \n "
2005-04-17 02:20:36 +04:00
" %d used bits \n "
" %d planes \n "
" attributes %08x \n " ,
2013-11-07 02:38:59 +04:00
sti - > sti_data - > inq_outptr . bits_per_pixel ,
sti - > sti_data - > inq_outptr . bits_used ,
sti - > sti_data - > inq_outptr . planes ,
2020-10-12 11:44:52 +03:00
sti - > sti_data - > inq_outptr . attributes ) ;
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static int sti_init_glob_cfg ( struct sti_struct * sti , unsigned long rom_address ,
unsigned long hpa )
2005-04-17 02:20:36 +04:00
{
struct sti_glob_cfg * glob_cfg ;
struct sti_glob_cfg_ext * glob_cfg_ext ;
2023-05-10 23:17:27 +03:00
void * save_addr , * ptr ;
2005-04-17 02:20:36 +04:00
void * sti_mem_addr ;
2013-11-07 02:38:59 +04:00
int i , size ;
2005-04-17 02:20:36 +04:00
2013-11-07 02:38:59 +04:00
if ( sti - > sti_mem_request < 256 )
2005-04-17 02:20:36 +04:00
sti - > sti_mem_request = 256 ; /* STI default */
2013-11-07 02:38:59 +04:00
size = sizeof ( struct sti_all_data ) + sti - > sti_mem_request - 256 ;
2005-04-17 02:20:36 +04:00
2013-11-07 02:38:59 +04:00
sti - > sti_data = kzalloc ( size , STI_LOWMEM ) ;
if ( ! sti - > sti_data )
2005-04-17 02:20:36 +04:00
return - ENOMEM ;
2013-11-07 02:38:59 +04:00
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 ;
2005-04-17 02:20:36 +04:00
2023-05-10 23:17:27 +03:00
for ( i = 0 ; i < STI_REGION_MAX ; i + + ) {
2005-04-17 02:20:36 +04:00
unsigned long newhpa , len ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
if ( sti - > pd ) {
unsigned char offs = sti - > rm_entry [ i ] ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
if ( offs = = 0 )
continue ;
if ( offs ! = PCI_ROM_ADDRESS & &
( offs < PCI_BASE_ADDRESS_0 | |
offs > PCI_BASE_ADDRESS_5 ) ) {
2020-10-12 11:44:52 +03:00
pr_warn ( " STI pci region mapping for region %d (%02x) can't be mapped \n " ,
2005-04-17 02:20:36 +04:00
i , sti - > rm_entry [ i ] ) ;
continue ;
}
newhpa = pci_resource_start ( sti - > pd , ( offs - PCI_BASE_ADDRESS_0 ) / 4 ) ;
} else
newhpa = ( i = = 0 ) ? rom_address : hpa ;
sti - > regions_phys [ i ] =
REGION_OFFSET_TO_PHYS ( sti - > regions [ i ] , newhpa ) ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
len = sti - > regions [ i ] . region_desc . length * 4096 ;
2023-04-17 15:56:42 +03:00
2023-05-10 23:17:27 +03:00
pr_debug ( " region #%d: phys %08lx, len=%lukB, "
2005-04-17 02:20:36 +04:00
" btlb=%d, sysonly=%d, cache=%d, last=%d \n " ,
2023-05-10 23:17:27 +03:00
i , sti - > regions_phys [ i ] , len / 1024 ,
2005-04-17 02:20:36 +04:00
sti - > regions [ i ] . region_desc . btlb ,
sti - > regions [ i ] . region_desc . sys_only ,
2023-04-17 15:56:42 +03:00
sti - > regions [ i ] . region_desc . cache ,
2020-10-12 11:44:52 +03:00
sti - > regions [ i ] . region_desc . last ) ;
2005-04-17 02:20:36 +04:00
/* last entry reached ? */
if ( sti - > regions [ i ] . region_desc . last )
break ;
}
2023-05-10 23:17:27 +03:00
ptr = & glob_cfg - > region_ptrs ;
for ( i = 0 ; i < STI_REGION_MAX ; i + + )
ptr = store_sti_val ( sti , ptr , sti - > regions_phys [ i ] ) ;
* ( s32 * ) ptr = 0 ; /* set reent_lvl */
ptr + = sizeof ( s32 ) ;
ptr = store_sti_ptr ( sti , ptr , save_addr ) ;
ptr = store_sti_ptr ( sti , ptr , glob_cfg_ext ) ;
2005-04-17 02:20:36 +04:00
2023-05-10 23:17:27 +03:00
store_sti_ptr ( sti , & glob_cfg_ext - > sti_mem_addr , sti_mem_addr ) ;
2005-04-17 02:20:36 +04:00
sti - > glob_cfg = glob_cfg ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
2014-01-31 18:39:40 +04:00
# ifdef CONFIG_FONT_SUPPORT
2012-12-22 01:07:39 +04:00
static struct sti_cooked_font *
sti_select_fbfont ( struct sti_cooked_rom * cooked_rom , const char * fbfont_name )
2005-04-17 02:20:36 +04:00
{
2013-11-07 02:38:59 +04:00
const struct font_desc * fbfont = NULL ;
2005-04-17 02:20:36 +04:00
unsigned int size , bpc ;
void * dest ;
struct sti_rom_font * nf ;
struct sti_cooked_font * cooked_font ;
2023-04-17 15:56:42 +03:00
2013-11-07 02:38:59 +04:00
if ( fbfont_name & & strlen ( fbfont_name ) )
fbfont = find_font ( fbfont_name ) ;
2005-04-17 02:20:36 +04:00
if ( ! fbfont )
2024-03-16 03:10:21 +03:00
fbfont = get_default_font ( 1024 , 768 , NULL , NULL ) ;
2005-04-17 02:20:36 +04:00
if ( ! fbfont )
2005-10-22 06:41:49 +04:00
return NULL ;
2005-04-17 02:20:36 +04:00
2022-06-02 14:55:26 +03:00
pr_info ( " using %ux%u framebuffer font %s \n " ,
2013-11-07 02:38:59 +04:00
fbfont - > width , fbfont - > height , fbfont - > name ) ;
2023-04-17 15:56:42 +03:00
bpc = ( ( fbfont - > width + 7 ) / 8 ) * fbfont - > height ;
2020-11-12 15:14:21 +03:00
size = bpc * fbfont - > charcount ;
2005-04-17 02:20:36 +04:00
size + = sizeof ( struct sti_rom_font ) ;
2013-11-07 02:38:59 +04:00
nf = kzalloc ( size , STI_LOWMEM ) ;
2005-04-17 02:20:36 +04:00
if ( ! nf )
2005-10-22 06:41:49 +04:00
return NULL ;
2005-04-17 02:20:36 +04:00
nf - > first_char = 0 ;
2020-11-12 15:14:21 +03:00
nf - > last_char = fbfont - > charcount - 1 ;
2005-04-17 02:20:36 +04:00
nf - > width = fbfont - > width ;
nf - > height = fbfont - > height ;
nf - > font_type = STI_FONT_HPROMAN8 ;
nf - > bytes_per_char = bpc ;
nf - > next_font = 0 ;
nf - > underline_height = 1 ;
nf - > underline_pos = fbfont - > height - nf - > underline_height ;
dest = nf ;
dest + = sizeof ( struct sti_rom_font ) ;
2020-11-12 15:14:21 +03:00
memcpy ( dest , fbfont - > data , bpc * fbfont - > charcount ) ;
2005-04-17 02:20:36 +04:00
2006-01-17 22:40:40 +03:00
cooked_font = kzalloc ( sizeof ( * cooked_font ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! cooked_font ) {
2005-10-22 06:41:49 +04:00
kfree ( nf ) ;
return NULL ;
2005-04-17 02:20:36 +04:00
}
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
cooked_font - > raw = nf ;
2020-10-12 11:44:52 +03:00
cooked_font - > raw_ptr = nf ;
2005-04-17 02:20:36 +04:00
cooked_font - > next_font = NULL ;
cooked_rom - > font_start = cooked_font ;
return cooked_font ;
}
# else
2012-12-22 01:07:39 +04:00
static struct sti_cooked_font *
sti_select_fbfont ( struct sti_cooked_rom * cooked_rom , const char * fbfont_name )
2005-04-17 02:20:36 +04:00
{
return NULL ;
}
# endif
2022-04-05 13:16:15 +03:00
static void sti_dump_font ( struct sti_cooked_font * font )
{
# ifdef STI_DUMP_FONT
unsigned char * p = ( unsigned char * ) font - > raw ;
int n ;
p + = sizeof ( struct sti_rom_font ) ;
pr_debug ( " w %d h %d bpc %d \n " , font - > width , font - > height ,
font - > raw - > bytes_per_char ) ;
for ( n = 0 ; n < 256 * font - > raw - > bytes_per_char ; n + = 16 , p + = 16 ) {
pr_debug ( " 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, "
" 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, "
" 0x%02x, 0x%02x, 0x%02x, 0x%02x, \n " ,
p [ 0 ] , p [ 1 ] , p [ 2 ] , p [ 3 ] , p [ 4 ] , p [ 5 ] , p [ 6 ] , p [ 7 ] , p [ 8 ] ,
p [ 9 ] , p [ 10 ] , p [ 11 ] , p [ 12 ] , p [ 13 ] , p [ 14 ] , p [ 15 ] ) ;
}
# endif
}
2020-10-12 11:44:52 +03:00
static int sti_search_font ( struct sti_cooked_rom * rom , int height , int width )
{
struct sti_cooked_font * font ;
int i = 0 ;
for ( font = rom - > font_start ; font ; font = font - > next_font , i + + ) {
if ( ( font - > raw - > width = = width ) & &
( font - > raw - > height = = height ) )
return i ;
}
return 0 ;
}
static struct sti_cooked_font * sti_select_font ( struct sti_cooked_rom * rom )
2005-04-17 02:20:36 +04:00
{
struct sti_cooked_font * font ;
int i ;
/* check for framebuffer-font first */
2020-10-12 11:44:52 +03:00
if ( ! font_index ) {
font = sti_select_fbfont ( rom , font_name ) ;
if ( font )
return font ;
}
2005-04-17 02:20:36 +04:00
2020-10-12 11:44:52 +03:00
if ( font_width & & font_height )
font_index = sti_search_font ( rom ,
font_height , font_width ) ;
2005-04-17 02:20:36 +04:00
2020-10-12 11:44:52 +03:00
for ( font = rom - > font_start , i = font_index - 1 ;
font & & ( i > 0 ) ;
font = font - > next_font , i - - ) ;
2005-04-17 02:20:36 +04:00
if ( font )
return font ;
else
return rom - > font_start ;
}
2020-10-12 11:44:52 +03:00
static void sti_dump_rom ( struct sti_struct * sti )
2005-04-17 02:20:36 +04:00
{
2020-10-12 11:44:52 +03:00
struct sti_rom * rom = sti - > rom - > raw ;
struct sti_cooked_font * font_start ;
int nr ;
pr_info ( " id %04x-%04x, conforms to spec rev. %d.%02x \n " ,
2023-04-17 15:56:42 +03:00
rom - > graphics_id [ 0 ] ,
2005-04-17 02:20:36 +04:00
rom - > graphics_id [ 1 ] ,
2023-04-17 15:56:42 +03:00
rom - > revno [ 0 ] > > 4 ,
2005-04-17 02:20:36 +04:00
rom - > revno [ 0 ] & 0x0f ) ;
2020-10-12 11:44:52 +03:00
pr_debug ( " supports %d monitors \n " , rom - > num_mons ) ;
pr_debug ( " font start %08x \n " , rom - > font_start ) ;
pr_debug ( " region list %08x \n " , rom - > region_list ) ;
pr_debug ( " init_graph %08x \n " , rom - > init_graph ) ;
pr_debug ( " bus support %02x \n " , rom - > bus_support ) ;
pr_debug ( " ext bus support %02x \n " , rom - > ext_bus_support ) ;
pr_debug ( " alternate code type %d \n " , rom - > alt_code_type ) ;
font_start = sti - > rom - > font_start ;
nr = 0 ;
while ( font_start ) {
struct sti_rom_font * f = font_start - > raw ;
pr_info ( " built-in font #%d: size %dx%d, chars %d-%d, bpc %d \n " , + + nr ,
f - > width , f - > height ,
f - > first_char , f - > last_char , f - > bytes_per_char ) ;
font_start = font_start - > next_font ;
}
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static int sti_cook_fonts ( struct sti_cooked_rom * cooked_rom ,
struct sti_rom * raw_rom )
2005-04-17 02:20:36 +04:00
{
struct sti_rom_font * raw_font , * font_start ;
struct sti_cooked_font * cooked_font ;
2023-04-17 15:56:42 +03:00
2006-01-17 22:40:40 +03:00
cooked_font = kzalloc ( sizeof ( * cooked_font ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! cooked_font )
return 0 ;
cooked_rom - > font_start = cooked_font ;
raw_font = ( ( void * ) raw_rom ) + ( raw_rom - > font_start ) ;
font_start = raw_font ;
cooked_font - > raw = raw_font ;
while ( raw_font - > next_font ) {
raw_font = ( ( void * ) font_start ) + ( raw_font - > next_font ) ;
2006-01-17 22:40:40 +03:00
cooked_font - > next_font = kzalloc ( sizeof ( * cooked_font ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! cooked_font - > next_font )
return 1 ;
cooked_font = cooked_font - > next_font ;
cooked_font - > raw = raw_font ;
}
cooked_font - > next_font = NULL ;
return 1 ;
}
2005-10-22 06:41:49 +04:00
# define BMODE_RELOCATE(offset) offset = (offset) / 4;
# define BMODE_LAST_ADDR_OFFS 0x50
2005-04-17 02:20:36 +04:00
2020-10-12 11:44:52 +03:00
void sti_font_convert_bytemode ( struct sti_struct * sti , struct sti_cooked_font * f )
2005-04-17 02:20:36 +04:00
{
unsigned char * n , * p , * q ;
2020-11-12 15:14:21 +03:00
int size = f - > raw - > bytes_per_char * ( f - > raw - > last_char + 1 ) + sizeof ( struct sti_rom_font ) ;
2020-10-12 11:44:52 +03:00
struct sti_rom_font * old_font ;
if ( sti - > wordmode )
return ;
old_font = f - > raw_ptr ;
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:03:40 +03:00
n = kcalloc ( 4 , size , STI_LOWMEM ) ;
2020-10-12 11:44:52 +03:00
f - > raw_ptr = n ;
2005-04-17 02:20:36 +04:00
if ( ! n )
2020-10-12 11:44:52 +03:00
return ;
2005-04-17 02:20:36 +04:00
p = n + 3 ;
2020-10-12 11:44:52 +03:00
q = ( unsigned char * ) f - > raw ;
2005-04-17 02:20:36 +04:00
while ( size - - ) {
* p = * q + + ;
2020-10-12 11:44:52 +03:00
p + = 4 ;
2005-04-17 02:20:36 +04:00
}
2020-10-12 11:44:52 +03:00
/* store new ptr to byte-mode font and delete old font */
f - > raw = ( struct sti_rom_font * ) ( n + 3 ) ;
kfree ( old_font ) ;
2005-04-17 02:20:36 +04:00
}
2020-10-12 11:44:52 +03:00
EXPORT_SYMBOL ( sti_font_convert_bytemode ) ;
2005-04-17 02:20:36 +04:00
2012-12-22 01:07:39 +04:00
static void sti_bmode_rom_copy ( unsigned long base , unsigned long count ,
void * dest )
2005-04-17 02:20:36 +04:00
{
unsigned long dest_start = ( unsigned long ) dest ;
while ( count ) {
count - - ;
* ( u8 * ) dest = gsc_readl ( base ) ;
base + = 4 ;
dest + + ;
}
2007-06-29 10:17:50 +04:00
sti_flush ( dest_start , ( unsigned long ) dest ) ;
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static struct sti_rom * sti_get_bmode_rom ( unsigned long address )
2005-04-17 02:20:36 +04:00
{
struct sti_rom * raw ;
u32 size ;
2005-10-22 06:41:49 +04:00
struct sti_rom_font * raw_font , * font_start ;
2005-04-17 02:20:36 +04:00
sti_bmode_rom_copy ( address + BMODE_LAST_ADDR_OFFS , sizeof ( size ) , & size ) ;
2005-10-22 06:41:49 +04:00
size = ( size + 3 ) / 4 ;
2013-11-07 02:38:59 +04:00
raw = kmalloc ( size , STI_LOWMEM ) ;
2005-04-17 02:20:36 +04:00
if ( raw ) {
2005-10-22 06:41:49 +04:00
sti_bmode_rom_copy ( address , size , raw ) ;
memmove ( & raw - > res004 , & raw - > type [ 0 ] , 0x3c ) ;
raw - > type [ 3 ] = raw - > res004 ;
2005-04-17 02:20:36 +04:00
2005-10-22 06:41:49 +04:00
BMODE_RELOCATE ( raw - > region_list ) ;
BMODE_RELOCATE ( raw - > font_start ) ;
2005-04-17 02:20:36 +04:00
2005-10-22 06:41:49 +04:00
BMODE_RELOCATE ( raw - > init_graph ) ;
BMODE_RELOCATE ( raw - > state_mgmt ) ;
BMODE_RELOCATE ( raw - > font_unpmv ) ;
BMODE_RELOCATE ( raw - > block_move ) ;
BMODE_RELOCATE ( raw - > inq_conf ) ;
2005-04-17 02:20:36 +04:00
2005-10-22 06:41:49 +04:00
raw_font = ( ( void * ) raw ) + raw - > font_start ;
font_start = raw_font ;
2023-04-17 15:56:42 +03:00
2005-10-22 06:41:49 +04:00
while ( raw_font - > next_font ) {
BMODE_RELOCATE ( raw_font - > next_font ) ;
raw_font = ( ( void * ) font_start ) + raw_font - > next_font ;
}
2005-04-17 02:20:36 +04:00
}
2005-10-22 06:41:49 +04:00
return raw ;
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static struct sti_rom * sti_get_wmode_rom ( unsigned long address )
2005-04-17 02:20:36 +04:00
{
struct sti_rom * raw ;
unsigned long size ;
2005-10-22 06:41:49 +04:00
2023-04-17 15:56:42 +03:00
/* read the ROM size directly from the struct in ROM */
2005-04-17 02:20:36 +04:00
size = gsc_readl ( address + offsetof ( struct sti_rom , last_addr ) ) ;
2013-11-07 02:38:59 +04:00
raw = kmalloc ( size , STI_LOWMEM ) ;
2005-10-22 06:41:49 +04:00
if ( raw )
sti_rom_copy ( address , size , raw ) ;
2005-04-17 02:20:36 +04:00
2005-10-22 06:41:49 +04:00
return raw ;
2005-04-17 02:20:36 +04:00
}
2012-12-22 01:07:39 +04:00
static int sti_read_rom ( int wordmode , struct sti_struct * sti ,
unsigned long address )
2005-04-17 02:20:36 +04:00
{
struct sti_cooked_rom * cooked ;
struct sti_rom * raw = NULL ;
2008-07-30 09:33:01 +04:00
unsigned long revno ;
2005-04-17 02:20:36 +04:00
cooked = kmalloc ( sizeof * cooked , GFP_KERNEL ) ;
if ( ! cooked )
goto out_err ;
2005-10-22 06:41:49 +04:00
if ( wordmode )
raw = sti_get_wmode_rom ( address ) ;
else
raw = sti_get_bmode_rom ( address ) ;
if ( ! raw )
goto out_err ;
2005-04-17 02:20:36 +04:00
if ( ! sti_cook_fonts ( cooked , raw ) ) {
2020-10-12 11:44:52 +03:00
pr_warn ( " No font found for STI at %08lx \n " , address ) ;
2005-04-17 02:20:36 +04:00
goto out_err ;
}
if ( raw - > region_list )
memcpy ( sti - > regions , ( ( void * ) raw ) + raw - > region_list , sizeof ( sti - > regions ) ) ;
address = ( unsigned long ) STI_PTR ( raw ) ;
2020-10-12 11:44:52 +03:00
pr_info ( " STI %s ROM supports 32 %sbit firmware functions. \n " ,
wordmode ? " word mode " : " byte mode " ,
2013-11-07 02:38:59 +04:00
raw - > alt_code_type = = ALT_CODE_TYPE_PA_RISC_64
? " and 64 " : " " ) ;
2023-05-10 23:17:27 +03:00
if ( IS_ENABLED ( CONFIG_64BIT ) & &
raw - > alt_code_type = = ALT_CODE_TYPE_PA_RISC_64 ) {
sti - > do_call64 = 1 ;
sti - > font_unpmv = address + ( raw - > font_unp_addr & 0x03ffffff ) ;
sti - > block_move = address + ( raw - > block_move_addr & 0x03ffffff ) ;
sti - > init_graph = address + ( raw - > init_graph_addr & 0x03ffffff ) ;
sti - > inq_conf = address + ( raw - > inq_conf_addr & 0x03ffffff ) ;
} else {
sti - > font_unpmv = address + ( raw - > font_unpmv & 0x03ffffff ) ;
sti - > block_move = address + ( raw - > block_move & 0x03ffffff ) ;
sti - > init_graph = address + ( raw - > init_graph & 0x03ffffff ) ;
sti - > inq_conf = address + ( raw - > inq_conf & 0x03ffffff ) ;
}
2005-04-17 02:20:36 +04:00
sti - > rom = cooked ;
sti - > rom - > raw = raw ;
2020-10-12 11:44:52 +03:00
sti_dump_rom ( sti ) ;
sti - > wordmode = wordmode ;
sti - > font = sti_select_font ( sti - > rom ) ;
sti - > font - > width = sti - > font - > raw - > width ;
sti - > font - > height = sti - > font - > raw - > height ;
sti_font_convert_bytemode ( sti , sti - > font ) ;
2022-04-05 13:16:15 +03:00
sti_dump_font ( sti - > font ) ;
2005-04-17 02:20:36 +04:00
2023-05-10 23:17:27 +03:00
pr_info ( " using %d-bit STI ROM functions \n " ,
( IS_ENABLED ( CONFIG_64BIT ) & & sti - > do_call64 ) ? 64 : 32 ) ;
2005-04-17 02:20:36 +04:00
sti - > sti_mem_request = raw - > sti_mem_req ;
2023-05-10 23:17:27 +03:00
pr_debug ( " mem_request = %d, reentsize %d \n " ,
sti - > sti_mem_request , raw - > reentsize ) ;
2005-04-17 02:20:36 +04:00
sti - > graphics_id [ 0 ] = raw - > graphics_id [ 0 ] ;
sti - > graphics_id [ 1 ] = raw - > graphics_id [ 1 ] ;
2008-07-30 09:33:01 +04:00
/* check if the ROM routines in this card are compatible */
if ( wordmode | | sti - > graphics_id [ 1 ] ! = 0x09A02587 )
goto ok ;
revno = ( raw - > revno [ 0 ] < < 8 ) | raw - > revno [ 1 ] ;
switch ( sti - > graphics_id [ 0 ] ) {
case S9000_ID_HCRX :
/* HyperA or HyperB ? */
if ( revno = = 0x8408 | | revno = = 0x840b )
goto msg_not_supported ;
break ;
case CRT_ID_THUNDER :
if ( revno = = 0x8509 )
goto msg_not_supported ;
break ;
case CRT_ID_THUNDER2 :
if ( revno = = 0x850c )
goto msg_not_supported ;
}
ok :
2005-04-17 02:20:36 +04:00
return 1 ;
2008-07-30 09:33:01 +04:00
msg_not_supported :
2020-10-12 11:44:52 +03:00
pr_warn ( " Sorry, this GSC/STI card is not yet supported. \n " ) ;
pr_warn ( " Please see https://parisc.wiki.kernel.org/ "
" index.php/Graphics_howto for more info. \n " ) ;
2008-07-30 09:33:01 +04:00
/* fall through */
2005-04-17 02:20:36 +04:00
out_err :
kfree ( raw ) ;
kfree ( cooked ) ;
return 0 ;
}
2012-12-22 01:07:39 +04:00
static struct sti_struct * sti_try_rom_generic ( unsigned long address ,
unsigned long hpa ,
struct pci_dev * pd )
2005-04-17 02:20:36 +04:00
{
struct sti_struct * sti ;
int ok ;
u32 sig ;
if ( num_sti_roms > = MAX_STI_ROMS ) {
2020-10-12 11:44:52 +03:00
pr_warn ( " maximum number of STI ROMS reached ! \n " ) ;
2005-10-22 06:41:49 +04:00
return NULL ;
2005-04-17 02:20:36 +04:00
}
2023-04-17 15:56:42 +03:00
2006-01-17 22:40:40 +03:00
sti = kzalloc ( sizeof ( * sti ) , GFP_KERNEL ) ;
2018-03-28 17:34:29 +03:00
if ( ! sti )
2005-10-22 06:41:49 +04:00
return NULL ;
2005-04-17 02:20:36 +04:00
spin_lock_init ( & sti - > lock ) ;
test_rom :
2023-05-10 23:17:27 +03:00
/* pdc_add_valid() works only on 32-bit kernels */
if ( ( ! IS_ENABLED ( CONFIG_64BIT ) | |
( boot_cpu_data . pdc . capabilities & PDC_MODEL_OS32 ) ) & &
pdc_add_valid ( address ) ) {
2005-04-17 02:20:36 +04:00
goto out_err ;
2023-05-10 23:17:27 +03:00
}
2005-04-17 02:20:36 +04:00
sig = gsc_readl ( address ) ;
/* check for a PCI ROM structure */
if ( ( le32_to_cpu ( sig ) = = 0xaa55 ) ) {
unsigned int i , rm_offset ;
u32 * rm ;
i = gsc_readl ( address + 0x04 ) ;
if ( i ! = 1 ) {
2023-04-17 15:56:42 +03:00
/* The ROM could have multiple architecture
2005-04-17 02:20:36 +04:00
* dependent images ( e . g . i386 , parisc , . . . ) */
2020-10-12 11:44:52 +03:00
pr_warn ( " PCI ROM is not a STI ROM type image (0x%8x) \n " , i ) ;
2005-04-17 02:20:36 +04:00
goto out_err ;
}
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
sti - > pd = pd ;
i = gsc_readl ( address + 0x0c ) ;
2020-10-12 11:44:52 +03:00
pr_debug ( " PCI ROM size (from header) = %d kB \n " ,
le16_to_cpu ( i > > 16 ) * 512 / 1024 ) ;
2005-04-17 02:20:36 +04:00
rm_offset = le16_to_cpu ( i & 0xffff ) ;
2023-04-17 15:56:42 +03:00
if ( rm_offset ) {
2005-04-17 02:20:36 +04:00
/* read 16 bytes from the pci region mapper array */
rm = ( u32 * ) & sti - > rm_entry ;
* rm + + = gsc_readl ( address + rm_offset + 0x00 ) ;
* rm + + = gsc_readl ( address + rm_offset + 0x04 ) ;
* rm + + = gsc_readl ( address + rm_offset + 0x08 ) ;
* rm + + = gsc_readl ( address + rm_offset + 0x0c ) ;
}
address + = le32_to_cpu ( gsc_readl ( address + 8 ) ) ;
2020-10-12 11:44:52 +03:00
pr_debug ( " sig %04x, PCI STI ROM at %08lx \n " , sig , address ) ;
2005-04-17 02:20:36 +04:00
goto test_rom ;
}
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
ok = 0 ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
if ( ( sig & 0xff ) = = 0x01 ) {
2020-10-12 11:44:52 +03:00
pr_debug ( " byte mode ROM at %08lx, hpa at %08lx \n " ,
address , hpa ) ;
2005-04-17 02:20:36 +04:00
ok = sti_read_rom ( 0 , sti , address ) ;
}
if ( ( sig & 0xffff ) = = 0x0303 ) {
2020-10-12 11:44:52 +03:00
pr_debug ( " word mode ROM at %08lx, hpa at %08lx \n " ,
address , hpa ) ;
2005-04-17 02:20:36 +04:00
ok = sti_read_rom ( 1 , sti , address ) ;
}
if ( ! ok )
goto out_err ;
if ( sti_init_glob_cfg ( sti , address , hpa ) )
goto out_err ; /* not enough memory */
/* disable STI PCI ROM. ROM and card RAM overlap and
* leaving it enabled would force HPMCs
*/
if ( sti - > pd ) {
unsigned long rom_base ;
2023-04-17 15:56:42 +03:00
rom_base = pci_resource_start ( sti - > pd , PCI_ROM_RESOURCE ) ;
2005-04-17 02:20:36 +04:00
pci_write_config_dword ( sti - > pd , PCI_ROM_ADDRESS , rom_base & ~ PCI_ROM_ADDRESS_ENABLE ) ;
2020-10-12 11:44:52 +03:00
pr_debug ( " STI PCI ROM disabled \n " ) ;
2005-04-17 02:20:36 +04:00
}
if ( sti_init_graph ( sti ) )
goto out_err ;
sti_inq_conf ( sti ) ;
2023-05-10 23:17:27 +03:00
sti_dump_globcfg ( sti ) ;
2005-04-17 02:20:36 +04:00
sti_dump_outptr ( sti ) ;
2023-04-17 15:56:42 +03:00
2013-11-07 02:38:59 +04:00
pr_info ( " graphics card name: %s \n " ,
sti - > sti_data - > inq_outptr . dev_name ) ;
2005-04-17 02:20:36 +04:00
sti_roms [ num_sti_roms ] = sti ;
num_sti_roms + + ;
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
return sti ;
out_err :
kfree ( sti ) ;
return NULL ;
}
2012-12-22 01:07:39 +04:00
static void sticore_check_for_default_sti ( struct sti_struct * sti , char * path )
2005-04-17 02:20:36 +04:00
{
2022-06-02 14:55:26 +03:00
pr_info ( " located at [%s] \n " , sti - > pa_path ) ;
2005-04-17 02:20:36 +04:00
if ( strcmp ( path , default_sti_path ) = = 0 )
default_sti = sti ;
}
/*
2023-04-17 15:56:42 +03:00
* on newer systems PDC gives the address of the ROM
2005-04-17 02:20:36 +04:00
* in the additional address field addr [ 1 ] while on
2023-04-17 15:56:42 +03:00
* older Systems the PDC stores it in page0 - > proc_sti
2005-04-17 02:20:36 +04:00
*/
2017-08-21 22:54:23 +03:00
static int __init sticore_pa_init ( struct parisc_device * dev )
2005-04-17 02:20:36 +04:00
{
struct sti_struct * sti = NULL ;
2005-10-22 06:41:49 +04:00
int hpa = dev - > hpa . start ;
if ( dev - > num_addrs & & dev - > addr [ 0 ] )
sti = sti_try_rom_generic ( dev - > addr [ 0 ] , hpa , NULL ) ;
if ( ! sti )
sti = sti_try_rom_generic ( hpa , hpa , NULL ) ;
if ( ! sti )
sti = sti_try_rom_generic ( PAGE0 - > proc_sti , hpa , NULL ) ;
2005-04-17 02:20:36 +04:00
if ( ! sti )
return 1 ;
2005-10-22 06:41:49 +04:00
2022-06-02 14:55:26 +03:00
print_pa_hwpath ( dev , sti - > pa_path ) ;
sticore_check_for_default_sti ( sti , sti - > pa_path ) ;
2023-12-20 16:22:54 +03:00
sti - > dev = & dev - > dev ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2012-12-22 01:07:39 +04:00
static int sticore_pci_init ( struct pci_dev * pd , const struct pci_device_id * ent )
2005-04-17 02:20:36 +04:00
{
# ifdef CONFIG_PCI
unsigned long fb_base , rom_base ;
unsigned int fb_len , rom_len ;
2009-08-02 17:26:51 +04:00
int err ;
2005-04-17 02:20:36 +04:00
struct sti_struct * sti ;
2023-04-17 15:56:42 +03:00
2009-08-02 17:26:51 +04:00
err = pci_enable_device ( pd ) ;
if ( err < 0 ) {
dev_err ( & pd - > dev , " Cannot enable PCI device \n " ) ;
return err ;
}
2005-04-17 02:20:36 +04:00
fb_base = pci_resource_start ( pd , 0 ) ;
fb_len = pci_resource_len ( pd , 0 ) ;
rom_base = pci_resource_start ( pd , PCI_ROM_RESOURCE ) ;
rom_len = pci_resource_len ( pd , PCI_ROM_RESOURCE ) ;
if ( rom_base ) {
pci_write_config_dword ( pd , PCI_ROM_ADDRESS , rom_base | PCI_ROM_ADDRESS_ENABLE ) ;
2020-10-12 11:44:52 +03:00
pr_debug ( " STI PCI ROM enabled at 0x%08lx \n " , rom_base ) ;
2005-04-17 02:20:36 +04:00
}
2020-10-12 11:44:52 +03:00
pr_info ( " STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB) \n " ,
2005-04-17 02:20:36 +04:00
rom_base , rom_len / 1024 , fb_base , fb_len / 1024 / 1024 ) ;
2020-10-12 11:44:52 +03:00
pr_debug ( " Trying PCI STI ROM at %08lx, PCI hpa at %08lx \n " ,
rom_base , fb_base ) ;
2005-04-17 02:20:36 +04:00
sti = sti_try_rom_generic ( rom_base , fb_base , pd ) ;
if ( sti ) {
2022-06-02 14:55:26 +03:00
print_pci_hwpath ( pd , sti - > pa_path ) ;
sticore_check_for_default_sti ( sti , sti - > pa_path ) ;
2005-04-17 02:20:36 +04:00
}
2023-04-17 15:56:42 +03:00
2005-04-17 02:20:36 +04:00
if ( ! sti ) {
2020-10-12 11:44:52 +03:00
pr_warn ( " Unable to handle STI device '%s' \n " , pci_name ( pd ) ) ;
2005-04-17 02:20:36 +04:00
return - ENODEV ;
}
2023-12-20 16:22:54 +03:00
sti - > dev = & pd - > dev ;
2005-04-17 02:20:36 +04:00
# endif /* CONFIG_PCI */
return 0 ;
}
2017-08-21 22:54:23 +03:00
static void __exit sticore_pci_remove ( struct pci_dev * pd )
2005-04-17 02:20:36 +04:00
{
BUG ( ) ;
}
static struct pci_device_id sti_pci_tbl [ ] = {
{ PCI_DEVICE ( PCI_VENDOR_ID_HP , PCI_DEVICE_ID_HP_VISUALIZE_EG ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_HP , PCI_DEVICE_ID_HP_VISUALIZE_FX6 ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_HP , PCI_DEVICE_ID_HP_VISUALIZE_FX4 ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_HP , PCI_DEVICE_ID_HP_VISUALIZE_FX2 ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_HP , PCI_DEVICE_ID_HP_VISUALIZE_FXE ) } ,
{ 0 , } /* terminate list */
} ;
MODULE_DEVICE_TABLE ( pci , sti_pci_tbl ) ;
static struct pci_driver pci_sti_driver = {
. name = " sti " ,
. id_table = sti_pci_tbl ,
. probe = sticore_pci_init ,
2017-08-21 22:54:23 +03:00
. remove = __exit_p ( sticore_pci_remove ) ,
2005-04-17 02:20:36 +04:00
} ;
static struct parisc_device_id sti_pa_tbl [ ] = {
{ HPHW_FIO , HVERSION_REV_ANY_ID , HVERSION_ANY_ID , 0x00077 } ,
{ HPHW_FIO , HVERSION_REV_ANY_ID , HVERSION_ANY_ID , 0x00085 } ,
{ 0 , }
} ;
2017-08-21 22:54:23 +03:00
MODULE_DEVICE_TABLE ( parisc , sti_pa_tbl ) ;
2005-04-17 02:20:36 +04:00
2017-08-21 22:54:23 +03:00
static struct parisc_driver pa_sti_driver __refdata = {
2005-04-17 02:20:36 +04:00
. name = " sti " ,
. id_table = sti_pa_tbl ,
. probe = sticore_pa_init ,
} ;
/*
* sti_init_roms ( ) - detects all STI ROMs and stores them in sti_roms [ ]
*/
2006-01-17 22:40:40 +03:00
static int sticore_initialized __read_mostly ;
2005-04-17 02:20:36 +04:00
2012-12-22 01:07:39 +04:00
static void sti_init_roms ( void )
2005-04-17 02:20:36 +04:00
{
if ( sticore_initialized )
return ;
sticore_initialized = 1 ;
2020-10-12 11:44:52 +03:00
pr_info ( " STI GSC/PCI core graphics driver "
2005-04-17 02:20:36 +04:00
STI_DRIVERVERSION " \n " ) ;
/* Register drivers for native & PCI cards */
register_parisc_driver ( & pa_sti_driver ) ;
2009-08-02 17:26:51 +04:00
WARN_ON ( pci_register_driver ( & pci_sti_driver ) ) ;
2005-04-17 02:20:36 +04:00
/* if we didn't find the given default sti, take the first one */
if ( ! default_sti )
default_sti = sti_roms [ 0 ] ;
}
/*
* index = 0 gives default sti
* index > 0 gives other stis in detection order
*/
struct sti_struct * sti_get_rom ( unsigned int index )
{
if ( ! sticore_initialized )
sti_init_roms ( ) ;
if ( index = = 0 )
return default_sti ;
if ( index > num_sti_roms )
return NULL ;
return sti_roms [ index - 1 ] ;
}
EXPORT_SYMBOL ( sti_get_rom ) ;
2013-11-07 02:38:59 +04:00
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 ;
/* Check for overflow when using 32bit STI on 64bit kernel. */
2023-05-10 23:17:27 +03:00
if ( WARN_ONCE ( IS_ENABLED ( CONFIG_64BIT ) & & ! sti - > do_call64 & &
( upper_32_bits ( _flags ) | | upper_32_bits ( _inptr ) | |
upper_32_bits ( _outptr ) | | upper_32_bits ( _glob_cfg ) ) ,
2013-11-07 02:38:59 +04:00
" Out of 32bit-range pointers! " ) )
return - 1 ;
2023-05-10 23:17:27 +03:00
ret = pdc_sti_call ( func , _flags , _inptr , _outptr , _glob_cfg ,
sti - > do_call64 ) ;
2013-11-07 02:38:59 +04:00
return ret ;
}
2005-04-17 02:20:36 +04:00
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_LICENSE ( " GPL v2 " ) ;