http://bugzilla.openmoko.org/cgi-bin/bugzilla/show_bug.cgi?id=766

From: Cesar Eduardo Barros <cesarb@cesarb.net>

Fix gsmd getting "stuck"

This last patch fixes the remaining problem: on reset, when receiving the
"AT-Command Interpreter ready", gsmd was getting stuck. The cause was that
the ATZ command was not being removed from g->busy_atcmds, meaning
GSMD_FD_WRITE would not get set again. To compound the problem, in that
case it never even reached the line which set the flag.

This patch does the following:
  1. Checks for g->busy_atcmds on atcmd_submit()
  2. Shuffles the order of the first few code blocks on ml_parse(), so cmd
     will get set before checking for the interpreter ready condition
  3. When getting "AT-Command Interpreter ready", generates a fake ERROR
     responseand goes directly to final_cb; this runs all normal processing
     for the command (which can depend on the command's callback), dequeues
     it, and sets GSMD_FD_WRITE if needed.

As an aside: with this patch, there's no need for all the powering
off/on/off/on dance on /etc/init.d/gsmd, which helps avoid hitting
bugzilla #788.

Signed-off-by: Jim Huang <jserv@openmoko.org>
---
 gsm/src/gsmd/atcmd.c |   30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

Index: gsm/src/gsmd/atcmd.c
===================================================================
--- gsm.orig/src/gsmd/atcmd.c	2007-09-17 23:45:41.000000000 +0800
+++ gsm/src/gsmd/atcmd.c	2007-09-18 00:26:17.000000000 +0800
@@ -209,16 +209,6 @@
 
 	DEBUGP("buf=`%s'(%d)\n", buf, len);
 
-	/* FIXME: This needs to be part of the vendor plugin. If we receive
-	 * an empty string or that 'ready' string, we need to init the modem */
-	if (strlen(buf) == 0 ||
-	    !strcmp(buf, "AT-Command Interpreter ready")) {
-		g->interpreter_ready = 1;
-		gsmd_initsettings(g);
-		gmsd_alive_start(g);
-		return 0;
-	}
-
 	/* responses come in order, so first response has to be for first
 	 * command we sent, i.e. first entry in list */
 	if (!llist_empty(&g->busy_atcmds))
@@ -230,6 +220,24 @@
 		return 0;
 	}
 
+	/* FIXME: This needs to be part of the vendor plugin. If we receive
+	 * an empty string or that 'ready' string, we need to init the modem */
+	if (strlen(buf) == 0 ||
+	    !strcmp(buf, "AT-Command Interpreter ready")) {
+		g->interpreter_ready = 1;
+		gsmd_initsettings(g);
+		gmsd_alive_start(g);
+
+		/* generate a synthetic ERROR response */
+		DEBUGP("synthetic error\n");
+		g->mlbuf_len = 0;
+		buf = "ERROR";
+		if (cmd)
+			cmd->ret = 4;
+		/* we must go through final_cb so the command is dequeued */
+		goto final_cb;
+	}
+
 	/* we have to differentiate between the following cases:
 	 *
 	 * A) an information response ("+whatever: ...")
@@ -523,7 +531,7 @@
 {
 	DEBUGP("submitting command `%s'\n", cmd->buf);
 
-	if (llist_empty(&g->pending_atcmds))
+	if (llist_empty(&g->pending_atcmds) && llist_empty(&g->busy_atcmds))
 		g->gfd_uart.when |= GSMD_FD_WRITE;
 	llist_add_tail(&cmd->list, &g->pending_atcmds);
 
