summaryrefslogtreecommitdiff
path: root/xivovp/base.c
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2010-10-01 20:20:37 +0200
committerNoe Rubinstein <nrubinstein@proformatique.com>2010-10-01 20:20:37 +0200
commit77c9f651204bdc5a27df6f70dcd73284ecc3e69b (patch)
treee21ce6083a76d59405a71e3be6851fda499eafbe /xivovp/base.c
parentda44ef97d3e389c24eaa7c2c9913a22b185583ab (diff)
sync fixes + misc improvments
Diffstat (limited to 'xivovp/base.c')
-rw-r--r--xivovp/base.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/xivovp/base.c b/xivovp/base.c
index 56a7d18..b600f87 100644
--- a/xivovp/base.c
+++ b/xivovp/base.c
@@ -17,10 +17,15 @@
#define DRV_NAME "xivovp"
#define TRACES_VANISH_DEFAULT 2000
-#define TXQUEUE_LEN 5
+#define TXQUEUE_LEN 16 /* WARNING TOTHINK possible DoS attack by
+ overrunning this queue */
static int traces_vanish = TRACES_VANISH_DEFAULT;
+static int alawoverride = 1; /* It's named like that in every DAHDI driver
+ except I prefer it to be 1 so the name doesn't
+ make much sense. */
module_param(traces_vanish, int, 0444);
+module_param(alawoverride, int, 0600);
MODULE_PARM_DESC(traces_vanish,
"number of " __stringify(TICK_MS) "ms ticks after device init complete "
"event at which point VP-API II Lite traces will be reduced to only "
@@ -50,7 +55,7 @@ struct xivovp_line {
enum dahdi_txsig txsig_queue[TXQUEUE_LEN];
int txsig_queue_len; // is there a better/canonical way to write that?
- spinlock_t vp_lock;
+ spinlock_t lock;
//int reverse_polarity;
};
@@ -70,7 +75,6 @@ struct timer_list rxtx_timer;
static void xivovp_rxtx(unsigned long data)
{
- static int i;
(void) data;
dahdi_receive(&xivovp.span);
dahdi_transmit(&xivovp.span);
@@ -85,10 +89,8 @@ static struct xivovp_line* xivovp_line_from_ctx(VpLineCtxType* line_ctx)
Vp890LineObjectType* line_obj;
int i;
- if(!line_ctx) {
- printk(KERN_ERR DRV_NAME ": LineCtx == NULL\n");
- return NULL;
- }
+ if(!line_ctx)
+ panic(DRV_NAME ": LineCtx == NULL\n");
line_obj = line_ctx->pLineObj;
@@ -96,7 +98,7 @@ static struct xivovp_line* xivovp_line_from_ctx(VpLineCtxType* line_ctx)
if(&xivovp.line[i].line_obj == line_obj)
return &xivovp.line[i];
- printk(KERN_ERR DRV_NAME ": unknown FX line, this shouldn't happen\n");
+ panic(DRV_NAME ": unknown FX line, this shouldn't happen\n");
return NULL;
}
@@ -123,13 +125,16 @@ static void vp_set_debug_select_running(void)
static int xivovp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
{
struct xivovp_line* line = chan->pvt;
+ unsigned long flags;
if(line->txsig_queue_len >= ARRAY_SIZE(line->txsig_queue)) {
printk(KERN_WARNING DRV_NAME "(chan %d): txsig overrun", chan->chanpos);
return -1;
}
+ spin_lock_irqsave(&line->lock, flags);
line->txsig_queue[line->txsig_queue_len++] = txsig;
+ spin_unlock_irqrestore(&line->lock, flags);
return 0;
}
@@ -182,15 +187,21 @@ static void xivovp_hooksig_pvt(struct xivovp_line* line, enum dahdi_txsig txsig)
static void xivovp_handle_txsig_queue(void)
{
static int said;
- int i, j;
+ int i, j, k;
+ enum dahdi_txsig txsig_queue[TXQUEUE_LEN];
+ unsigned long flags;
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]);
- }
+ spin_lock_irqsave(&xivovp.line[i].lock, flags);
+ for(j = 0; j < xivovp.line[i].txsig_queue_len; j++)
+ txsig_queue[j] = xivovp.line[i].txsig_queue[j];
xivovp.line[i].txsig_queue_len = 0;
+ spin_unlock_irqrestore(&xivovp.line[i].lock, flags);
+
+ for(k = 0; k < j; k++)
+ xivovp_hooksig_pvt(&xivovp.line[i],
+ txsig_queue[k]);
} else if(!said) {
said = 1;
printk(KERN_WARNING DRV_NAME ": txsig pending but calibration not done yet! Waiting...\n");
@@ -353,7 +364,7 @@ static void vp_tick(const unsigned long data)
vpst = VpGetResults(&event, &result);
if (vpst != VP_STATUS_SUCCESS) {
printk(KERN_ERR DRV_NAME ": VpGetResults returned %d\n", (int) vpst);
- return;
+ return; // TOTHINK
}
}
}
@@ -389,20 +400,22 @@ span_init(void)
xivovp.span.ops = &xivovp_span_ops;
xivovp.span.channels = ARRAY_SIZE(xivovp.chans);
xivovp.span.chans = xivovp.chans;
- xivovp.span.deflaw = DAHDI_LAW_MULAW; // TODO alawoverride
+ xivovp.span.deflaw = alawoverride ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
+ xivovp.span.flags = DAHDI_FLAG_RBS;
init_waitqueue_head(&xivovp.span.maintq); /* still dunno what this is */
for(l = xivovp.line; l < xivovp.line + NB_LINES; l++) {
xivovp.chans[l - xivovp.line] = &l->chan;
l->chan.pvt = l;
- if(l->type == FXS_LINE)
+ if(l->type == FXO_LINE)
+ /* /!\ FXO uses FXS sig and vice-versa */
l->chan.sigcap = DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS |
DAHDI_SIG_FXSKS;
else
l->chan.sigcap = DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS |
DAHDI_SIG_FXOKS;
- spin_lock_init(&l->vp_lock);
+ spin_lock_init(&l->lock);
}
if(dahdi_register(&xivovp.span, /*prefmaster*/ 0)) {
@@ -548,7 +561,9 @@ test_evb_ve890_exit(void)
dahdi_unregister(&xivovp.span);
- del_timer_sync(&xivovp.vp_tick_timer); /* XXX : TODO update upstream Linux doc of del_timer_sync */
+ del_timer_sync(&xivovp.vp_tick_timer);
+ del_timer_sync(&rxtx_timer);
+ /* XXX : TODO update upstream Linux doc of del_timer_sync */
tlp_spidev_exit();
}