Sophie

Sophie

distrib > Mageia > 3 > i586 > media > core-release-src > by-pkgid > 8abaca718808f5de8d4ce0a27c7c282f > files > 13

dahdi-2.6.1-2.mga3.src.rpm

--- dahdi-linux-2.6.1/drivers/dahdi/wcb4xxp/base.c	2012-04-05 18:22:41.000000000 +0200
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/wcb4xxp/base.c	2013-01-25 20:25:36.000000000 +0100
@@ -1249,7 +1249,8 @@ static char *hfc_decode_st_state(struct
 			"?", "?", "?", "?", "?", "?", "?", "?" }
 	};
 
-	if (!(str = kmalloc(256, GFP_KERNEL))) {
+	str = kmalloc(256, GFP_ATOMIC);
+	if (!str) {
 		dev_warn(&b4->pdev->dev, "could not allocate mem for ST state decode string!\n");
 		return NULL;
 	}
diff -Naurp dahdi-linux-2.6.1/drivers/dahdi/wct4xxp/base.c dahdi-linux-2.6.2-rc1/drivers/dahdi/wct4xxp/base.c
--- dahdi-linux-2.6.1/drivers/dahdi/wct4xxp/base.c	2012-03-22 19:36:14.000000000 +0100
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/wct4xxp/base.c	2013-01-25 20:25:36.000000000 +0100
@@ -1239,9 +1239,11 @@ static int t4_ioctl(struct dahdi_chan *c
 		else
 			clear_bit(chan->chanpos - 1, &ts->dtmfmutemask);
 
-		channel = (chan->chanpos) << 3;
-		if (!has_e1_span(wc))
-			channel += (4 << 3);
+		channel = has_e1_span(wc) ? chan->chanpos : chan->chanpos + 4;
+		if (is_octal(wc))
+			channel = channel << 3;
+		else
+			channel = channel << 2;
 		channel |= chan->span->offset;
 		vpm450m_setdtmf(wc->vpm, channel, j & DAHDI_TONEDETECT_ON,
 				j & DAHDI_TONEDETECT_MUTE);
@@ -2037,7 +2039,7 @@ static void t4_span_assigned(struct dahd
 	/* We use this to make sure all the spans are assigned before
 	 * running the serial setup. */
 	list_for_each_entry(pos, &wc->ddev->spans, device_node) {
-		if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags))
+		if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &pos->flags))
 			++unassigned_spans;
 	}
 
@@ -2093,6 +2095,8 @@ static int t4_alloc_channels(struct t4 *
 	for (i = 0; i < ARRAY_SIZE(ts->chans); ++i) {
 		kfree(ts->chans[i]);
 		kfree(ts->ec[i]);
+		ts->chans[i] = NULL;
+		ts->ec[i] = NULL;
 	}
 
 	ts->linemode = linemode;
diff -Naurp dahdi-linux-2.6.1/drivers/dahdi/wctdm24xxp/base.c dahdi-linux-2.6.2-rc1/drivers/dahdi/wctdm24xxp/base.c
--- dahdi-linux-2.6.1/drivers/dahdi/wctdm24xxp/base.c	2012-03-29 17:28:43.000000000 +0200
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/wctdm24xxp/base.c	2013-01-25 20:25:36.000000000 +0100
@@ -1833,19 +1833,22 @@ static void wctdm_qrvdri_check_hook(stru
 static inline bool is_fxo_ringing(const struct fxo *const fxo)
 {
 	return ((fxo->hook_ring_shadow & 0x60) &&
-		(fxo->battery_state == BATTERY_PRESENT));
+		((fxo->battery_state == BATTERY_PRESENT) ||
+		 (fxo->battery_state == BATTERY_DEBOUNCING_LOST)));
 }
 
 static inline bool is_fxo_ringing_positive(const struct fxo *const fxo)
 {
 	return (((fxo->hook_ring_shadow & 0x60) == 0x20) &&
-		(fxo->battery_state == BATTERY_PRESENT));
+		((fxo->battery_state == BATTERY_PRESENT) ||
+		 (fxo->battery_state == BATTERY_DEBOUNCING_LOST)));
 }
 
 static inline bool is_fxo_ringing_negative(const struct fxo *const fxo)
 {
 	return (((fxo->hook_ring_shadow & 0x60) == 0x40) &&
-		(fxo->battery_state == BATTERY_PRESENT));
+		((fxo->battery_state == BATTERY_PRESENT) ||
+		 (fxo->battery_state == BATTERY_DEBOUNCING_LOST)));
 }
 
 static inline void set_ring(struct fxo *fxo, enum ring_detector_state new)
@@ -1856,19 +1859,21 @@ static inline void set_ring(struct fxo *
 static void wctdm_fxo_ring_detect(struct wctdm *wc, struct wctdm_module *mod)
 {
 	struct fxo *const fxo = &mod->mod.fxo;
+	static const unsigned int POLARITY_CHANGES_NEEDED = 2;
 
 	/* Look for ring status bits (Ring Detect Signal Negative and Ring
-	 * Detect Signal Positive) to transition back and forth some number of
-	 * times to indicate that a ring is occurring.  Provide some number of
-	 * samples to allow for the transitions to occur before giving up.
-	 * NOTE: neon mwi voltages will trigger one of these bits to go active
-	 * but not to have transitions between the two bits (i.e. no negative
-	 * to positive or positive to negative traversals) */
+	 * Detect Signal Positive) to transition back and forth
+	 * POLARITY_CHANGES_NEEDED times to indicate that a ring is occurring.
+	 * Provide some number of samples to allow for the transitions to occur
+	 * before giving up.  NOTE: neon mwi voltages will trigger one of these
+	 * bits to go active but not to have transitions between the two bits
+	 * (i.e. no negative to positive or positive to negative traversals) */
 
 	switch (fxo->ring_state) {
 	case DEBOUNCING_RINGING_POSITIVE:
 		if (is_fxo_ringing_negative(fxo)) {
-			if (++fxo->ring_polarity_change_count > 4) {
+			if (++fxo->ring_polarity_change_count >
+						POLARITY_CHANGES_NEEDED) {
 				mod_hooksig(wc, mod, DAHDI_RXSIG_RING);
 				set_ring(fxo, RINGING);
 				if (debug) {
@@ -1886,7 +1891,8 @@ static void wctdm_fxo_ring_detect(struct
 		break;
 	case DEBOUNCING_RINGING_NEGATIVE:
 		if (is_fxo_ringing_positive(fxo)) {
-			if (++fxo->ring_polarity_change_count > 4) {
+			if (++fxo->ring_polarity_change_count >
+						POLARITY_CHANGES_NEEDED) {
 				mod_hooksig(wc, mod, DAHDI_RXSIG_RING);
 				set_ring(fxo, RINGING);
 				if (debug) {
@@ -1956,13 +1962,13 @@ wctdm_check_battery_lost(struct wctdm *w
 	*/
 	switch (fxo->battery_state) {
 	case BATTERY_DEBOUNCING_PRESENT:
+	case BATTERY_DEBOUNCING_PRESENT_ALARM: /* intentional drop through */
 		/* we were going to BATTERY_PRESENT, but
 		 * battery was lost again. */
 		fxo->battery_state = BATTERY_LOST;
 		break;
 	case BATTERY_UNKNOWN:
 		mod_hooksig(wc, mod, DAHDI_RXSIG_ONHOOK);
-	case BATTERY_DEBOUNCING_PRESENT_ALARM: /* intentional drop through */
 	case BATTERY_PRESENT:
 		fxo->battery_state = BATTERY_DEBOUNCING_LOST;
 		fxo->battdebounce_timer = wc->framecount + battdebounce;
@@ -2017,7 +2023,7 @@ wctdm_check_battery_present(struct wctdm
 
 	switch (fxo->battery_state) {
 	case BATTERY_DEBOUNCING_PRESENT:
-		if (time_after(jiffies, fxo->battdebounce_timer)) {
+		if (time_after(wc->framecount, fxo->battdebounce_timer)) {
 			if (debug) {
 				dev_info(&wc->vb.pdev->dev,
 					 "BATTERY on %d/%d (%s)!\n",
@@ -2042,12 +2048,12 @@ wctdm_check_battery_present(struct wctdm
 			 * of its time period has already passed while
 			 * debouncing occurred */
 			fxo->battery_state = BATTERY_DEBOUNCING_PRESENT_ALARM;
-			fxo->battdebounce_timer = jiffies +
-				msecs_to_jiffies(battalarm - battdebounce);
+			fxo->battdebounce_timer = wc->framecount +
+						   battalarm - battdebounce;
 		}
 		break;
 	case BATTERY_DEBOUNCING_PRESENT_ALARM:
-		if (time_after(jiffies, fxo->battdebounce_timer)) {
+		if (time_after(wc->framecount, fxo->battdebounce_timer)) {
 			fxo->battery_state = BATTERY_PRESENT;
 			dahdi_alarm_channel(get_dahdi_chan(wc, mod),
 					    DAHDI_ALARM_NONE);
@@ -2056,6 +2062,7 @@ wctdm_check_battery_present(struct wctdm
 	case BATTERY_PRESENT:
 		break;
 	case BATTERY_DEBOUNCING_LOST:
+	case BATTERY_DEBOUNCING_LOST_ALARM:
 		/* we were going to BATTERY_LOST, but battery appeared again,
 		 * so clear the debounce timer */
 		fxo->battery_state = BATTERY_PRESENT;
@@ -2063,10 +2070,8 @@ wctdm_check_battery_present(struct wctdm
 	case BATTERY_UNKNOWN:
 		mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK);
 	case BATTERY_LOST: /* intentional drop through */
-	case BATTERY_DEBOUNCING_LOST_ALARM:
 		fxo->battery_state = BATTERY_DEBOUNCING_PRESENT;
-		fxo->battdebounce_timer = jiffies +
-						msecs_to_jiffies(battdebounce);
+		fxo->battdebounce_timer = wc->framecount + battdebounce;
 		break;
 	}
 }
diff -Naurp dahdi-linux-2.6.1/drivers/dahdi/wcte12xp/base.c dahdi-linux-2.6.2-rc1/drivers/dahdi/wcte12xp/base.c
--- dahdi-linux-2.6.1/drivers/dahdi/wcte12xp/base.c	2012-03-21 20:11:57.000000000 +0100
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/wcte12xp/base.c	2013-01-25 20:25:36.000000000 +0100
@@ -27,6 +27,8 @@
  * this program for more details.
  */
 
+#define pr_fmt(fmt)             KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/module.h>
@@ -55,18 +57,14 @@
 #error VOICEBUS_SFRAME_SIZE != SFRAME_SIZE
 #endif
 
-#ifndef pr_fmt
-#define pr_fmt(fmt)             KBUILD_MODNAME ": " fmt
-#endif
-
 static int debug;
-static int j1mode = 0;
+static int j1mode = -1;
 static int alarmdebounce = 2500; /* LOF/LFA def to 2.5s AT&T TR54016*/
 static int losalarmdebounce = 2500; /* LOS def to 2.5s AT&T TR54016*/
 static int aisalarmdebounce = 2500; /* AIS(blue) def to 2.5s AT&T TR54016*/
 static int yelalarmdebounce = 500; /* RAI(yellow) def to 0.5s AT&T devguide */
 static int t1e1override = -1; /* deprecated */
-static char *default_linemode = "auto"; /* 'auto', 'e1', or 't1' */
+static char *default_linemode = "auto"; /* 'auto', 'e1', 't1', or 'j1' */
 static int latency = VOICEBUS_DEFAULT_LATENCY;
 static unsigned int max_latency = VOICEBUS_DEFAULT_MAXLATENCY;
 static int vpmsupport = 1;
@@ -645,21 +643,21 @@ static inline int t1_setreg(struct t1 *w
 	return 0;
 }
 
-static int t1_getreg(struct t1 *wc, int addr)
+static void __t1_getreg(struct t1 *wc, int addr, struct command *cmd)
 {
-	struct command *cmd =  NULL;
-	unsigned long ret;
-	unsigned long flags;
-
-	might_sleep();
-
-	cmd = get_free_cmd(wc);
-	if (!cmd)
-		return -ENOMEM;
 	cmd->address = addr;
 	cmd->data = 0x00;
 	cmd->flags = __CMD_RD;
 	submit_cmd(wc, cmd);
+}
+
+static int __t1_getresult(struct t1 *wc, struct command *cmd)
+{
+	int ret;
+	unsigned long flags;
+
+	might_sleep();
+
 	ret = wait_for_completion_interruptible_timeout(&cmd->complete, HZ*10);
 	if (unlikely(!ret)) {
 		spin_lock_irqsave(&wc->reglock, flags);
@@ -690,10 +688,22 @@ static int t1_getreg(struct t1 *wc, int
 		}
 	}
 	ret = cmd->data;
-	free_cmd(wc, cmd);
 	return ret;
 }
 
+static int t1_getreg(struct t1 *wc, int addr)
+{
+	int res;
+	struct command *cmd =  NULL;
+	cmd = get_free_cmd(wc);
+	if (!cmd)
+		return -ENOMEM;
+	__t1_getreg(wc, addr, cmd);
+	res = __t1_getresult(wc, cmd);
+	free_cmd(wc, cmd);
+	return res;
+}
+
 static void t1_setleds(struct t1 *wc, int leds)
 {
 	struct command *cmd;
@@ -883,7 +893,8 @@ static void t1_configure_t1(struct t1 *w
 	fmr1 = 0x9e; /* FMR1: Mode 0, T1 mode, CRC on for ESF, 2.048 Mhz system data rate, no XAIS */
 	fmr2 = 0x20; /* FMR2: no payload loopback, don't auto yellow alarm */
 
-	if (j1mode)
+
+	if (!strcasecmp("j1", wc->span.spantype))
 		fmr4 = 0x1c;
 	else
 		fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */
@@ -923,7 +934,7 @@ static void t1_configure_t1(struct t1 *w
 	t1_setreg(wc, 0x38, 0x0a);	/* PCD: LOS after 176 consecutive "zeros" */
 	t1_setreg(wc, 0x39, 0x15);	/* PCR: 22 "ones" clear LOS */
 
-	if (j1mode)
+	if (!strcasecmp("j1", wc->span.spantype))
 		t1_setreg(wc, 0x24, 0x80); /* J1 overide */
 		
 	/* Generate pulse mask for T1 */
@@ -1184,15 +1195,47 @@ static int t1xxp_rbsbits(struct dahdi_ch
 	return 0;
 }
 
-static inline void t1_check_sigbits(struct t1 *wc)
+static void t1_check_sigbits(struct t1 *wc)
 {
+	struct command_container {
+		struct command *cmd;
+		struct list_head node;
+		unsigned int index;
+	};
+	struct command_container *cont;
+	LIST_HEAD(commands);
 	int a,i,rxs;
 
 	if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &wc->span.flags)))
 		return;
+
 	if (dahdi_is_e1_span(&wc->span)) {
+		/* Send out all the commands first. */
 		for (i = 0; i < 15; i++) {
-			a = t1_getreg(wc, 0x71 + i);
+			if (!(wc->span.chans[i+16]->sig & DAHDI_SIG_CLEAR) ||
+			    !(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR))  {
+				cont = kzalloc(sizeof(*cont), GFP_KERNEL);
+				if (!cont) {
+					WARN_ON_ONCE(1);
+					goto done;
+				}
+				cont->cmd = get_free_cmd(wc);
+				if (!cont->cmd) {
+					WARN_ON_ONCE(1);
+					goto done;
+				}
+				cont->index = i;
+				list_add_tail(&cont->node, &commands);
+				__t1_getreg(wc, 0x71 + i, cont->cmd);
+			}
+		}
+
+		/* Now check the results */
+		list_for_each_entry_reverse(cont, &commands, node) {
+			i = cont->index;
+			a = __t1_getresult(wc, cont->cmd);
+			free_cmd(wc, cont->cmd);
+			cont->cmd = NULL;
 			if (a > -1) {
 				/* Get high channel in low bits */
 				rxs = (a & 0xf);
@@ -1210,8 +1253,29 @@ static inline void t1_check_sigbits(stru
 			}
 		}
 	} else if (wc->span.lineconfig & DAHDI_CONFIG_D4) {
-		for (i = 0; i < 24; i+=4) {
-			a = t1_getreg(wc, 0x70 + (i>>2));
+		/* First we'll send out the commands */
+		for (i = 0; i < 24; i += 4) {
+			cont = kzalloc(sizeof(*cont), GFP_KERNEL);
+			if (!cont) {
+				WARN_ON_ONCE(1);
+				goto done;
+			}
+			cont->cmd = get_free_cmd(wc);
+			if (!cont->cmd) {
+				WARN_ON_ONCE(1);
+				goto done;
+			}
+			cont->index = i;
+			list_add_tail(&cont->node, &commands);
+			__t1_getreg(wc, 0x70 + (i>>2), cont->cmd);
+		}
+
+		/* Now we'll check the results */
+		list_for_each_entry_reverse(cont, &commands, node) {
+			i = cont->index;
+			a = __t1_getresult(wc, cont->cmd);
+			free_cmd(wc, cont->cmd);
+			cont->cmd = NULL;
 			if (a > -1) {
 				/* Get high channel in low bits */
 				rxs = (a & 0x3) << 2;
@@ -1241,8 +1305,28 @@ static inline void t1_check_sigbits(stru
 			}
 		}
 	} else {
-		for (i = 0; i < 24; i+=2) {
-			a = t1_getreg(wc, 0x70 + (i>>1));
+		/* First send out the commands. */
+		for (i = 0; i < 24; i += 2) {
+			cont = kzalloc(sizeof(*cont), GFP_KERNEL);
+			if (!cont) {
+				WARN_ON_ONCE(1);
+				goto done;
+			}
+			cont->cmd = get_free_cmd(wc);
+			if (!cont->cmd) {
+				WARN_ON_ONCE(1);
+				goto done;
+			}
+			cont->index = i;
+			list_add_tail(&cont->node, &commands);
+			__t1_getreg(wc, 0x70 + (i>>1), cont->cmd);
+		}
+
+		list_for_each_entry_reverse(cont, &commands, node) {
+			i = cont->index;
+			a = __t1_getresult(wc, cont->cmd);
+			free_cmd(wc, cont->cmd);
+			cont->cmd = NULL;
 			if (a > -1) {
 				/* Get high channel in low bits */
 				rxs = (a & 0xf);
@@ -1260,6 +1344,21 @@ static inline void t1_check_sigbits(stru
 			}
 		}
 	}
+done:
+	while (!list_empty(&commands)) {
+		cont = container_of(commands.next,
+				    struct command_container, node);
+		if (unlikely(cont->cmd)) {
+			/* We do not care about the result, let's just wait for
+			 * the rest of the system to finish with it. */
+			__t1_getresult(wc, cont->cmd);
+			free_cmd(wc, cont->cmd);
+			cont->cmd = NULL;
+		}
+		list_del(&cont->node);
+		kfree(cont);
+	}
+	return;
 }
 
 struct maint_work_struct {
@@ -1846,18 +1945,32 @@ static int t1_software_init(struct t1 *w
 	memset(chans, 0, sizeof(chans));
 	memset(ec, 0, sizeof(ec));
 
-	if (type == E1) {
+	switch (type) {
+	case E1:
 		wc->span.channels = 31;
 		wc->span.spantype = "E1";
 		wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3 |
 			DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
 		wc->span.deflaw = DAHDI_LAW_ALAW;
-	} else {
+		break;
+	case T1:
 		wc->span.channels = 24;
 		wc->span.spantype = "T1";
 		wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS |
 			DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
 		wc->span.deflaw = DAHDI_LAW_MULAW;
+		break;
+	case J1:
+		wc->span.channels = 24;
+		wc->span.spantype = "J1";
+		wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS |
+			DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
+		wc->span.deflaw = DAHDI_LAW_MULAW;
+		break;
+	default:
+		spin_unlock_irqrestore(&wc->reglock, flags);
+		res = -EINVAL;
+		goto error_exit;
 	}
 
 	spin_unlock_irqrestore(&wc->reglock, flags);
@@ -1866,7 +1979,7 @@ static int t1_software_init(struct t1 *w
 		return -ENOMEM;
 
 	t1_info(wc, "Setting up global serial parameters for %s\n",
-		(dahdi_is_e1_span(&wc->span) ? "E1" : "T1"));
+		wc->span.spantype);
 
 	t4_serial_setup(wc);
 	set_bit(DAHDI_FLAGBIT_RBS, &wc->span.flags);
@@ -1922,12 +2035,19 @@ static int t1xxp_set_linemode(struct dah
 
 	if (!strcasecmp(linemode, "t1")) {
 		dev_info(&wc->vb.pdev->dev,
-			 "Changing from E1 to T1 line mode.\n");
+			 "Changing from %s to T1 line mode.\n",
+			 wc->span.spantype);
 		res = t1_software_init(wc, T1);
 	} else if (!strcasecmp(linemode, "e1")) {
 		dev_info(&wc->vb.pdev->dev,
-			 "Changing from T1 to E1 line mode.\n");
+			 "Changing from %s to E1 line mode.\n",
+			 wc->span.spantype);
 		res = t1_software_init(wc, E1);
+	} else if (!strcasecmp(linemode, "j1")) {
+		dev_info(&wc->vb.pdev->dev,
+			 "Changing from %s to E1 line mode.\n",
+			 wc->span.spantype);
+		res = t1_software_init(wc, J1);
 	} else {
 		dev_err(&wc->vb.pdev->dev,
 			"'%s' is an unknown linemode.\n", linemode);
@@ -1967,14 +2087,15 @@ static int t1_hardware_post_init(struct
 	int x;
 
 	/* T1 or E1 */
-	if (-1 != t1e1override) {
-		pr_info("t1e1override is deprecated. Please use 'default_linemode'.\n");
-		*type = (t1e1override) ? E1 : T1;
+	if ((-1 != t1e1override) || (-1 != j1mode)) {
+		*type = (t1e1override) ? E1 : (j1mode) ? J1 : T1;
 	} else {
 		if (!strcasecmp(default_linemode, "e1")) {
 			*type = E1;
 		} else if (!strcasecmp(default_linemode, "t1")) {
 			*type = T1;
+		} else if (!strcasecmp(default_linemode, "j1")) {
+			*type = J1;
 		} else {
 			u8 pins;
 			res = t1_getpins(wc, &pins);
@@ -1983,7 +2104,8 @@ static int t1_hardware_post_init(struct
 			*type = (pins & 0x01) ? T1 : E1;
 		}
 	}
-	debug_printk(wc, 1, "linemode: %s\n", (*type == T1) ? "T1" : "E1");
+	debug_printk(wc, 1, "linemode: %s\n", (*type == T1) ? "T1" :
+					(J1 == *type) ? "J1" : "E1");
 	
 	/* what version of the FALC are we using? */
 	reg = t1_setreg(wc, 0x4a, 0xaa);
@@ -2014,19 +2136,41 @@ static int t1_hardware_post_init(struct
 	return 0;
 }
 
-static inline void t1_check_alarms(struct t1 *wc)
+static void t1_check_alarms(struct t1 *wc)
 {
 	unsigned char c,d;
 	int alarms;
 	int x,j;
 	unsigned char fmr4; /* must read this always */
+	struct command *cmds[3];
 
 	if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &wc->span.flags)))
 		return;
 
-	c = t1_getreg(wc, 0x4c);
-	fmr4 = t1_getreg(wc, 0x20); /* must read this even if we don't use it */
-	d = t1_getreg(wc, 0x4d);
+	for (x = 0; x < ARRAY_SIZE(cmds); ++x) {
+		cmds[x] = get_free_cmd(wc);
+		if (!cmds[x]) {
+			WARN_ON(1);
+			for (x = 0; x < ARRAY_SIZE(cmds); ++x)
+				free_cmd(wc, cmds[x]);
+			return;
+		}
+	}
+
+	/* Since this is voicebus, if we issue all the reads initially and then
+	 * check the results we can save ourselves some time. Otherwise, each
+	 * read will take a minimum of 3ms to go through the complete pipeline.
+	 */
+	__t1_getreg(wc, 0x4c, cmds[0]);
+	__t1_getreg(wc, 0x20, cmds[1]); /* must read this even if not used */
+	__t1_getreg(wc, 0x4d, cmds[2]);
+
+	d = __t1_getresult(wc, cmds[2]);
+	fmr4 = __t1_getresult(wc, cmds[1]);
+	c = __t1_getresult(wc, cmds[0]);
+
+	for (x=0; x < ARRAY_SIZE(cmds); ++x)
+		free_cmd(wc, cmds[x]);
 
 	/* Assume no alarms */
 	alarms = 0;
@@ -2442,11 +2586,11 @@ static void timer_work_func(struct work_
 {
 	struct t1 *wc = container_of(work, struct t1, timer_work);
 #endif
+	if (test_bit(INITIALIZED, &wc->bit_flags))
+		mod_timer(&wc->timer, jiffies + HZ/30);
 	t1_do_counters(wc);
 	t1_check_alarms(wc);
 	t1_check_sigbits(wc);
-	if (test_bit(INITIALIZED, &wc->bit_flags))
-		mod_timer(&wc->timer, jiffies + HZ/10);
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
@@ -2932,14 +3076,20 @@ static int __init te12xp_init(void)
 	if (!cmd_cache)
 		return -ENOMEM;
 
-	if (-1 != t1e1override) {
-		pr_info("'t1e1override' is deprecated. "
-			"Please use 'default_linemode' instead\n");
+	if ((-1 != t1e1override) || (-1 != j1mode)) {
+		pr_info("'t1e1override' and 'j1mode' are deprecated. "
+			"Please use 'default_linemode' instead.\n");
+		/* If someone is setting j1mode, then, t1e1override most likely
+		 * needs to be forced to t1 mode */
+		if (j1mode > 0)
+			t1e1override = 0;
 	} else if (strcasecmp(default_linemode, "auto") &&
 		   strcasecmp(default_linemode, "t1") &&
+		   strcasecmp(default_linemode, "j1") &&
 		   strcasecmp(default_linemode, "e1")) {
-		pr_err("'%s' is an unknown span type.", default_linemode);
+		pr_err("'%s' is an unknown span type.\n", default_linemode);
 		default_linemode = "auto";
+		kmem_cache_destroy(cmd_cache);
 		return -EINVAL;
 	}
 	res = dahdi_pci_module(&te12xp_driver);
diff -Naurp dahdi-linux-2.6.1/drivers/dahdi/wcte12xp/wcte12xp.h dahdi-linux-2.6.2-rc1/drivers/dahdi/wcte12xp/wcte12xp.h
--- dahdi-linux-2.6.1/drivers/dahdi/wcte12xp/wcte12xp.h	2011-10-26 20:58:14.000000000 +0200
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/wcte12xp/wcte12xp.h	2013-01-25 20:25:36.000000000 +0100
@@ -77,6 +77,7 @@
 enum linemode {
 	T1 = 1,
 	E1,
+	J1,
 };
 
 struct command {
--- dahdi-linux-2.6.1/drivers/dahdi/xpp/card_global.c	2012-03-15 18:35:57.000000000 +0100
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/xpp/card_global.c	2013-01-25 20:25:36.000000000 +0100
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/kmod.h>
 #include "xdefs.h"
 #include "xpd.h"
 #include "xpp_dahdi.h"
@@ -655,6 +656,15 @@ static void global_packet_dump(const cha
 
 #define	MAX_PATH_STR	128
 
+#ifndef	UMH_WAIT_PROC
+/*
+ * - UMH_WAIT_PROC was introduced as enum in 2.6.23
+ *   with a value of 1
+ * - It was changed to a macro (and it's value was modified) in 3.3.0
+ */
+#define	UMH_WAIT_PROC	1
+#endif
+
 int run_initialize_registers(xpd_t *xpd)
 {
 	int	ret;
@@ -737,7 +747,7 @@ int run_initialize_registers(xpd_t *xpd)
 	}
 	XPD_DBG(DEVICES, xpd, "running '%s' for type=%d revision=%d\n",
 			init_card, xpd->type, xbus->revision);
-	ret = call_usermodehelper(init_card, argv, envp, 1);
+	ret = call_usermodehelper(init_card, argv, envp, UMH_WAIT_PROC);
 	/*
 	 * Carefully report results
 	 */
--- dahdi-linux-2.6.1/drivers/dahdi/xpp/xdefs.h	2011-01-30 15:11:49.000000000 +0100
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/xpp/xdefs.h	2013-01-25 20:25:36.000000000 +0100
@@ -144,12 +144,14 @@ typedef unsigned char		byte;
 #define	SET_PROC_DIRENTRY_OWNER(p)	do { } while(0);
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-/* Also don't define this for later RHEL >= 5.2 . hex_asc is from the 
- * same linux-2.6-net-infrastructure-updates-to-mac80211-iwl4965.patch
- * as is the bool typedef. */
-#if LINUX_VERSION_CODE != KERNEL_VERSION(2,6,18)  || !  defined(hex_asc)
-typedef int			bool;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
+/* Also don't define this for later RHEL >= 5.2. */
+#if defined(RHEL_RELEASE_CODE) && defined(RHEL_RELEASE_VERSION)
+#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5, 3)
+typedef int bool;
+#endif
+#else
+typedef int bool;
 #endif
 #endif
 #else
--- dahdi-linux-2.6.1/drivers/dahdi/xpp/xpp_dahdi.c	2012-04-11 22:19:29.000000000 +0200
+++ dahdi-linux-2.6.2-rc1/drivers/dahdi/xpp/xpp_dahdi.c	2013-01-25 20:25:36.000000000 +0100
@@ -1083,7 +1083,7 @@ int xpd_dahdi_postregister(xpd_t *xpd)
  */
 void xpd_dahdi_preunregister(xpd_t *xpd)
 {
-	if (!xpd)
+	if (!xpd || !IS_PHONEDEV(xpd))
 		return;
 	XPD_DBG(DEVICES, xpd, "\n");
 	update_xpd_status(xpd, DAHDI_ALARM_NOTOPEN);
@@ -1103,7 +1103,7 @@ void xpd_dahdi_preunregister(xpd_t *xpd)
 
 void xpd_dahdi_postunregister(xpd_t *xpd)
 {
-	if (!xpd)
+	if (!xpd || !IS_PHONEDEV(xpd))
 		return;
 	atomic_dec(&PHONEDEV(xpd).dahdi_registered);
 	atomic_dec(&num_registered_spans);
--- dahdi-linux-2.6.1/include/dahdi/kernel.h	2012-04-03 22:10:03.000000000 +0200
+++ dahdi-linux-2.6.2-rc1/include/dahdi/kernel.h	2013-01-25 20:25:36.000000000 +0100
@@ -72,7 +72,7 @@
 #define DAHDI_IRQ_HANDLER(a) static irqreturn_t a(int irq, void *dev_id, struct pt_regs *regs)
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
 #ifdef CONFIG_PCI
 #include <linux/pci-aspm.h>
 #endif