aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/xgifb/XGI_main_26.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/xgifb/XGI_main_26.c')
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 64ffd70eb7dc..f775c5453845 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/sizes.h>
#include <linux/module.h>
#ifdef CONFIG_MTRR
@@ -329,6 +330,7 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
{
u16 xres, yres;
struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
+ unsigned long required_mem;
if (xgifb_info->chip == XG21) {
if (xgifb_info->display2 == XGIFB_DISP_LCD) {
@@ -345,13 +347,13 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
}
}
- return myindex;
+ goto check_memory;
}
/* FIXME: for now, all is valid on XG27 */
if (xgifb_info->chip == XG27)
- return myindex;
+ goto check_memory;
if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
return -1;
@@ -539,6 +541,12 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
case XGIFB_DISP_NONE:
break;
}
+
+check_memory:
+ required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres *
+ XGIbios_mode[myindex].bpp / 8;
+ if (required_mem > xgifb_info->video_size)
+ return -1;
return myindex;
}
@@ -913,17 +921,10 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
}
if ((filter >= 0) && (filter <= 7)) {
- pr_debug("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
+ pr_debug("FilterTable[%d]-%d: %*ph\n",
filter_tb, filter,
- XGI_TV_filter[filter_tb].
- filter[filter][0],
- XGI_TV_filter[filter_tb].
- filter[filter][1],
- XGI_TV_filter[filter_tb].
- filter[filter][2],
- XGI_TV_filter[filter_tb].
- filter[filter][3]
- );
+ 4, XGI_TV_filter[filter_tb].
+ filter[filter]);
xgifb_reg_set(
XGIPART2,
0x35,
@@ -1404,11 +1405,10 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
|| var->xoffset)
return -EINVAL;
- } else {
- if (var->xoffset + info->var.xres > info->var.xres_virtual
+ } else if (var->xoffset + info->var.xres > info->var.xres_virtual
|| var->yoffset + info->var.yres
- > info->var.yres_virtual)
- return -EINVAL;
+ > info->var.yres_virtual) {
+ return -EINVAL;
}
err = XGIfb_pan_var(var, info);
if (err < 0)
@@ -1471,6 +1471,9 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
+ if (!reg)
+ return -1;
+
switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
case XGI_DRAM_SIZE_1MB:
xgifb_info->video_size = 0x100000;
@@ -1701,6 +1704,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
struct fb_info *fb_info;
struct xgifb_video_info *xgifb_info;
struct xgi_hw_device_info *hw_info;
+ unsigned long video_size_max;
fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev);
if (!fb_info)
@@ -1721,6 +1725,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
xgifb_info->subsysvendor = pdev->subsystem_vendor;
xgifb_info->subsysdevice = pdev->subsystem_device;
+ video_size_max = pci_resource_len(pdev, 0);
xgifb_info->video_base = pci_resource_start(pdev, 0);
xgifb_info->mmio_base = pci_resource_start(pdev, 1);
xgifb_info->mmio_size = pci_resource_len(pdev, 1);
@@ -1777,10 +1782,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
hw_info->jChipType = xgifb_info->chip;
if (XGIfb_get_dram_size(xgifb_info)) {
- dev_err(&pdev->dev,
- "Fatal error: Unable to determine RAM size.\n");
- ret = -ENODEV;
- goto error_disable;
+ xgifb_info->video_size = min_t(unsigned long, video_size_max,
+ SZ_16M);
+ } else if (xgifb_info->video_size > video_size_max) {
+ xgifb_info->video_size = video_size_max;
}
/* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */