summaryrefslogtreecommitdiff
path: root/xivovp
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2010-09-24 10:05:31 +0200
committerNoe Rubinstein <nrubinstein@proformatique.com>2010-09-24 10:05:31 +0200
commit966533f27dfd378548f4fa4da0b46e093e812bff (patch)
tree9625ad01b5aaa643003c75e14b04a65ffa0a53e8 /xivovp
parentb3658e40e48ec7ddce38117739fe05b5e6346d3b (diff)
Still crashes but supposed to be better
Diffstat (limited to 'xivovp')
-rw-r--r--xivovp/base.c (renamed from xivovp/xivovp.c)123
1 files changed, 95 insertions, 28 deletions
diff --git a/xivovp/xivovp.c b/xivovp/base.c
index 6a6890f..4f0b703 100644
--- a/xivovp/xivovp.c
+++ b/xivovp/base.c
@@ -17,6 +17,7 @@
#define DRV_NAME KBUILD_BASENAME
#define TRACES_VANISH_DEFAULT 2000
+#define TXQUEUE_LEN 5
static int traces_vanish = TRACES_VANISH_DEFAULT;
module_param(traces_vanish, int, 0444);
@@ -26,7 +27,7 @@ MODULE_PARM_DESC(traces_vanish,
"ERROR/WARNING/INFO (default: " __stringify(TRACES_VANISH_DEFAULT) ")");
-#define NB_LINES 2
+#define NB_LINES 1 //XXX
#define TICK_JIFFIES DIV_ROUND_UP(TICK_MS * HZ, 1000)
#define DEBUG_SELECT_RUNNING (VP_DBG_ERROR \
| VP_DBG_WARNING \
@@ -36,11 +37,19 @@ enum xivovp_line_type { FXS_LINE = 0, FXO_LINE = 1 };
struct xivovp_line {
enum xivovp_line_type type;
- //int reverse_polarity;
+
+ int ready;
Vp890LineObjectType line_obj;
VpLineCtxType vp_ctx;
+
struct dahdi_chan chan;
+ enum dahdi_txsig txsig_queue[TXQUEUE_LEN];
+ int txsig_queue_len; // is there a better/canonical way to write that?
+
+ spinlock_t vp_lock;
+
+ //int reverse_polarity;
};
static struct xivovp {
@@ -54,13 +63,16 @@ static struct xivovp {
VpDevCtxType dev_ctx;
} xivovp;
+static int
+xivovp_hooksig_pvt(struct xivovp_line* line, enum dahdi_txsig txsig);
+
/* Shouldn't there be something better there? TOTHINK */
static struct xivovp_line* xivovp_line_from_ctx(VpLineCtxType* line_ctx)
{
Vp890LineObjectType* line_obj = line_ctx->pLineObj;
int i;
- for(i = 0; i < NB_LINES; i++)
+ for(i = 0; i < ARRAY_SIZE(xivovp.line); i++)
if(&xivovp.line[i].line_obj == line_obj)
return &xivovp.line[i];
@@ -88,6 +100,7 @@ static void vp_set_debug_select_running(void)
static void vp_tick(const unsigned long data)
{
+ int i, j;
static VpEventType event;
static VpResultsType result;
struct xivovp_line* line;
@@ -134,14 +147,14 @@ static void vp_tick(const unsigned long data)
.fxo = 0,
};
printk(KERN_INFO DRV_NAME ": vp dev init complete\n");
- vpst = VpSetOption(event.pLineCtx, NULL,
+ vpst = VpSetOption(NULL, event.pDevCtx,
VP_OPTION_ID_EVENT_MASK, &event_mask);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": VpSetOption VP_OPTION_ID_EVENT_MASK returned %d\n",
(int)vpst);
return;
}
- vpst = VpSetOption(event.pLineCtx, NULL,
+ vpst = VpSetOption(NULL, event.pDevCtx,
VP_OPTION_ID_TIMESLOT,
&timeslot);
if (vpst != VP_STATUS_SUCCESS) {
@@ -149,14 +162,20 @@ static void vp_tick(const unsigned long data)
(int)vpst);
return;
}
- vpst = VpSetLineState(event.pLineCtx,
+
+ vpst = VpSetLineState(&xivovp.line[FXS_LINE].vp_ctx,
VP_LINE_OHT);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": VpSetLineState returned %d\n",
(int)vpst);
return;
}
- vpst = VpCalLine(event.pLineCtx);
+
+ //TODO: VpSetLineState for FXO_LINE
+ //TODO: VpCalLine for FXO_LINE
+ // What happens if lines aren't connected?
+
+ vpst = VpCalLine(&xivovp.line[FXS_LINE].vp_ctx);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": VpCalLine returned %d\n",
(int)vpst);
@@ -168,6 +187,7 @@ static void vp_tick(const unsigned long data)
case VP_EVID_CAL_CMP:
printk(KERN_INFO DRV_NAME ": calibration succeeded\n");
+ xivovp_line_from_ctx(event.pLineCtx)->ready = 1;
vp_set_debug_select_running();
break;
@@ -213,6 +233,17 @@ static void vp_tick(const unsigned long data)
}
}
+
+ for(i = 0; i < ARRAY_SIZE(xivovp.line); i++) {
+ if(xivovp.line[i].ready) {
+ for(j = 0; j < xivovp.line[i].txsig_queue_len; j++) {
+ xivovp_hooksig_pvt(&xivovp.line[i],
+ xivovp.line[i].txsig_queue[j]);
+ }
+ xivovp.line[i].txsig_queue_len = 0;
+ }
+ }
+
if (count_and_stop_traces) {
if (traces_vanish >= 0 && --traces_vanish < 0)
vp_set_debug_select_running();
@@ -221,50 +252,63 @@ static void vp_tick(const unsigned long data)
mod_timer(&xivovp.vp_tick_timer, jiffies + TICK_JIFFIES);
}
+static int
+xivovp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
+{
+ struct xivovp_line* line = chan->pvt;
+
+ if(line->txsig_queue_len >= ARRAY_SIZE(line->txsig_queue)) {
+ printk(KERN_WARNING DRV_NAME "(chan %d): txsig overrun", chan->chanpos);
+ return -1;
+ }
+
+ line->txsig_queue[line->txsig_queue_len++] = txsig;
+ return 0;
+}
+
/*
* hooksig transmits sig from DAHDI to VP.
* sig from VP is handled in vp_tick and transmitted to DAHDI with
* dahdi_hooksig
*/
static int
-xivovp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
+xivovp_hooksig_pvt(struct xivovp_line* line, enum dahdi_txsig txsig)
{
- struct xivovp_line* line = &xivovp.line[chan->chanpos - 1];
-
+ int chanpos = line->chan.chanpos;
if(line->type == FXO_LINE) {
switch(txsig) {
case DAHDI_TXSIG_START:
case DAHDI_TXSIG_OFFHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): transmitting %s state on FXO, setting to TALK.\n", chan->chanpos, txsig == DAHDI_TXSIG_START ? "START" : "OFFHOOK");
+ printk(KERN_WARNING DRV_NAME "(chan %d): transmitting %s state on FXO, setting to TALK.\n", chanpos, txsig == DAHDI_TXSIG_START ? "START" : "OFFHOOK");
VpSetLineState(&line->vp_ctx, VP_LINE_FXO_TALK);
break;
case DAHDI_TXSIG_ONHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): transmitting ONHOOK on FXO, setting to OHT.\n", chan->chanpos);
+ printk(KERN_WARNING DRV_NAME "(chan %d): transmitting ONHOOK on FXO, setting to OHT.\n", chanpos);
VpSetLineState(&line->vp_ctx, VP_LINE_FXO_OHT);
break;
default:
- printk(KERN_WARNING DRV_NAME "(chan %d): unsupported tx state for FXO: %d\n", chan->chanpos, txsig);
+ printk(KERN_WARNING DRV_NAME "(chan %d): unsupported tx state for FXO: %d\n", chanpos, txsig);
}
} else /* FXS */ {
switch(txsig) {
case DAHDI_TXSIG_START:
- printk(KERN_WARNING DRV_NAME "(chan %d): transmitting START on FXS, setting to RINGING.\n", chan->chanpos);
+ printk(KERN_WARNING DRV_NAME "(chan %d): transmitting START on FXS, setting to RINGING.\n", chanpos);
VpSetLineState(&line->vp_ctx, VP_LINE_RINGING);
break;
case DAHDI_TXSIG_OFFHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): transmitting OFFHOOK on FXS, setting to TALK.\n", chan->chanpos);
+ printk(KERN_WARNING DRV_NAME "(chan %d): transmitting OFFHOOK on FXS, setting to TALK.\n", chanpos);
VpSetLineState(&line->vp_ctx, VP_LINE_TALK);
break;
case DAHDI_TXSIG_ONHOOK:
- printk(KERN_WARNING DRV_NAME "(chan %d): transmitting ONHOOK on FXS, setting to OHT.\n", chan->chanpos);
+ printk(KERN_WARNING DRV_NAME "(chan %d): transmitting ONHOOK on FXS, setting to OHT.\n", chanpos);
VpSetLineState(&line->vp_ctx, VP_LINE_OHT);
break;
case DAHDI_TXSIG_KEWL:
- printk(KERN_WARNING DRV_NAME "(chan %d): requested to transmit DAHDI_TXSIG_KEWL but I have no idea what it means.\n", chan->chanpos);
+ printk(KERN_WARNING DRV_NAME "(chan %d): requested to transmit DAHDI_TXSIG_KEWL but I have no idea what it means.\n", chanpos);
//VpSetLineState(line->vp_ctx, );
return -1;
default:
- printk(KERN_WARNING DRV_NAME "(chan %d): unsupported tx state for FXS: %d\n", chan->chanpos, txsig);
+ printk(KERN_WARNING DRV_NAME "(chan %d): unsupported tx state for FXS: %d\n", chanpos, txsig);
return -1;
}
}
@@ -280,8 +324,6 @@ static const struct dahdi_span_ops xivovp_span_ops = {
static int
span_init(void)
{
- int i;
-
dahdi_copy_string(xivovp.span.name, "XiVO_FX", sizeof(xivovp.span.name));
dahdi_copy_string(xivovp.span.desc,
"FXO/FXS driver for Avencall's XiVO IPBX OpenHardware "
@@ -291,8 +333,6 @@ span_init(void)
sizeof(xivovp.span.devicetype));
xivovp.span.ops = &xivovp_span_ops;
xivovp.span.chans = xivovp.chans;
- for(i = 0; i < NB_LINES; i++)
- xivovp.chans[i] = &xivovp.line[i].chan;
init_waitqueue_head(&xivovp.span.maintq); /* still dunno what this is */
@@ -300,6 +340,28 @@ span_init(void)
}
static int
+xivovp_init(void)
+{
+ int i;
+ /* this is simple because no dynamic alloc */
+
+ init_timer(&xivovp.vp_tick_timer);
+ xivovp.vp_tick_timer.function = vp_tick;
+ xivovp.vp_tick_timer.data = 42;
+
+ xivovp.line[FXS_LINE].type = FXS_LINE;
+ xivovp.line[FXO_LINE].type = FXO_LINE;
+
+ for(i = 0; i < NB_LINES; i++) {
+ xivovp.chans[i] = &xivovp.line[i].chan;
+ xivovp.line[i].chan.pvt = &xivovp.line[i].chan;
+ spin_lock_init(&xivovp.line[i].vp_lock);
+ }
+
+ return 0;
+}
+
+static int
vp_init(void)
{
int rc;
@@ -319,8 +381,8 @@ vp_init(void)
vpst = VpMakeLineObject(
VP_TERM_FXS_GENERIC,
FXS_LINE,
- &xivovp.line[0].vp_ctx,
- (void*)&xivovp.line[0].line_obj,
+ &xivovp.line[FXS_LINE].vp_ctx,
+ (void*)&xivovp.line[FXS_LINE].line_obj,
&xivovp.dev_ctx);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": VpMakeLineObject (FXS) failed (%d)\n", vpst);
@@ -356,6 +418,8 @@ vp_init(void)
goto err_vp_init_device;
}
+ return 0;
+
/* nothing */
err_vp_init_device:
/* nothing */
@@ -371,16 +435,17 @@ test_evb_ve890_init(void)
int rc;
printk(KERN_INFO DRV_NAME ": entering %s\n", __func__);
- init_timer(&xivovp.vp_tick_timer);
- xivovp.vp_tick_timer.function = vp_tick;
- xivovp.vp_tick_timer.data = 42;
-
rc = tlp_spidev_init();
if (rc < 0) {
printk(KERN_ERR DRV_NAME ": tlp_spidev_init failed (%d)\n", rc);
goto err_spidev_init;
}
+ rc = xivovp_init();
+ if(rc < 0)
+ goto err_xivovp_init;
+
+
rc = vp_init();
if(rc < 0)
goto err_vp_init;
@@ -397,6 +462,8 @@ test_evb_ve890_init(void)
err_dahdi_init:
/* nothing */
+ err_xivovp_init:
+ /* nothing */
err_vp_init:
tlp_spidev_exit();
err_spidev_init: