summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dahdi/wctdm24xxp')
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c37
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h2
-rw-r--r--drivers/dahdi/wctdm24xxp/xhfc.c15
3 files changed, 54 insertions, 0 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index cd0ae98..f04703f 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -3564,6 +3564,42 @@ static int wctdm_dacs(struct dahdi_chan *dst, struct dahdi_chan *src)
return 0;
}
+/**
+ * wctdm_wait_for_ready
+ *
+ * Check if the board has finished any setup and is ready to start processing
+ * calls.
+ */
+int wctdm_wait_for_ready(const struct wctdm *wc)
+{
+ while (!wc->initialized) {
+ if (fatal_signal_pending(current))
+ return -EIO;
+ msleep_interruptible(250);
+ }
+ return 0;
+}
+
+/**
+ * wctdm_chanconfig - Called when the channels are being configured.
+ *
+ * Ensure that the card is completely ready to go before we allow the channels
+ * to be completely configured. This is to allow lengthy initialization
+ * actions to take place in background on driver load and ensure we're synced
+ * up by the time dahdi_cfg is run.
+ *
+ */
+static int
+wctdm_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
+{
+ struct wctdm *wc = chan->pvt;
+
+ if ((file->f_flags & O_NONBLOCK) && !wc->initialized)
+ return -EAGAIN;
+
+ return wctdm_wait_for_ready(wc);
+}
+
static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
.owner = THIS_MODULE,
.hooksig = wctdm_hooksig,
@@ -3571,6 +3607,7 @@ static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
.close = wctdm_close,
.ioctl = wctdm_ioctl,
.watchdog = wctdm_watchdog,
+ .chanconfig = wctdm_chanconfig,
.dacs = wctdm_dacs,
#ifdef VPM_SUPPORT
.echocan_create = wctdm_echocan_create,
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index 99d8159..9619318 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -270,6 +270,8 @@ struct wctdm {
int wctdm_getreg(struct wctdm *wc, int card, int addr);
int wctdm_setreg(struct wctdm *wc, int card, int addr, int val);
+int wctdm_wait_for_ready(const struct wctdm *wc);
+
extern struct semaphore ifacelock;
extern struct wctdm *ifaces[WC_MAX_IFACES];
diff --git a/drivers/dahdi/wctdm24xxp/xhfc.c b/drivers/dahdi/wctdm24xxp/xhfc.c
index 730d2e0..e0cc687 100644
--- a/drivers/dahdi/wctdm24xxp/xhfc.c
+++ b/drivers/dahdi/wctdm24xxp/xhfc.c
@@ -2183,11 +2183,19 @@ int b400m_spanconfig(struct file *file, struct dahdi_span *span,
struct wctdm *wc;
int te_mode, term;
int pos;
+ int res;
bspan = bspan_from_dspan(span);
b4 = bspan->parent;
wc = b4->wc;
+ if ((file->f_flags & O_NONBLOCK) && !wc->initialized)
+ return -EAGAIN;
+
+ res = wctdm_wait_for_ready(wc);
+ if (res)
+ return res;
+
b400m_disable_workqueues(b4->wc);
te_mode = (lc->lineconfig & DAHDI_CONFIG_NTTE) ? 0 : 1;
@@ -2258,6 +2266,13 @@ int b400m_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
struct b400m *b4 = bspan->parent;
int res;
+ if ((file->f_flags & O_NONBLOCK) && !b4->wc->initialized)
+ return -EAGAIN;
+
+ res = wctdm_wait_for_ready(b4->wc);
+ if (res)
+ return res;
+
alreadyrunning = bspan->wspan->span.flags & DAHDI_FLAG_RUNNING;
if (DBG_FOPS) {