[svn-commits] tzafrir: linux/trunk r10410 - /linux/trunk/drivers/dahdi/xpp/xbus-core.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jan 5 11:35:21 CST 2012


Author: tzafrir
Date: Thu Jan  5 11:35:17 2012
New Revision: 10410

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10410
Log:
xpp: handle failures during dahdi_register_device()

* If dahdi_register_device() failed, not all resources were freed.
  When dahdi_unregister_device() was called later (during driver
  removal) a panic was caused.

* Add proper error handling for possible failures in
  xbus_register_dahdi_device():
  - new xbus_free_ddev() safely free an xbus->ddev
  - This is called from all failures points.
  - It is also called from xbus_unregister_dahdi_device()

Signed-off-by: Oron Peled <oron.peled at xorcom.com>
Acked-By: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

Modified:
    linux/trunk/drivers/dahdi/xpp/xbus-core.c

Modified: linux/trunk/drivers/dahdi/xpp/xbus-core.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/xbus-core.c?view=diff&rev=10410&r1=10409&r2=10410
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/xbus-core.c (original)
+++ linux/trunk/drivers/dahdi/xpp/xbus-core.c Thu Jan  5 11:35:17 2012
@@ -900,18 +900,37 @@
 	return xbus->ddev && xbus->ddev->dev.parent;
 }
 
+static void xbus_free_ddev(xbus_t *xbus)
+{
+	if (!xbus->ddev)
+		return;
+	if (xbus->ddev->devicetype)
+		kfree(xbus->ddev->devicetype);
+	xbus->ddev->devicetype = NULL;
+	xbus->ddev->location = NULL;
+	xbus->ddev->hardware_id = NULL;
+	dahdi_free_device(xbus->ddev);
+	xbus->ddev = NULL;
+}
+
 int xbus_register_dahdi_device(xbus_t *xbus)
 {
-	int	i;
-	int	offset = 0;
+	int i;
+	int offset = 0;
+	int ret;
 
 	XBUS_DBG(DEVICES, xbus, "Entering %s\n", __func__);
 	if (xbus_is_registered(xbus)) {
 		XBUS_ERR(xbus, "Already registered to DAHDI\n");
 		WARN_ON(1);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err;
 	}
 	xbus->ddev = dahdi_create_device();
+	if (!xbus->ddev) {
+		ret = -ENOMEM;
+		goto err;
+	}
 	/*
 	 * This actually describe the dahdi_spaninfo version 3
 	 * A bunch of unrelated data exported via a modified ioctl()
@@ -926,8 +945,10 @@
 	 * OK, let's add to the kernel more useless info.
 	 */
 	xbus->ddev->devicetype = kasprintf(GFP_KERNEL, "Astribank2");
-	if (!xbus->ddev->devicetype)
-		return -ENOMEM;
+	if (!xbus->ddev->devicetype) {
+		ret = -ENOMEM;
+		goto err;
+	}
 
 	/*
 	 * location is the only usefull new data item.
@@ -952,7 +973,8 @@
 	}
 	if (dahdi_register_device(xbus->ddev, &xbus->astribank)) {
 		XBUS_ERR(xbus, "Failed to dahdi_register_device()\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err;
 	}
 	for (i = 0; i < MAX_XPDS; i++) {
 		xpd_t *xpd = xpd_of(xbus, i);
@@ -962,6 +984,9 @@
 		}
 	}
 	return 0;
+err:
+	xbus_free_ddev(xbus);
+	return ret;
 }
 
 void xbus_unregister_dahdi_device(xbus_t *xbus)
@@ -976,12 +1001,7 @@
 	if (xbus->ddev) {
 		dahdi_unregister_device(xbus->ddev);
 		XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n", __func__);
-		kfree(xbus->ddev->devicetype);
-		xbus->ddev->devicetype = NULL;
-		xbus->ddev->location = NULL;
-		xbus->ddev->hardware_id = NULL;
-		dahdi_free_device(xbus->ddev);
-		xbus->ddev = NULL;
+		xbus_free_ddev(xbus);
 	}
 	for(i = 0; i < MAX_XPDS; i++) {
 		xpd_t *xpd = xpd_of(xbus, i);




More information about the svn-commits mailing list