wcte43x: Do not get stuck in "Not Open" state when DAHDI_CONFIG_NOTOPEN is set.
This is the same change for the wcte13xp driver but applied to the other xbus-based digital card. If dahdi_cfg set the DAHDI_CONFIG_NOTOPEN setting on the span, which it does when the "yellow" flag is added to the span config line, then it was possible for the span to get stuck with DAHDI_ALARM_NOTOPEN (NOP). This is because the driver only updates the alarm state when the framer reports that the span alarm has changed. Therefore, unless the framer goes through an alarm transition, the fact that channels are opened was never noticed by alarm handling routine. Now check the alarm state directly when the first channel is opened, and the last channel is closed. Internal-Issue-ID: DAHDI-1103 Signed-off-by: Shaun Ruffell <sruffell@digium.com> Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
parent
61aeaf13ae
commit
71867c3de7
@ -91,8 +91,9 @@ struct t43x;
|
|||||||
struct t43x_span {
|
struct t43x_span {
|
||||||
struct t43x *owner;
|
struct t43x *owner;
|
||||||
struct dahdi_span span;
|
struct dahdi_span span;
|
||||||
#define NMF_FLAGBIT 1
|
#define NMF_FLAGBIT 1
|
||||||
#define SENDINGYELLOW_FLAGBIT 2
|
#define SENDINGYELLOW_FLAGBIT 2
|
||||||
|
#define HAVE_OPEN_CHANNELS_FLAGBIT 3
|
||||||
unsigned long bit_flags;
|
unsigned long bit_flags;
|
||||||
unsigned char txsigs[16]; /* Copy of tx sig registers */
|
unsigned char txsigs[16]; /* Copy of tx sig registers */
|
||||||
unsigned long lofalarmtimer;
|
unsigned long lofalarmtimer;
|
||||||
@ -1719,10 +1720,21 @@ static void t43x_configure_e1(struct t43x *wc, int span_idx, int lineconfig)
|
|||||||
framing, line, crc4);
|
framing, line, crc4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool have_open_channels(const struct t43x_span *ts)
|
||||||
|
{
|
||||||
|
int x, j;
|
||||||
|
for (x = 0, j = 0; x < ts->span.channels; x++) {
|
||||||
|
const struct dahdi_chan *chan = ts->span.chans[x];
|
||||||
|
if (test_bit(DAHDI_FLAGBIT_OPEN, &chan->flags) ||
|
||||||
|
dahdi_have_netdev(chan))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void t43x_framer_start(struct t43x *wc)
|
static void t43x_framer_start(struct t43x *wc)
|
||||||
{
|
{
|
||||||
int unit;
|
int unit;
|
||||||
struct t43x_span *ts;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -1739,7 +1751,7 @@ static void t43x_framer_start(struct t43x *wc)
|
|||||||
dev_warn(&wc->xb.pdev->dev, "DMA engine did not stop.\n");
|
dev_warn(&wc->xb.pdev->dev, "DMA engine did not stop.\n");
|
||||||
|
|
||||||
for (unit = 0; unit < wc->numspans; unit++) {
|
for (unit = 0; unit < wc->numspans; unit++) {
|
||||||
ts = wc->tspans[unit];
|
struct t43x_span *ts = wc->tspans[unit];
|
||||||
if (dahdi_is_e1_span(&ts->span)) {
|
if (dahdi_is_e1_span(&ts->span)) {
|
||||||
t43x_configure_e1(wc, unit, ts->span.lineconfig);
|
t43x_configure_e1(wc, unit, ts->span.lineconfig);
|
||||||
} else { /* is a T1 card */
|
} else { /* is a T1 card */
|
||||||
@ -1753,6 +1765,15 @@ static void t43x_framer_start(struct t43x *wc)
|
|||||||
|
|
||||||
for (unit = 0; unit < wc->numspans; unit++) {
|
for (unit = 0; unit < wc->numspans; unit++) {
|
||||||
/* Get this party started */
|
/* Get this party started */
|
||||||
|
struct t43x_span *ts = wc->tspans[unit];
|
||||||
|
|
||||||
|
/* Check for "open channels" here in case some channels have
|
||||||
|
* netdev. */
|
||||||
|
if (have_open_channels(ts))
|
||||||
|
clear_bit(HAVE_OPEN_CHANNELS_FLAGBIT, &ts->bit_flags);
|
||||||
|
else
|
||||||
|
set_bit(HAVE_OPEN_CHANNELS_FLAGBIT, &ts->bit_flags);
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
t43x_check_alarms(wc, unit);
|
t43x_check_alarms(wc, unit);
|
||||||
t43x_check_sigbits(wc, unit);
|
t43x_check_sigbits(wc, unit);
|
||||||
@ -1774,7 +1795,7 @@ static void t43x_framer_start(struct t43x *wc)
|
|||||||
|
|
||||||
/* Clear all counters */
|
/* Clear all counters */
|
||||||
for (unit = 0; unit < wc->numspans; unit++) {
|
for (unit = 0; unit < wc->numspans; unit++) {
|
||||||
ts = wc->tspans[unit];
|
struct t43x_span *ts = wc->tspans[unit];
|
||||||
memset(&ts->span.count, 0, sizeof(ts->span.count));
|
memset(&ts->span.count, 0, sizeof(ts->span.count));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2657,7 +2678,6 @@ static void t43x_check_alarms(struct t43x *wc, int span_idx)
|
|||||||
struct t43x_span *ts = wc->tspans[span_idx];
|
struct t43x_span *ts = wc->tspans[span_idx];
|
||||||
unsigned char c, d;
|
unsigned char c, d;
|
||||||
int alarms;
|
int alarms;
|
||||||
int x, j;
|
|
||||||
int fidx = (wc->numspans == 2) ? span_idx+1 : span_idx;
|
int fidx = (wc->numspans == 2) ? span_idx+1 : span_idx;
|
||||||
|
|
||||||
if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &ts->span.flags)))
|
if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &ts->span.flags)))
|
||||||
@ -2699,11 +2719,7 @@ static void t43x_check_alarms(struct t43x *wc, int span_idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
|
if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
|
||||||
for (x = 0, j = 0; x < ts->span.channels; x++)
|
if (!test_bit(HAVE_OPEN_CHANNELS_FLAGBIT, &ts->bit_flags))
|
||||||
if ((ts->chans[x]->flags & DAHDI_FLAG_OPEN) ||
|
|
||||||
dahdi_have_netdev(ts->chans[x]))
|
|
||||||
j++;
|
|
||||||
if (!j)
|
|
||||||
alarms |= DAHDI_ALARM_NOTOPEN;
|
alarms |= DAHDI_ALARM_NOTOPEN;
|
||||||
else
|
else
|
||||||
alarms &= ~DAHDI_ALARM_NOTOPEN;
|
alarms &= ~DAHDI_ALARM_NOTOPEN;
|
||||||
@ -3157,6 +3173,45 @@ static void t43x_timer(unsigned long data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int t43x_open(struct dahdi_chan *chan)
|
||||||
|
{
|
||||||
|
struct t43x *wc = chan->pvt;
|
||||||
|
struct t43x_span *ts = container_of(chan->span, struct t43x_span, span);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!(ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!test_and_set_bit(HAVE_OPEN_CHANNELS_FLAGBIT, &ts->bit_flags)) {
|
||||||
|
local_irq_save(flags);
|
||||||
|
t43x_check_alarms(wc, ts->span.offset);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int t43x_close(struct dahdi_chan *chan)
|
||||||
|
{
|
||||||
|
struct t43x *wc = chan->pvt;
|
||||||
|
struct t43x_span *ts = container_of(chan->span, struct t43x_span, span);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!(ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (have_open_channels(ts))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!test_and_set_bit(HAVE_OPEN_CHANNELS_FLAGBIT, &ts->bit_flags)) {
|
||||||
|
local_irq_save(flags);
|
||||||
|
t43x_check_alarms(wc, ts->span.offset);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct dahdi_span_ops t43x_span_ops = {
|
static const struct dahdi_span_ops t43x_span_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.spanconfig = t43x_spanconfig,
|
.spanconfig = t43x_spanconfig,
|
||||||
@ -3169,6 +3224,8 @@ static const struct dahdi_span_ops t43x_span_ops = {
|
|||||||
.set_spantype = t43x_set_linemode,
|
.set_spantype = t43x_set_linemode,
|
||||||
.echocan_create = t43x_echocan_create,
|
.echocan_create = t43x_echocan_create,
|
||||||
.echocan_name = t43x_echocan_name,
|
.echocan_name = t43x_echocan_name,
|
||||||
|
.open = t43x_open,
|
||||||
|
.close = t43x_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user