[svn-commits] sruffell: branch linux/sruffell/wctdm24xxp-cmdlist r9856 - in /linux/team/sru...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Mar 16 16:40:31 CDT 2011


Author: sruffell
Date: Wed Mar 16 16:40:27 2011
New Revision: 9856

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9856
Log:
wctdm24xxp: Hold the reglock longer in the interrupt handler.

Cuts down on the overhead of constantly saving and restoring the
interrupt registers.

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

Modified:
    linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/voicebus/GpakCust.h
    linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c

Modified: linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/voicebus/GpakCust.h
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/voicebus/GpakCust.h?view=diff&rev=9856&r1=9855&r2=9856
==============================================================================
--- linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/voicebus/GpakCust.h (original)
+++ linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/voicebus/GpakCust.h Wed Mar 16 16:40:27 2011
@@ -154,38 +154,38 @@
 struct GpakEcanParms;
 void vpmadt032_get_default_parameters(struct GpakEcanParms *p);
 
-/* If there is a command ready to go to the VPMADT032, return it, otherwise NULL */
+/* If there is a command ready to go to the VPMADT032, return it, otherwise
+ * NULL. Call with local interrupts disabled.  */
 static inline struct vpmadt032_cmd *vpmadt032_get_ready_cmd(struct vpmadt032 *vpm)
 {
-	unsigned long flags;
 	struct vpmadt032_cmd *cmd;
 
-	spin_lock_irqsave(&vpm->list_lock, flags);
+	spin_lock(&vpm->list_lock);
 	if (list_empty(&vpm->pending_cmds)) {
-		spin_unlock_irqrestore(&vpm->list_lock, flags);
+		spin_unlock(&vpm->list_lock);
 		return NULL;
 	}
 	cmd = list_entry(vpm->pending_cmds.next, struct vpmadt032_cmd, node);
 	list_move_tail(&cmd->node, &vpm->active_cmds);
-	spin_unlock_irqrestore(&vpm->list_lock, flags);
+	spin_unlock(&vpm->list_lock);
 	return cmd;
 }
 
+/**
+ * call with local interrupts disabled.
+ */
 static inline void vpmadt032_resend(struct vpmadt032 *vpm)
 {
-	unsigned long flags;
 	struct vpmadt032_cmd *cmd, *temp;
-
-	BUG_ON(!vpm);
 
 	/* By moving the commands back to the pending list, they will be
 	 * transmitted when room is available */
-	spin_lock_irqsave(&vpm->list_lock, flags);
+	spin_lock(&vpm->list_lock);
 	list_for_each_entry_safe(cmd, temp, &vpm->active_cmds, node) {
 		cmd->desc &= ~(__VPM150M_TX);
 		list_move_tail(&cmd->node, &vpm->pending_cmds);
 	}
-	spin_unlock_irqrestore(&vpm->list_lock, flags);
+	spin_unlock(&vpm->list_lock);
 }
 
 

Modified: linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=9856&r1=9855&r2=9856
==============================================================================
--- linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c Wed Mar 16 16:40:27 2011
@@ -474,9 +474,8 @@
         return a != b;
 }
 
-static inline void cmd_dequeue_vpmadt032(struct wctdm *wc, u8 *eframe)
-{
-	unsigned long flags;
+static void cmd_dequeue_vpmadt032(struct wctdm *wc, u8 *eframe)
+{
 	struct vpmadt032_cmd *curcmd = NULL;
 	struct vpmadt032 *vpmadt032 = wc->vpmadt032;
 	int x;
@@ -488,7 +487,6 @@
 	if (test_bit(VPM150M_HPIRESET, &vpmadt032->control)) {
 		if (debug & DEBUG_ECHOCAN)
 			dev_info(&wc->vb.pdev->dev, "HW Resetting VPMADT032...\n");
-		spin_lock_irqsave(&wc->reglock, flags);
 		for (x = 24; x < 28; x++) {
 			if (x == 24) {
 				if (test_and_clear_bit(VPM150M_HPIRESET,
@@ -503,7 +501,6 @@
 			eframe[CMD_BYTE(x, 1, 0)] = 0;
 			eframe[CMD_BYTE(x, 2, 0)] = 0x00;
 		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
 		return;
 	}
 
@@ -587,10 +584,9 @@
 	}
 }
 
-static inline void cmd_dequeue(struct wctdm *wc, unsigned char *eframe, int card, int pos)
+static void _cmd_dequeue(struct wctdm *wc, u8 *eframe, int card, int pos)
 {
 	struct wctdm_module *const mod = &wc->mods[card];
-	unsigned long flags;
 	unsigned int curcmd=0;
 	int x;
 	int subaddr = card & 0x3;
@@ -604,7 +600,6 @@
 
 	/* Skip audio */
 	eframe += 24;
-	spin_lock_irqsave(&wc->reglock, flags);
 	/* Search for something waiting to transmit */
 	if (pos) {
 		for (x = 0; x < MAX_COMMANDS; x++) {
@@ -619,25 +614,36 @@
 
 	if (!curcmd) {
 		/* If nothing else, use filler */
-		if (mod->type == FXS)
+		switch (mod->type) {
+		case FXS:
 			curcmd = CMD_RD(LINE_STATE);
-		else if (mod->type == FXO)
+			break;
+		case FXO:
 			curcmd = CMD_RD(12);
-		else if (mod->type == BRI)
+			break;
+		case BRI:
 			curcmd = 0x101010;
-		else if (mod->type == QRV)
+			break;
+		case QRV:
 			curcmd = CMD_RD(3);
-	}
-
-	if (mod->type == FXS) {
+			break;
+		default:
+			break;
+		}
+	}
+
+	switch (mod->type) {
+	case FXS:
 		eframe[CMD_BYTE(card, 0, mod->altcs)] = (1 << (subaddr));
 		if (curcmd & __CMD_WR)
 			eframe[CMD_BYTE(card, 1, mod->altcs)] = (curcmd >> 8) & 0x7f;
 		else
 			eframe[CMD_BYTE(card, 1, mod->altcs)] = 0x80 | ((curcmd >> 8) & 0x7f);
 		eframe[CMD_BYTE(card, 2, mod->altcs)] = curcmd & 0xff;
-
-	} else if (mod->type == FXO) {
+		break;
+
+	case FXO:
+	{
 		static const int FXO_ADDRS[4] = { 0x00, 0x08, 0x04, 0x0c };
 		int idx = CMD_BYTE(card, 0, mod->altcs);
 		if (curcmd & __CMD_WR)
@@ -646,8 +652,9 @@
 			eframe[idx] = 0x60 | FXO_ADDRS[subaddr];
 		eframe[CMD_BYTE(card, 1, mod->altcs)] = (curcmd >> 8) & 0xff;
 		eframe[CMD_BYTE(card, 2, mod->altcs)] = curcmd & 0xff;
-
-	} else if (mod->type == FXSINIT) {
+		break;
+	}
+	case FXSINIT:
 		/* Special case, we initialize the FXS's into the three-byte command mode then
 		   switch to the regular mode.  To send it into thee byte mode, treat the path as
 		   6 two-byte commands and in the last one we initialize register 0 to 0x80. All modules
@@ -658,18 +665,18 @@
 			eframe[CMD_BYTE(card, 2, mod->altcs)] = 0x80;
 		else
 			eframe[CMD_BYTE(card, 2, mod->altcs)] = 0x00;
-
-	} else if (mod->type == BRI) {
-
+		break;
+
+	case BRI:
 		if (unlikely((curcmd != 0x101010) && (curcmd & 0x1010) == 0x1010)) /* b400m CPLD */
 			eframe[CMD_BYTE(card, 0, 0)] = 0x55;
 		else /* xhfc */
 			eframe[CMD_BYTE(card, 0, 0)] = 0x10;
 		eframe[CMD_BYTE(card, 1, 0)] = (curcmd >> 8) & 0xff;
 		eframe[CMD_BYTE(card, 2, 0)] = curcmd & 0xff;
-
-	} else if (mod->type == QRV) {
- 
+		break;
+
+	case QRV:
 		eframe[CMD_BYTE(card, 0, mod->altcs)] = 0x00;
 		if (!curcmd) {
 			eframe[CMD_BYTE(card, 1, mod->altcs)] = 0x00;
@@ -681,18 +688,19 @@
 				eframe[CMD_BYTE(card, 1, mod->altcs)] = 0xc0 | ((curcmd >> 8) & 0x3f);
 			eframe[CMD_BYTE(card, 2, mod->altcs)] = curcmd & 0xff;
 		}
-	} else if (mod->type == NONE) {
+		break;
+
+	case NONE:
 		eframe[CMD_BYTE(card, 0, mod->altcs)] = 0x10;
 		eframe[CMD_BYTE(card, 1, mod->altcs)] = 0x10;
 		eframe[CMD_BYTE(card, 2, mod->altcs)] = 0x10;
-	}
-	spin_unlock_irqrestore(&wc->reglock, flags);
+		break;
+	}
 }
 
 static inline void cmd_decipher_vpmadt032(struct wctdm *wc, const u8 *eframe)
 {
-	unsigned long flags;
-	struct vpmadt032 *vpm = wc->vpmadt032;
+	struct vpmadt032 *const vpm = wc->vpmadt032;
 	struct vpmadt032_cmd *cmd;
 
 	BUG_ON(!vpm);
@@ -703,18 +711,17 @@
 		return;
 	}
 
-	spin_lock_irqsave(&vpm->list_lock, flags);
+	spin_lock(&vpm->list_lock);
 	cmd = list_entry(vpm->active_cmds.next, struct vpmadt032_cmd, node);
 	if (wc->rxident == cmd->txident) {
 		list_del_init(&cmd->node);
 	} else {
 		cmd = NULL;
 	}
-	spin_unlock_irqrestore(&vpm->list_lock, flags);
-
-	if (!cmd) {
+	spin_unlock(&vpm->list_lock);
+
+	if (!cmd)
 		return;
-	}
 
 	/* Skip audio */
 	eframe += 24;
@@ -730,10 +737,12 @@
 	}
 }
 
-static inline void cmd_decipher(struct wctdm *wc, const u8 *eframe, int card)
+/**
+ * Call with the reglock held and local interrupts disabled
+ */
+static void _cmd_decipher(struct wctdm *wc, const u8 *eframe, int card)
 {
 	struct wctdm_module *const mod = &wc->mods[card];
-	unsigned long flags;
 	unsigned char ident;
 	int x;
 
@@ -743,7 +752,6 @@
 
 	/* Skip audio */
 	eframe += 24;
-	spin_lock_irqsave(&wc->reglock, flags);
 
 	/* Search for any pending results */
 	for (x=0;x<MAX_COMMANDS;x++) {
@@ -767,7 +775,6 @@
 			}
 		}
 	}
-	spin_unlock_irqrestore(&wc->reglock, flags);
 }
 
 static void cmd_checkisr(struct wctdm *wc, struct wctdm_module *const mod)
@@ -857,7 +864,8 @@
 
 static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char *sframe)
 {
-	int x,y;
+	unsigned long flags;
+	int x, y;
 	struct dahdi_span *s;
 	unsigned char *eframe = sframe;
 
@@ -879,6 +887,7 @@
 #endif
 	}
 
+	spin_lock_irqsave(&wc->reglock, flags);
 	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
 		/* Send a sample, as a 32-bit word */
 
@@ -887,12 +896,11 @@
 		 * BRI modules have a different number of TDM channels than
 		 * installed modules. */
 		for (y = 0; y < wc->avchannels; y++) {
-			if (!x && y < wc->mods_per_board) {
+			if (!x && y < wc->mods_per_board)
 				cmd_checkisr(wc, &wc->mods[y]);
-			}
 
 			if (y < wc->mods_per_board)
-				cmd_dequeue(wc, eframe, y, x);
+				_cmd_dequeue(wc, eframe, y, x);
 		}
 
 		if (wc->vpmadt032) {
@@ -909,6 +917,7 @@
 		}
 		eframe += (EFRAME_SIZE + EFRAME_GAP);
 	}
+	spin_unlock_irqrestore(&wc->reglock, flags);
 }
 
 static bool
@@ -1009,12 +1018,13 @@
 	return val;
 }
 
-static inline void cmd_retransmit(struct wctdm *wc)
+/**
+ * call with wc->reglock held and interrupts disabled.
+ */
+static void cmd_retransmit(struct wctdm *wc)
 {
 	int x,y;
-	unsigned long flags;
 	/* Force retransmissions */
-	spin_lock_irqsave(&wc->reglock, flags);
 	for (x=0;x<MAX_COMMANDS;x++) {
 		for (y = 0; y < wc->mods_per_board; y++) {
 			struct wctdm_module *const mod = &wc->mods[y];
@@ -1024,7 +1034,6 @@
 				mod->cmdq.cmds[x] &= ~(__CMD_TX | (0xff << 24));
 		}
 	}
-	spin_unlock_irqrestore(&wc->reglock, flags);
 #ifdef VPM_SUPPORT
 	if (wc->vpmadt032)
 		vpmadt032_resend(wc->vpmadt032);
@@ -1085,8 +1094,9 @@
 
 static inline void wctdm_receiveprep(struct wctdm *wc, const u8 *sframe)
 {
-	int x,y;
-	bool irqmiss = 0;
+	unsigned long flags;
+	int x, y;
+	bool irqmiss = false;
 	unsigned char expected;
 	const u8 *eframe = sframe;
 
@@ -1096,27 +1106,25 @@
 	if (likely(wc->initialized))
 		extract_tdm_data(wc, sframe);
 
+	spin_lock_irqsave(&wc->reglock, flags);
 	for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
 		if (x < DAHDI_CHUNKSIZE - 1) {
-			expected = wc->rxident+1;
+			expected = wc->rxident + 1;
 			wc->rxident = eframe[EFRAME_SIZE + 1];
 			if (wc->rxident != expected) {
-				irqmiss = 1;
+				irqmiss = true;
 				cmd_retransmit(wc);
 			}
 		}
-		for (y = 0; y < wc->avchannels; y++) {
-			cmd_decipher(wc, eframe, y);
-		}
-
-		if (wc->vpmadt032) {
+
+		for (y = 0; y < wc->avchannels; y++)
+			_cmd_decipher(wc, eframe, y);
+		if (wc->vpmadt032)
 			cmd_decipher_vpmadt032(wc, eframe);
-		} else if (wc->vpmadt032) {
-			cmd_decipher_vpmadt032(wc, eframe);
-		}
 
 		eframe += (EFRAME_SIZE + EFRAME_GAP);
 	}
+	spin_unlock_irqrestore(&wc->reglock, flags);
 
 	/* XXX We're wasting 8 taps.  We should get closer :( */
 	if (likely(wc->initialized)) {




More information about the svn-commits mailing list