wcte43x: Do not grab reglock in handle_transmit/handle_receive.
If the driver is loaded with vpmsupport=0, then it was possible to create a deadlock situation since the call into __dahdi_ec_chunk might then try to grab the channel lock while already holding the reglock. The purpose of grabbing reglock in the DMA routines was to protect the channel array, which can be changed when linemode is changing. So instead, we'll completely mask off that interrupt line from all CPUs when potentially changing the channel array. Signed-off-by: Shaun Ruffell <sruffell@digium.com>
This commit is contained in:
parent
b3c6320374
commit
cbad5a7ae1
@ -2454,10 +2454,9 @@ t43x_init_one_span(struct t43x *wc, struct t43x_span *ts, enum linemode type)
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
/* Stop the interrupt handler so that we may swap the channel array. */
|
||||
disable_irq(wc->xb.pdev->irq);
|
||||
|
||||
/* Because the interrupt handler is running, we need to atomically
|
||||
* swap the channel arrays. */
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
for (x = 0; x < ARRAY_SIZE(ts->chans); x++) {
|
||||
kfree(ts->chans[x]);
|
||||
@ -2997,7 +2996,6 @@ static void t43x_handle_receive(struct wcxb *xb, void *vfp)
|
||||
if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &ts->span.flags))
|
||||
continue;
|
||||
|
||||
spin_lock(&wc->reglock);
|
||||
for (j = 0; j < DAHDI_CHUNKSIZE; j++) {
|
||||
for (i = 0; i < ts->span.channels; i++) {
|
||||
ts->chans[i]->readchunk[j] =
|
||||
@ -3012,7 +3010,6 @@ static void t43x_handle_receive(struct wcxb *xb, void *vfp)
|
||||
c->writechunk);
|
||||
}
|
||||
}
|
||||
spin_unlock(&wc->reglock);
|
||||
|
||||
_dahdi_receive(&ts->span);
|
||||
}
|
||||
@ -3034,12 +3031,10 @@ static void t43x_handle_transmit(struct wcxb *xb, void *vfp)
|
||||
|
||||
_dahdi_transmit(&ts->span);
|
||||
|
||||
spin_lock(&wc->reglock);
|
||||
for (j = 0; j < DAHDI_CHUNKSIZE; j++)
|
||||
for (i = 0; i < ts->span.channels; i++)
|
||||
frame[j*WCXB_DMA_CHAN_SIZE+(s+1+i*4)] =
|
||||
ts->chans[i]->writechunk[j];
|
||||
spin_unlock(&wc->reglock);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user