[svn-commits] sruffell: linux/trunk r9968 - /linux/trunk/drivers/dahdi/wctdm24xxp/base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jun 2 15:03:52 CDT 2011


Author: sruffell
Date: Thu Jun  2 15:03:48 2011
New Revision: 9968

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9968
Log:
wctdm24xxp: Allow more than one outstanding read at a time.

Since every read needs to go through the complete voicebus pipeline, if
we know we're going to read multiple bytes we can queue them all up.

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

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

Modified: linux/trunk/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=9968&r1=9967&r2=9968
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctdm24xxp/base.c Thu Jun  2 15:03:48 2011
@@ -1059,6 +1059,54 @@
 	return val;
 }
 
+static int wctdm_getregs(struct wctdm *wc, struct wctdm_module *const mod,
+			 int *const addresses, const size_t count)
+{
+	int x;
+	unsigned long flags;
+	struct wctdm_cmd *cmd;
+	struct wctdm_cmd **cmds = kmalloc(sizeof(cmd) * count, GFP_KERNEL);
+
+	if (!cmds)
+		return -ENOMEM;
+
+	for (x = 0; x < count; ++x) {
+		cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+		if (!cmd) {
+			kfree(cmds);
+			return -ENOMEM;
+		}
+
+		cmd->complete = kmalloc(sizeof(*cmd->complete), GFP_KERNEL);
+		if (!cmd->complete) {
+			kfree(cmd);
+			kfree(cmds);
+			return -ENOMEM;
+		}
+
+		init_completion(cmd->complete);
+
+		cmd->cmd = CMD_RD(addresses[x]);
+
+		spin_lock_irqsave(&wc->reglock, flags);
+		list_add_tail(&cmd->node, &mod->pending_cmds);
+		spin_unlock_irqrestore(&wc->reglock, flags);
+
+		cmds[x] = cmd;
+	}
+
+	for (x = count - 1; x >= 0; --x) {
+		cmd = cmds[x];
+		wait_for_completion(cmd->complete);
+		addresses[x] = cmd->cmd & 0xff;
+		kfree(cmd->complete);
+		kfree(cmd);
+	}
+
+	kfree(cmds);
+	return 0;
+}
+
 /**
  * call with wc->reglock held and interrupts disabled.
  */
@@ -1268,10 +1316,10 @@
 	if (!wait_access(wc, mod)) {
 		wctdm_setreg(wc, mod, IAA, address);
 		if (!wait_access(wc, mod)) {
-			unsigned char data1, data2;
-			data1 = wctdm_getreg(wc, mod, IDA_LO);
-			data2 = wctdm_getreg(wc, mod, IDA_HI);
-			res = data1 | (data2 << 8);
+			int addresses[2] = {IDA_LO, IDA_HI};
+			wctdm_getregs(wc, mod, addresses,
+				      ARRAY_SIZE(addresses));
+			res = addresses[0] | (addresses[1] << 8);
 		} else
 			p = "Failed to wait inside\n";
 	} else
@@ -2191,13 +2239,14 @@
 
 static int wctdm_voicedaa_insane(struct wctdm *wc, struct wctdm_module *mod)
 {
-	int blah;
-	blah = wctdm_getreg(wc, mod, 2);
-	if (blah != 0x3)
+	int blah[] = {2, 11};
+	wctdm_getregs(wc, mod, blah, ARRAY_SIZE(blah));
+	if (blah[0] != 0x3)
 		return -2;
-	blah = wctdm_getreg(wc, mod, 11);
-	if (debug & DEBUG_CARD)
-		dev_info(&wc->vb.pdev->dev, "VoiceDAA System: %02x\n", blah & 0xf);
+	if (debug & DEBUG_CARD) {
+		dev_info(&wc->vb.pdev->dev,
+			 "VoiceDAA System: %02x\n", blah[1] & 0xf);
+	}
 	return 0;
 }
 
@@ -2777,6 +2826,7 @@
 	unsigned char r19,r9;
 	int x;
 	int fxsmode=0;
+	int addresses[NUM_CAL_REGS];
 
 #if 0 /* TODO */
 	if (wc->mods[mod->card & 0xfc].type == QRV)
@@ -2893,7 +2943,10 @@
 
 		/* Save calibration vectors */
 		for (x = 0; x < NUM_CAL_REGS; x++)
-			fxs->calregs.vals[x] = wctdm_getreg(wc, mod, 96 + x);
+			addresses[x] = 96 + x;
+		wctdm_getregs(wc, mod, addresses, ARRAY_SIZE(addresses));
+		for (x = 0; x < NUM_CAL_REGS; x++)
+			fxs->calregs.vals[x] = addresses[x];
 #endif
 
 	} else {




More information about the svn-commits mailing list