[svn-commits] sruffell: linux/trunk r10248 - /linux/trunk/drivers/dahdi/wct4xxp/base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Oct 20 15:53:21 CDT 2011


Author: sruffell
Date: Thu Oct 20 15:53:18 2011
New Revision: 10248

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10248
Log:
wct4xxp: Atomically perform some read/modify/write operations

There are read/modify/write operations on the framer that were not
protected by any locks. While I didn't notice any code paths that would
result in simultaneous accesses to these registers, this change will
hopefully save someone else some time in the future verifying that the
accesses are safe. A side effect is that the reglock is acquired only
once for each read/modify/write cycle as opposed to twice previously.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Acked-by: Michael Spiceland <mspiceland at digium.com>
Acked-by: Russ Meyerriecks <rmeyerriecks at digium.com>

Modified:
    linux/trunk/drivers/dahdi/wct4xxp/base.c

Modified: linux/trunk/drivers/dahdi/wct4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wct4xxp/base.c?view=diff&rev=10248&r1=10247&r2=10248
==============================================================================
--- linux/trunk/drivers/dahdi/wct4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wct4xxp/base.c Thu Oct 20 15:53:18 2011
@@ -808,6 +808,7 @@
 {
 	struct t4_span *t = wc->tspans[span];
 	unsigned char imr0, imr1, mode;
+	unsigned long flags;
 	int i = 0;
 
 	if (debug & DEBUG_FRAMER)
@@ -820,19 +821,21 @@
 		t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00);
 	}
 
-	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
-	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
+	spin_lock_irqsave(&wc->reglock, flags);
+	imr0 = __t4_framer_in(wc, span, FRMR_IMR0);
+	imr1 = __t4_framer_in(wc, span, FRMR_IMR1);
 
 	/* Disable HDLC interrupts */
 	imr0 |= HDLC_IMR0_MASK;
-	t4_framer_out(wc, span, FRMR_IMR0, imr0);
+	__t4_framer_out(wc, span, FRMR_IMR0, imr0);
 
 	imr1 |= HDLC_IMR1_MASK;
-	t4_framer_out(wc, span, FRMR_IMR1, imr1);
-
-	mode = t4_framer_in(wc, span, FRMR_MODE);
+	__t4_framer_out(wc, span, FRMR_IMR1, imr1);
+
+	mode = __t4_framer_in(wc, span, FRMR_MODE);
 	mode &= ~FRMR_MODE_HRAC;
-	t4_framer_out(wc, span, FRMR_MODE, mode);
+	__t4_framer_out(wc, span, FRMR_MODE, mode);
+	spin_unlock_irqrestore(&wc->reglock, flags);
 
 	t->sigactive = 0;
 }
@@ -879,29 +882,33 @@
 
 	mode |= FRMR_MODE_HRAC;
 
+	spin_lock_irqsave(&wc->reglock, flags);
+
 	/* Make sure we're in the right mode */
-	t4_framer_out(wc, span, FRMR_MODE, mode);
-	t4_framer_out(wc, span, FRMR_TSEO, 0x00);
-	t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode);
+	__t4_framer_out(wc, span, FRMR_MODE, mode);
+	__t4_framer_out(wc, span, FRMR_TSEO, 0x00);
+	__t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode);
 
 	/* Set the interframe gaps, etc */
-	t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
-
-	t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
+	__t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
+
+	__t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
 	
 	/* Set up the time slot that we want to tx/rx on */
-	t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
-	t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
-
-	imr0 = t4_framer_in(wc, span, FRMR_IMR0);
-	imr1 = t4_framer_in(wc, span, FRMR_IMR1);
+	__t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
+	__t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
+
+	imr0 = __t4_framer_in(wc, span, FRMR_IMR0);
+	imr1 = __t4_framer_in(wc, span, FRMR_IMR1);
 
 	/* Enable our interrupts again */
 	imr0 &= ~HDLC_IMR0_MASK;
-	t4_framer_out(wc, span, FRMR_IMR0, imr0);
+	__t4_framer_out(wc, span, FRMR_IMR0, imr0);
 
 	imr1 &= ~HDLC_IMR1_MASK;
-	t4_framer_out(wc, span, FRMR_IMR1, imr1);
+	__t4_framer_out(wc, span, FRMR_IMR1, imr1);
+
+	spin_unlock_irqrestore(&wc->reglock, flags);
 
 	/* Reset the signaling controller */
 	t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
@@ -1789,6 +1796,7 @@
 	int gen2;
 	struct t4_span *ts;
 	unsigned int reg;
+	unsigned long flags;
 	
 	gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
 	for (x = 0; x < wc->numspans; x++) {
@@ -1861,11 +1869,13 @@
 		ts->alarmcheck_time = jiffies + msecs_to_jiffies(250);
 
 		/* Enable 1sec timer interrupt */
-		reg = t4_framer_in(wc, x, FMR1_T);
-		t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
+		spin_lock_irqsave(&wc->reglock, flags);
+		reg = __t4_framer_in(wc, x, FMR1_T);
+		__t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
 
 		/* Enable Errored Second interrupt */
-		t4_framer_out(wc, x, ESM, 0);
+		__t4_framer_out(wc, x, ESM, 0);
+		spin_unlock_irqrestore(&wc->reglock, flags);
 
 		t4_reset_counters(&ts->span);
 
@@ -3924,6 +3934,7 @@
 {
 	int x;
 	unsigned int regval;
+	unsigned long flags;
 
 	if (t4_pci_in(wc, WC_VERSION) >= 0xc01a0165) {
 		wc->tspans[0]->spanflags |= FLAG_OCTOPT;
@@ -3941,10 +3952,13 @@
 	if (t4_framer_in(wc, 0, 0x4a) != 0x05)
 		dev_info(&wc->dev->dev, "WARNING: FALC framer not intialized "
 				"in compatibility mode.\n");
-	regval = t4_framer_in(wc, 0 ,0xd6);
+	spin_lock_irqsave(&wc->reglock, flags);
+	regval = __t4_framer_in(wc, 0, 0xd6);
 	regval |= (1 << 5); /* set COMP_DIS*/
-	t4_framer_out(wc, 0, 0xd6, regval);
-	regval = t4_framer_in(wc, 0, 0x4a);
+	__t4_framer_out(wc, 0, 0xd6, regval);
+	regval = __t4_framer_in(wc, 0, 0x4a);
+	spin_unlock_irqrestore(&wc->reglock, flags);
+
 	if (regval == 0x05)
 		dev_info(&wc->dev->dev, "FALC Framer Version: 2.1 or "
 				"earlier\n");
@@ -3954,11 +3968,14 @@
 	} else
 		dev_info(&wc->dev->dev, "FALC Framer Version: Unknown "
 				"(VSTR = 0x%02x)\n", regval);
-	regval = t4_framer_in(wc, 0 ,0xd6);
+
+	spin_lock_irqsave(&wc->reglock, flags);
+	regval = __t4_framer_in(wc, 0, 0xd6);
 	regval &= ~(1 << 5); /* clear COMP_DIS*/
-	t4_framer_out(wc, 0, 0xd6, regval);
-	
-	t4_framer_out(wc, 0, 0x4a, 0xaa);
+	__t4_framer_out(wc, 0, 0xd6, regval);
+	__t4_framer_out(wc, 0, 0x4a, 0xaa);
+	spin_unlock_irqrestore(&wc->reglock, flags);
+
 	if (debug) {
 		dev_info(&wc->dev->dev, "Board ID: %02x\n", wc->order);
 		for (x = 0; x < 11; x++) {




More information about the svn-commits mailing list