[PATCH 01/16] [FB] viafb: Fix various resource leaks during module_init()

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Jonathan Corbet
Date: Thursday, April 8, 2010 - 10:15 am

From: Harald Welte <laforge@gnumonks.org>

The current code executed from module_init() in viafb does not have
proper error checking and [partial] resoure release paths in case
an error happens half way through driver initialization.

This patch adresses the most obvious of those issues, such as a
leftover i2c bus if module_init (and thus module load) fails.

[jc: fixed merge conflicts]
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
---
 drivers/video/via/viafbdev.c |   52 ++++++++++++++++++++++++++++++-----------
 1 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 3028e7d..91bfe6d 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
 
  * This program is free software; you can redistribute it and/or
@@ -1847,7 +1847,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 				   const struct pci_device_id *ent)
 {
 	u32 default_xres, default_yres;
-	int vmode_index;
+	int rc, vmode_index;
 	u32 viafb_par_length;
 
 	DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
@@ -1862,7 +1862,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 		&pdev->dev);
 	if (!viafbinfo) {
 		printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
-		return -ENODEV;
+		return -ENOMEM;
 	}
 
 	viaparinfo = (struct viafb_par *)viafbinfo->par;
@@ -1886,7 +1886,9 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 		viafb_dual_fb = 0;
 
 	/* Set up I2C bus stuff */
-	viafb_create_i2c_bus(viaparinfo);
+	rc = viafb_create_i2c_bus(viaparinfo);
+	if (rc)
+		goto out_fb_release;
 
 	viafb_init_chip_info(pdev, ent);
 	viaparinfo->fbmem = pci_resource_start(pdev, 0);
@@ -1897,7 +1899,8 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 		viaparinfo->memsize);
 	if (!viafbinfo->screen_base) {
 		printk(KERN_INFO "ioremap failed\n");
-		return -ENOMEM;
+		rc = -EIO;
+		goto out_delete_i2c;
 	}
 
 	viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1);
@@ -1988,8 +1991,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 		if (!viafbinfo1) {
 			printk(KERN_ERR
 			"allocate the second framebuffer struct error\n");
-			framebuffer_release(viafbinfo);
-			return -ENOMEM;
+			goto out_delete_i2c;
 		}
 		viaparinfo1 = viafbinfo1->par;
 		memcpy(viaparinfo1, viaparinfo, viafb_par_length);
@@ -2044,21 +2046,26 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 	viaparinfo->depth = fb_get_color_depth(&viafbinfo->var,
 		&viafbinfo->fix);
 	default_var.activate = FB_ACTIVATE_NOW;
-	fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
+	rc = fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
+	if (rc)
+		goto out_fb1_release;
 
 	if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
 	    && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) {
-		if (register_framebuffer(viafbinfo1) < 0)
-			return -EINVAL;
+		rc = register_framebuffer(viafbinfo1);
+		if (rc)
+			goto out_dealloc_cmap;
 	}
-	if (register_framebuffer(viafbinfo) < 0)
-		return -EINVAL;
+	rc = register_framebuffer(viafbinfo);
+	if (rc)
+		goto out_fb1_unreg_lcd_cle266;
 
 	if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device)
 			|| (viaparinfo->chip_info->gfx_chip_name !=
 			UNICHROME_CLE266))) {
-		if (register_framebuffer(viafbinfo1) < 0)
-			return -EINVAL;
+		rc = register_framebuffer(viafbinfo1);
+		if (rc)
+			goto out_fb_unreg;
 	}
 	DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n",
 		  viafbinfo->node, viafbinfo->fix.id, default_var.xres,
@@ -2067,6 +2074,23 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 	viafb_init_proc(&viaparinfo->shared->proc_entry);
 	viafb_init_dac(IGA2);
 	return 0;
+
+out_fb_unreg:
+	unregister_framebuffer(viafbinfo);
+out_fb1_unreg_lcd_cle266:
+	if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
+            && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
+		unregister_framebuffer(viafbinfo1);
+out_dealloc_cmap:
+	fb_dealloc_cmap(&viafbinfo->cmap);
+out_fb1_release:
+	if (viafbinfo1)
+		framebuffer_release(viafbinfo1);
+out_delete_i2c:
+	viafb_delete_i2c_buss(viaparinfo);
+out_fb_release:
+	framebuffer_release(viafbinfo);
+	return rc;
 }
 
 static void __devexit via_pci_remove(struct pci_dev *pdev)
-- 
1.7.0.1

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[RFC] Initial OLPC Viafb merge, Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 01/16] [FB] viafb: Fix various resource leaks durin ..., Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 02/16] viafb: use proper pci config API, Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 04/16] viafb: Retain GEMODE reserved bits, Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 11/16] Minimal support for viafb suspend/resume, Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 14/16] Remove cursor restore hack in viafb, Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 15/16] viafb: rework suspend/resume, Jonathan Corbet, (Thu Apr 8, 10:15 am)
[PATCH 16/16] viafb: Only suspend/resume on VX855, Jonathan Corbet, (Thu Apr 8, 10:15 am)
Re: [PATCH 01/16] [FB] viafb: Fix various resource leaks d ..., Florian Tobias Schan ..., (Thu Apr 8, 11:22 am)
Re: [PATCH 02/16] viafb: use proper pci config API, Florian Tobias Schan ..., (Thu Apr 8, 11:42 am)
Re: [PATCH 03/16] viafb: Unmap the frame buffer on initial ..., Florian Tobias Schan ..., (Thu Apr 8, 11:55 am)
Re: [PATCH 04/16] viafb: Retain GEMODE reserved bits, Florian Tobias Schan ..., (Thu Apr 8, 8:07 pm)
Re: [PATCH 05/16] viafb: Determine type of 2D engine and s ..., Florian Tobias Schan ..., (Thu Apr 8, 8:20 pm)
Re: [PATCH 06/16] viafb: complete support for VX800/VX855 ..., Florian Tobias Schan ..., (Thu Apr 8, 9:21 pm)
Re: [RFC] Initial OLPC Viafb merge, Florian Tobias Schan ..., (Thu Apr 8, 10:43 pm)
Re: [RFC] Initial OLPC Viafb merge, Jonathan Corbet, (Fri Apr 9, 11:46 am)
Re: [PATCH 02/16] viafb: use proper pci config API, Jonathan Corbet, (Fri Apr 9, 12:46 pm)
Re: [PATCH 04/16] viafb: Retain GEMODE reserved bits, Jonathan Corbet, (Fri Apr 9, 12:59 pm)
Re: [PATCH 04/16] viafb: Retain GEMODE reserved bits, Florian Tobias Schan ..., (Fri Apr 9, 1:23 pm)
Re: [PATCH 04/16] viafb: Retain GEMODE reserved bits, Jonathan Corbet, (Fri Apr 9, 1:30 pm)
Re: [PATCH 05/16] viafb: Determine type of 2D engine and s ..., Florian Tobias Schan ..., (Fri Apr 9, 1:34 pm)
Re: [PATCH 07/16] viafb: Add 1200x900 DCON/LCD panel modes ..., Florian Tobias Schan ..., (Fri Apr 9, 2:27 pm)
Re: [PATCH 08/16] viafb: Do not probe for LVDS/TMDS on OLP ..., Florian Tobias Schan ..., (Fri Apr 9, 2:40 pm)
Re: [PATCH 09/16] viafb: rework the I2C support in the VIA ..., Florian Tobias Schan ..., (Fri Apr 9, 3:07 pm)
Re: [PATCH 10/16] suppress verbose debug messages: change ..., Florian Tobias Schan ..., (Fri Apr 9, 3:09 pm)
Re: [RFC] Initial OLPC Viafb merge, Florian Tobias Schan ..., (Fri Apr 9, 4:32 pm)
Re: [RFC] Initial OLPC Viafb merge, Jonathan Corbet, (Fri Apr 9, 5:27 pm)
Re: [PATCH 08/16] viafb: Do not probe for LVDS/TMDS on OLP ..., Florian Tobias Schan ..., (Fri Apr 9, 5:42 pm)
Re: [RFC] Initial OLPC Viafb merge, Florian Tobias Schan ..., (Fri Apr 9, 6:02 pm)
Re: [PATCH 02/16] viafb: use proper pci config API, Harald Welte, (Fri Apr 9, 11:41 pm)
Re: [RFC] Initial OLPC Viafb merge, Bruno Prémont, (Sat Apr 10, 1:52 am)
Re: [RFC] Initial OLPC Viafb merge, Florian Tobias Schan ..., (Mon Apr 12, 8:03 pm)
Re: [PATCH 05/16] viafb: Determine type of 2D engine and s ..., Florian Tobias Schan ..., (Sun Apr 18, 11:05 am)
Re: [PATCH 07/16] viafb: Add 1200x900 DCON/LCD panel modes ..., Florian Tobias Schan ..., (Sun Apr 18, 11:24 am)
Re: [RFC] Initial OLPC Viafb merge, Jonathan Corbet, (Wed Apr 21, 1:37 pm)