$NetBSD: patch-af,v 1.6 2019/05/02 19:01:17 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.cc.orig	2019-04-14 02:32:25.000000000 +0000
+++ jeeps/gpsread.cc
@@ -95,6 +95,37 @@ int32 GPS_Serial_Packet_Read(gpsdevh* fd
       GPS_Diag("%02x ", u);
 
       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");
           (void) fflush(stderr);
@@ -104,6 +135,7 @@ int32 GPS_Serial_Packet_Read(gpsdevh* fd
         continue;
       }
 
+    dle_missed:
       if (len == 1) {
         (*packet).type = u;
         ++len;
@@ -127,6 +159,20 @@ int32 GPS_Serial_Packet_Read(gpsdevh* fd
       if (u == ETX)
         if (isDLE) {
           if (p - (*packet).data - 2 != (*packet).n) {
+	    /*
+	     * 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("GPS_Packet_Read: Bad count");
             gps_errno = FRAMING_ERROR;
             return 0;
