Index: drivers/dahdi/wctdm24xxp/base.c =================================================================== --- drivers/dahdi/wctdm24xxp/base.c (revision 8983) +++ drivers/dahdi/wctdm24xxp/base.c (working copy) @@ -1375,9 +1375,28 @@ #else spin_lock_irqsave(&fxs->lasttxhooklock, flags); res = wc->cmdq[card].isrshadow[1]; + /* This makes sure the lasthook was put in reg 64 the linefeed reg */ - if (((res & SLIC_LF_SETMASK) | SLIC_LF_OPPENDING) == fxs->lasttxhook) - fxs->lasttxhook &= SLIC_LF_SETMASK; + if (fxs->lasttxhook & SLIC_LF_OPPENDING) { + if ((res & SLIC_LF_SETMASK) == (fxs->lasttxhook & SLIC_LF_SETMASK)) { + fxs->lasttxhook &= SLIC_LF_SETMASK; + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, "SLIC_LF OK: intcount=%d channel=%d shadow=%02x lasttxhook=%02x\n", wc->intcount, card, res, fxs->lasttxhook); + } + } else if (!(wc->intcount & 0x03)) { + wc->sethook[card] = CMD_WR(LINE_STATE, fxs->lasttxhook); + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, "SLIC_LF RETRY: intcount=%d channel=%d shadow=%02x lasttxhook=%02x\n", wc->intcount, card, res, fxs->lasttxhook); + } + } + } +#if 0 + if (debug & DEBUG_CARD) { + if (!(wc->intcount % 100)) { + dev_info(&wc->vb.pdev->dev, "SLIC_LF DEBUG: intcount=%d channel=%d shadow=%02x lasttxhook=%02x\n", wc->intcount, card, res, fxs->lasttxhook); + } + } +#endif res = !res && /* reg 64 has to be zero at last isr read */ !(fxs->lasttxhook & SLIC_LF_OPPENDING) && /* not a transition */ @@ -1943,26 +1962,40 @@ fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_OHTRAN_REV : SLIC_LF_OHTRAN_FWD; } else if (fxs->ohttimer) { - fxs->ohttimer -= DAHDI_CHUNKSIZE; - if (fxs->ohttimer) - return; + /* check if still OnHook */ + if (!fxs->oldrxhook) { + fxs->ohttimer -= DAHDI_CHUNKSIZE; + if (fxs->ohttimer) + return; - /* Switch to active */ - fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_ACTIVE_REV : - SLIC_LF_ACTIVE_FWD; - spin_lock_irqsave(&fxs->lasttxhooklock, flags); - if (SLIC_LF_OHTRAN_FWD == fxs->lasttxhook) { - /* Apply the change if appropriate */ - fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_FWD; - /* Data enqueued here */ - wc->sethook[card] = CMD_WR(LINE_STATE, fxs->lasttxhook); - } else if (SLIC_LF_OHTRAN_REV == fxs->lasttxhook) { - /* Apply the change if appropriate */ - fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_REV; - /* Data enqueued here */ - wc->sethook[card] = CMD_WR(LINE_STATE, fxs->lasttxhook); + /* Switch to active */ + fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_ACTIVE_REV : + SLIC_LF_ACTIVE_FWD; + spin_lock_irqsave(&fxs->lasttxhooklock, flags); + if (SLIC_LF_OHTRAN_FWD == fxs->lasttxhook) { + /* Apply the change if appropriate */ + fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_FWD; + /* Data enqueued here */ + wc->sethook[card] = CMD_WR(LINE_STATE, fxs->lasttxhook); + if (debug & DEBUG_CARD) + dev_info(&wc->vb.pdev->dev, "Channel %d OnHookTransfer stop\n", card ); + } else if (SLIC_LF_OHTRAN_REV == fxs->lasttxhook) { + /* Apply the change if appropriate */ + fxs->lasttxhook = SLIC_LF_OPPENDING | SLIC_LF_ACTIVE_REV; + /* Data enqueued here */ + wc->sethook[card] = CMD_WR(LINE_STATE, fxs->lasttxhook); + if (debug & DEBUG_CARD) + dev_info(&wc->vb.pdev->dev, "Channel %d OnHookTransfer stop\n", card ); + } + spin_unlock_irqrestore(&fxs->lasttxhooklock, flags); + } else { + fxs->ohttimer = 0; + /* Switch to active */ + fxs->idletxhookstate = POLARITY_XOR(card) ? SLIC_LF_ACTIVE_REV : SLIC_LF_ACTIVE_FWD; + if (debug & DEBUG_CARD) + dev_info(&wc->vb.pdev->dev, "Channel %d OnHookTransfer abort\n", card ); } - spin_unlock_irqrestore(&fxs->lasttxhooklock, flags); + } } @@ -3119,21 +3152,39 @@ return -EINVAL; /* Can't change polarity while ringing or when open */ if (((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_RINGING) || - ((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_OPEN)) + ((fxs->lasttxhook & SLIC_LF_SETMASK) == SLIC_LF_OPEN)) { + if (debug & DEBUG_CARD) { + dev_info(&wc->vb.pdev->dev, "Channel %d Unable to Set Polarity\n", chan->chanpos - 1 ); + } return -EINVAL; + } fxs->reversepolarity = (x) ? 1 : 0; - if (POLARITY_XOR(chan->chanpos -1)) { + if (POLARITY_XOR(chan->chanpos - 1)) { fxs->idletxhookstate |= SLIC_LF_REVMASK; - x = fxs->lasttxhook; + x = fxs->lasttxhook & SLIC_LF_SETMASK; x |= SLIC_LF_REVMASK; - set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]); + x = set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]); + if (debug & DEBUG_CARD) { + if (x){ + dev_info(&wc->vb.pdev->dev, "Channel %d TIMEOUT: Set Reverse Polarity\n", chan->chanpos - 1); + } else { + dev_info(&wc->vb.pdev->dev, "Channel %d Set Reverse Polarity\n", chan->chanpos - 1); + } + } } else { fxs->idletxhookstate &= ~SLIC_LF_REVMASK; - x = fxs->lasttxhook; + x = fxs->lasttxhook & SLIC_LF_SETMASK; x &= ~SLIC_LF_REVMASK; - set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]); + x = set_lasttxhook_interruptible(fxs, x, &wc->sethook[chan->chanpos - 1]); + if (debug & DEBUG_CARD) { + if (x){ + dev_info(&wc->vb.pdev->dev, "Channel %d TIMEOUT: Set Normal Polarity\n", chan->chanpos - 1 ); + } else { + dev_info(&wc->vb.pdev->dev, "Channel %d Set Normal Polarity\n", chan->chanpos - 1 ); + } + } } break; case DAHDI_RADIO_GETPARAM: