[svn-commits] sruffell: linux/trunk r9332 - /linux/trunk/drivers/dahdi/voicebus/GpakCust.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Sep 16 13:57:43 CDT 2010


Author: sruffell
Date: Thu Sep 16 13:57:39 2010
New Revision: 9332

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9332
Log:
vpmadt032: Remove potential endless waits when resetting.

It is possible to softlock if the board stops delivering interrupts in
the middle of a reset.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Modified:
    linux/trunk/drivers/dahdi/voicebus/GpakCust.c

Modified: linux/trunk/drivers/dahdi/voicebus/GpakCust.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/voicebus/GpakCust.c?view=diff&rev=9332&r1=9331&r2=9332
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/GpakCust.c (original)
+++ linux/trunk/drivers/dahdi/voicebus/GpakCust.c Thu Sep 16 13:57:39 2010
@@ -564,27 +564,45 @@
 	int res;
 	gpakPingDspStat_t pingstatus;
 	u16 version;
+	unsigned long stoptime;
+	struct device *const dev = &vpm->vb->pdev->dev;
 
 	might_sleep();
 
 	set_bit(VPM150M_HPIRESET, &vpm->control);
 	msleep(2000);
-	while (test_bit(VPM150M_HPIRESET, &vpm->control))
+	/* It should never take longer than 5 seconds. */
+	stoptime = jiffies + 3*HZ;
+	while (test_bit(VPM150M_HPIRESET, &vpm->control) &&
+	       time_before(jiffies, stoptime))
 		msleep(1);
+
+	if (time_after(jiffies, stoptime)) {
+		dev_dbg(dev, "Detected failure to clear HPIRESET.\n");
+		return -EIO;
+	}
 
 	/* Set us up to page 0 */
 	vpmadt032_setpage(vpm, 0);
 
 	res = vpmadtreg_loadfirmware(vpm->vb);
 	if (res) {
-		dev_info(&vpm->vb->pdev->dev, "Failed to load the firmware.\n");
+		dev_err(dev, "Failed to load VPMADT032 firmware.\n");
 		return res;
 	}
 	vpm->curpage = -1;
 
+	stoptime = jiffies + 3*HZ;
 	set_bit(VPM150M_SWRESET, &vpm->control);
-	while (test_bit(VPM150M_SWRESET, &vpm->control))
+	while (test_bit(VPM150M_SWRESET, &vpm->control) &&
+	       time_before(jiffies, stoptime))
 		msleep(1);
+
+	if (time_after(jiffies, stoptime)) {
+		dev_dbg(dev, "Detected failure to clear SWRESET.\n");
+		return -EIO;
+	}
+
 
 	/* Set us up to page 0 */
 	pingstatus = gpakPingDsp(vpm->dspid, &version);
@@ -606,6 +624,8 @@
 	int i;
 	u16 reg;
 	int res = -EFAULT;
+	unsigned long stoptime;
+	struct device *dev;
 	gpakPingDspStat_t pingstatus;
 
 	BUG_ON(!vpm->setchanconfig_from_state);
@@ -615,6 +635,8 @@
 	vpm->vb = vb;
 
 	might_sleep();
+
+	dev = &vpm->vb->pdev->dev;
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
 	INIT_WORK(&vpm->work, vpmadt032_bh, vpm);
@@ -622,7 +644,7 @@
 	INIT_WORK(&vpm->work, vpmadt032_bh);
 #endif
 	if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
-		dev_info(&vpm->vb->pdev->dev, "VPMADT032 Testing page access: ");
+		dev_info(dev, "VPMADT032 Testing page access: ");
 
 	for (i = 0; i < 0xf; i++) {
 		int x;
@@ -630,8 +652,12 @@
 			vpmadt032_setpage(vpm, i);
 			reg = vpmadt032_getpage(vpm);
 			if (reg != i) {
-				if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
-					dev_info(&vpm->vb->pdev->dev, "Failed: Sent %x != %x VPMADT032 Failed HI page test\n", i, reg);
+				if (vpm->options.debug &
+				    DEBUG_VPMADT032_ECHOCAN) {
+					dev_err(dev, "Failed: Sent %x != %x " \
+						"VPMADT032 Failed HI page " \
+						"test\n", i, reg);
+				}
 				res = -ENODEV;
 				goto failed_exit;
 			}
@@ -641,9 +667,17 @@
 	if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
 		dev_info(&vpm->vb->pdev->dev, "Passed\n");
 
+	stoptime = jiffies + 3*HZ;
 	set_bit(VPM150M_HPIRESET, &vpm->control);
-	while (test_bit(VPM150M_HPIRESET, &vpm->control))
+	while (test_bit(VPM150M_HPIRESET, &vpm->control) &&
+	       time_before(jiffies, stoptime))
 		msleep(1);
+
+	if (time_after(jiffies, stoptime)) {
+		dev_dbg(dev, "Detected failure to clear HPIRESET.\n");
+		res = -EIO;
+		goto failed_exit;
+	}
 	msleep(250);
 
 	/* Set us up to page 0 */
@@ -666,9 +700,17 @@
 	if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
 		printk(KERN_CONT "Passed\n");
 
+	stoptime = jiffies + 3*HZ;
 	set_bit(VPM150M_HPIRESET, &vpm->control);
-	while (test_bit(VPM150M_HPIRESET, &vpm->control))
+	while (test_bit(VPM150M_HPIRESET, &vpm->control) &&
+	       time_before(jiffies, stoptime))
 		msleep(1);
+
+	if (time_after(jiffies, stoptime)) {
+		dev_dbg(dev, "Detected failure to clear SWRESET.\n");
+		res = -EIO;
+		goto failed_exit;
+	}
 
 	res = vpmadtreg_loadfirmware(vb);
 	if (res) {
@@ -678,9 +720,18 @@
 	vpm->curpage = -1;
 
 	dev_info(&vb->pdev->dev, "Booting VPMADT032\n");
+
+	stoptime = jiffies + 3*HZ;
 	set_bit(VPM150M_SWRESET, &vpm->control);
-	while (test_bit(VPM150M_SWRESET, &vpm->control))
+	while (test_bit(VPM150M_SWRESET, &vpm->control) &&
+	       time_before(jiffies, stoptime))
 		msleep(1);
+
+	if (time_after(jiffies, stoptime)) {
+		dev_dbg(dev, "Detected failure to clear SWRESET.\n");
+		res = -EIO;
+		goto failed_exit;
+	}
 
 	pingstatus = gpakPingDsp(vpm->dspid, &vpm->version);
 




More information about the svn-commits mailing list