$NetBSD: patch-af,v 1.2 2009/02/21 18:54:41 gdt Exp $

From Giles Lean, who places it in the public domain.  Workarounds for
problems with buggy USB serial adapators.  Not applied by upstream
2009-02-21 because it's too dangerous to work around problems without
understanding them.

--- jeeps/gpsread.c.orig	2010-03-26 03:09:20.000000000 +0000
+++ jeeps/gpsread.c
@@ -103,6 +103,36 @@ int32 GPS_Serial_Packet_Read(gpsdevh *fd
 
 	    if(!len)
 	    {
+                /*
+                 * Missed DLE characters have been observed with Geko
+                 * 201 and Legend GPSRs with Prolific USB-serial
+                 * cables.  The following kludge seems to help.
+                 *
+                 * It has been tested so far with the following
+                 * combinations of software and hardware:
+                 *
+                 * OS X 10.4.x and 10.5.x:
+                 *
+                 * - a Geko 201 (firmware version 2.70) and a third
+                 *   party cable using a Prolific USB-serial converter
+                 * - a Legend using a serial cable with a non-integral
+                 *   Prolific USB-serial converter.
+                 *
+                 * NetBSD-4.0/i386 with the Geko and cable as above.
+                 *
+                 * REVISIT GFL Should this be a switch in a .ini file?
+                 *
+                 * + it's a kludge, so leaving it always on is ugly
+                 * - if it's harmless to properly working hardware,
+                 *   then it's a better user experience to leave it on
+                 */
+                if (u == 0x06 || u == 0x15)
+                {
+                    ++len;
+		    (void) fprintf(stderr,"GPS_Packet_Read: inserted DLE due to 0x%02x.\n", u);
+                    goto dle_missed;
+                }
+
 		if(u != DLE)
 		{
 		    (void) fprintf(stderr,"GPS_Packet_Read: No DLE.  Data received, but probably not a garmin packet.\n");
@@ -113,6 +143,7 @@ int32 GPS_Serial_Packet_Read(gpsdevh *fd
 		continue;
 	    }
 
+dle_missed:
 	    if(len==1)
 	    {
 		(*packet)->type = u;
@@ -215,6 +246,20 @@ int32 GPS_Serial_Get_Ack(gpsdevh *fd, GP
     
     if(*(*rec)->data != (*tra)->type)
     {
+        /*
+         * When used with a buggy Prolific USB-serial converter the
+         * calling sequence GPS_A000() -> GPS_Get_Ack() sometimes
+         * returns data != type causing this routine to fail and the
+         * following error message to be emitted:
+         *
+         *   GARMIN:Can't init /dev/cu.usbserial
+         *
+         * Manually retrying usually works, and subsequent
+         * investigation shows that the call that fails is made from
+         * GPS_Init() which in this case is GPS_Serial_Init().  Simply
+         * retrying the call a workaround: see note and retry loop in
+         * gpsapp.c:GPS_Init().
+         */
 	gps_error = FRAMING_ERROR;
 	return 0;
     }
