提交 4cb5e42f 编写于 作者: T Tilman Schmidt 提交者: David S. Miller

isdn/gigaset: unclog bas_gigaset AT response pipe

Recover from a lost HD_RECEIVEATDATA_ACK message by sending a
zero-length HD_READ_ATMESSAGE command when ev_layer sends "+++".
Signed-off-by: NTilman Schmidt <tilman@imap.cc>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 60798c68
...@@ -1896,6 +1896,28 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) ...@@ -1896,6 +1896,28 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
* The next command will reopen the AT channel automatically. * The next command will reopen the AT channel automatically.
*/ */
if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) {
/* If an HD_RECEIVEATDATA_ACK message remains unhandled
* because of an error, the base never sends another one.
* The response channel is thus effectively blocked.
* Closing and reopening the AT channel does *not* clear
* this condition.
* As a stopgap measure, submit a zero-length AT read
* before closing the AT channel. This has the undocumented
* effect of triggering a new HD_RECEIVEATDATA_ACK message
* from the base if necessary.
* The subsequent AT channel close then discards any pending
* messages.
*/
spin_lock_irqsave(&cs->lock, flags);
if (!(cs->hw.bas->basstate & BS_ATRDPEND)) {
kfree(cs->hw.bas->rcvbuf);
cs->hw.bas->rcvbuf = NULL;
cs->hw.bas->rcvbuf_size = 0;
cs->hw.bas->retry_cmd_in = 0;
atread_submit(cs, 0);
}
spin_unlock_irqrestore(&cs->lock, flags);
rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
if (cb->wake_tasklet) if (cb->wake_tasklet)
tasklet_schedule(cb->wake_tasklet); tasklet_schedule(cb->wake_tasklet);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册