wcte13xp: Do not get stuck in "Not Open" state when DAHDI_CONFIG_NOTOPEN is set.
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 wcte13xp 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
b3a6b91858
commit
f35e8aafb0
@ -92,9 +92,10 @@ struct t13x {
|
|||||||
unsigned long loopuptimer;
|
unsigned long loopuptimer;
|
||||||
unsigned long loopdntimer;
|
unsigned long loopdntimer;
|
||||||
const char *name;
|
const char *name;
|
||||||
#define INITIALIZED 1
|
#define INITIALIZED 1
|
||||||
#define SHUTDOWN 2
|
#define SHUTDOWN 2
|
||||||
#define READY 3
|
#define READY 3
|
||||||
|
#define HAVE_OPEN_CHANNELS 4
|
||||||
unsigned long bit_flags;
|
unsigned long bit_flags;
|
||||||
u32 ledstate;
|
u32 ledstate;
|
||||||
struct dahdi_device *ddev;
|
struct dahdi_device *ddev;
|
||||||
@ -1285,6 +1286,18 @@ static int te13xp_check_for_interrupts(struct t13x *wc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool have_open_channels(const struct t13x *wc)
|
||||||
|
{
|
||||||
|
int x, j;
|
||||||
|
for (x = 0, j = 0; x < wc->span.channels; x++) {
|
||||||
|
const struct dahdi_chan *chan = wc->span.chans[x];
|
||||||
|
if (test_bit(DAHDI_FLAGBIT_OPEN, &chan->flags) ||
|
||||||
|
dahdi_have_netdev(chan))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int t13x_startup(struct file *file, struct dahdi_span *span)
|
static int t13x_startup(struct file *file, struct dahdi_span *span)
|
||||||
{
|
{
|
||||||
struct t13x *wc = container_of(span, struct t13x, span);
|
struct t13x *wc = container_of(span, struct t13x, span);
|
||||||
@ -1315,6 +1328,12 @@ static int t13x_startup(struct file *file, struct dahdi_span *span)
|
|||||||
dev_info(&wc->xb.pdev->dev,
|
dev_info(&wc->xb.pdev->dev,
|
||||||
"Calling startup (flags is %lu)\n", span->flags);
|
"Calling startup (flags is %lu)\n", span->flags);
|
||||||
|
|
||||||
|
/* Check for "open channels" here in case some channels have netdev. */
|
||||||
|
if (have_open_channels(wc))
|
||||||
|
clear_bit(HAVE_OPEN_CHANNELS, &wc->bit_flags);
|
||||||
|
else
|
||||||
|
set_bit(HAVE_OPEN_CHANNELS, &wc->bit_flags);
|
||||||
|
|
||||||
/* Get this party started */
|
/* Get this party started */
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
t13x_check_alarms(wc);
|
t13x_check_alarms(wc);
|
||||||
@ -1904,7 +1923,6 @@ static void t13x_check_alarms(struct t13x *wc)
|
|||||||
{
|
{
|
||||||
unsigned char c, d;
|
unsigned char c, d;
|
||||||
int alarms;
|
int alarms;
|
||||||
int x, j;
|
|
||||||
|
|
||||||
if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &wc->span.flags)))
|
if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &wc->span.flags)))
|
||||||
return;
|
return;
|
||||||
@ -1943,11 +1961,7 @@ static void t13x_check_alarms(struct t13x *wc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
|
if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
|
||||||
for (x = 0, j = 0; x < wc->span.channels; x++)
|
if (!test_bit(HAVE_OPEN_CHANNELS, &wc->bit_flags))
|
||||||
if ((wc->span.chans[x]->flags & DAHDI_FLAG_OPEN) ||
|
|
||||||
dahdi_have_netdev(wc->span.chans[x]))
|
|
||||||
j++;
|
|
||||||
if (!j)
|
|
||||||
alarms |= DAHDI_ALARM_NOTOPEN;
|
alarms |= DAHDI_ALARM_NOTOPEN;
|
||||||
else
|
else
|
||||||
alarms &= ~DAHDI_ALARM_NOTOPEN;
|
alarms &= ~DAHDI_ALARM_NOTOPEN;
|
||||||
@ -2348,6 +2362,41 @@ static void te13xp_timer(unsigned long data)
|
|||||||
static inline void create_sysfs_files(struct t13x *wc) { return; }
|
static inline void create_sysfs_files(struct t13x *wc) { return; }
|
||||||
static inline void remove_sysfs_files(struct t13x *wc) { return; }
|
static inline void remove_sysfs_files(struct t13x *wc) { return; }
|
||||||
|
|
||||||
|
static int t13x_open(struct dahdi_chan *chan)
|
||||||
|
{
|
||||||
|
struct t13x *wc = chan->pvt;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!(wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!test_and_set_bit(HAVE_OPEN_CHANNELS, &wc->bit_flags)) {
|
||||||
|
local_irq_save(flags);
|
||||||
|
t13x_check_alarms(wc);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int t13x_close(struct dahdi_chan *chan)
|
||||||
|
{
|
||||||
|
struct t13x *wc = chan->pvt;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!(wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!have_open_channels(wc)) {
|
||||||
|
if (test_and_clear_bit(HAVE_OPEN_CHANNELS, &wc->bit_flags)) {
|
||||||
|
local_irq_save(flags);
|
||||||
|
t13x_check_alarms(wc);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct dahdi_span_ops t13x_span_ops = {
|
static const struct dahdi_span_ops t13x_span_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.spanconfig = t13x_spanconfig,
|
.spanconfig = t13x_spanconfig,
|
||||||
@ -2359,6 +2408,8 @@ static const struct dahdi_span_ops t13x_span_ops = {
|
|||||||
.set_spantype = t13x_set_linemode,
|
.set_spantype = t13x_set_linemode,
|
||||||
.echocan_create = t13x_echocan_create,
|
.echocan_create = t13x_echocan_create,
|
||||||
.echocan_name = t13x_echocan_name,
|
.echocan_name = t13x_echocan_name,
|
||||||
|
.open = t13x_open,
|
||||||
|
.close = t13x_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SPI_BASE 0x200
|
#define SPI_BASE 0x200
|
||||||
|
Loading…
Reference in New Issue
Block a user