diff options
author | Shaun Ruffell <sruffell@digium.com> | 2011-04-14 19:11:14 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2011-04-14 19:11:14 +0000 |
commit | 71d2abf65876e5f84db4efb191325bcbc7eaa975 (patch) | |
tree | 75cc255589a2943779a9e3d475bd41cb58bdf928 /drivers | |
parent | 36be1ea4b143d75ea4211bba61821faf0097542d (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>
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9902 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dahdi/wcte12xp/base.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index 39b6f38..a65b279 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -600,12 +600,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); @@ -628,9 +638,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) @@ -1597,6 +1607,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; @@ -1607,10 +1618,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"); @@ -2323,7 +2336,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))) { |