summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-04-14 20:32:29 +0000
committerShaun Ruffell <sruffell@digium.com>2011-04-14 20:32:29 +0000
commit2df9521deec68ee8b06fac1e1476f3433219ee73 (patch)
tree2cfc49f6cb530c46fedf5c6d6837a8f77a64b7c1
parentb7366802d0cce6960e0fc0c4caafc4ab1c7583d9 (diff)
wcte12xp: If we cannot read the mode selection pins fail the module load.
Alexandre reported that on a particular server he would get a server crash when loading the wcte12xp driver after receiving a line about a timeout when trying to read the mode selection jumpers. If the driver times out when trying to read the mode selection bits there is a serious problem and it should not try to continue on with configuration / registration. Reported-and-Tested-by: Alexandre Abreu <alexandre.abreu@redt.com.br> Signed-off-by: Shaun Ruffell <sruffell@digium.com> Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=9902 git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.4@9904 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/wcte12xp/base.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 156b603..bb88691 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -628,12 +628,22 @@ static void t1_setleds(struct t1 *wc, int leds)
submit_cmd(wc, cmd);
}
-static inline int t1_getpins(struct t1 *wc, int inisr)
+/**
+ * t1_getpins - Returns the value of the jumpers on the card.
+ * @wc: The card to read from.
+ * @pins: Pointer to u8 character to hold the pins value.
+ *
+ * Returns 0 on success, otherwise an error code.
+ *
+ */
+static int t1_getpins(struct t1 *wc, u8 *pins)
{
struct command *cmd;
unsigned long flags;
unsigned long ret;
+ *pins = 0;
+
cmd = get_free_cmd(wc);
BUG_ON(!cmd);
@@ -656,9 +666,9 @@ static inline int t1_getpins(struct t1 *wc, int inisr)
}
return ret;
}
- ret = cmd->data;
+ *pins = cmd->data;
free_cmd(wc, cmd);
- return ret;
+ return 0;
}
static void __t1xxp_set_clear(struct t1 *wc)
@@ -1639,6 +1649,7 @@ static inline unsigned char t1_vpm_out(struct t1 *wc, int unit, const unsigned i
static int t1_hardware_post_init(struct t1 *wc)
{
+ int res;
unsigned int reg;
int x;
@@ -1649,10 +1660,12 @@ static int t1_hardware_post_init(struct t1 *wc)
else
wc->spantype = TYPE_T1;
} else {
- if (t1_getpins(wc,0) & 0x01) /* returns 1 for T1 mode */
- wc->spantype = TYPE_T1;
- else
- wc->spantype = TYPE_E1;
+ u8 pins;
+ res = t1_getpins(wc, &pins);
+ if (res)
+ return res;
+
+ wc->spantype = (pins & 0x01) ? TYPE_T1 : TYPE_E1;
}
debug_printk(wc, 1, "spantype: %s\n", 1 == wc->spantype ? "T1" : "E1");
@@ -2327,7 +2340,13 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
free_wc(wc);
return -EIO;
}
- t1_hardware_post_init(wc);
+
+ res = t1_hardware_post_init(wc);
+ if (res) {
+ voicebus_release(&wc->vb);
+ free_wc(wc);
+ return res;
+ }
for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
if (!(wc->chans[x] = kmalloc(sizeof(*wc->chans[x]), GFP_KERNEL))) {