diff options
author | Noe Rubinstein <nrubinstein@proformatique.com> | 2010-09-24 10:05:31 +0200 |
---|---|---|
committer | Noe Rubinstein <nrubinstein@proformatique.com> | 2010-09-24 10:05:31 +0200 |
commit | 966533f27dfd378548f4fa4da0b46e093e812bff (patch) | |
tree | 9625ad01b5aaa643003c75e14b04a65ffa0a53e8 /xivovp | |
parent | b3658e40e48ec7ddce38117739fe05b5e6346d3b (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, ×lot); 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: |