From be2e4b79a6d7d5518ad950db969345dd8528943f Mon Sep 17 00:00:00 2001
From: Colin O Flynn <coflynn@newae.com>
Date: Wed, 2 May 2007 23:05:21 +0000
Subject: [PATCH] 2007-05-01:    Colin O'Flynn <coflynn@newae.com>   *Problem
 in verbose output of previous commit. I hoped to    have all the verbose
 changes in a single commit, but that    won't happen...   *Main thing is
 fixed safemode to turn itself off when you can't    read the fuses anyway. I
 don't know what I was thinking when    I made it fail out of programmers that
 don't support fuse reading.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@733 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog  |  6 ++++++
 main.c     | 38 +++++++++++++++++++++++++---------
 safemode.c | 60 ++++++++++++++++++++++++++++++++++++++----------------
 3 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4833be61..c10ea0c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-05-01 Colin O'Flynn <coflynn@newae.com>
+    * safemode.c: -Oops - bug in verbose output. Fixed.
+                  -Fixed handling of cases where programmer cannot read fuses (AVR910)
+    * main.c:     -Also fixing handling of cases where programmer cannot read fuses
+                  This should close one or more bugs (18803, 19570)
+
 2007-05-01 Colin O'Flynn <coflynn@newae.com>
     * safemode.c: Added verbose output from safemode routines.
 
diff --git a/main.c b/main.c
index 1e20a320..860fafac 100644
--- a/main.c
+++ b/main.c
@@ -856,17 +856,35 @@ int main(int argc, char * argv [])
     /* If safemode is enabled, go ahead and read the current low, high,
        and extended fuse bytes as needed */
 
-    if (safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
-                           &safemode_efuse, &safemode_fuse, pgm, p, verbose) != 0) {
-      fprintf(stderr, "%s: safemode: To protect your AVR the programming "
-              "will be aborted\n",
-              progname);
-      exitrc = 1;
-      goto main_exit;
-    }
+	rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
+                           &safemode_efuse, &safemode_fuse, pgm, p, verbose);
 
-    //Save the fuses as default
-    safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
+    if (rc != 0) {
+
+	  //Check if the programmer just doesn't support reading
+	  if (rc == -5)
+			{
+			if (verbose > 0)
+				{
+				fprintf(stderr, "%s: safemode: Fuse reading not support by programmer.\n"
+                	            "              Safemode disabled.\n", progname);
+				}
+			safemode = 0;
+			}
+      else
+			{
+
+      		fprintf(stderr, "%s: safemode: To protect your AVR the programming "
+            				    "will be aborted\n",
+               					 progname);
+      		exitrc = 1;
+		    goto main_exit;
+			}
+    }
+	else  {
+	    //Save the fuses as default
+    	safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
+	}
   }
 
 
diff --git a/safemode.c b/safemode.c
index aea73ddd..62d02afa 100644
--- a/safemode.c
+++ b/safemode.c
@@ -2,7 +2,7 @@
  * avrdude - A Downloader/Uploader for AVR device programmers
  * avrdude is Copyright (C) 2000-2004  Brian S. Dean <bsd@bsdhome.com>
  *
- * This file: Copyright (C) 2005 Colin O'Flynn <coflynn@newae.com>
+ * This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -86,6 +86,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
 
   unsigned char value;
   unsigned char fusegood = 0;
+  unsigned char allowfuseread = 1;
   unsigned char safemode_lfuse;
   unsigned char safemode_hfuse;
   unsigned char safemode_efuse;
@@ -106,7 +107,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     fusegood = 0; /* By default fuse is a failure */
     if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
         {
-        safemode_fuse = 1 + value; //failed - ensure they differ
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
@@ -114,7 +115,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
 		}
     if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
         {
-        value = 1 + safemode_fuse; //failed - ensure they differ
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
@@ -123,7 +124,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     if (value == safemode_fuse) {
         if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
             {
-            value = 1 + safemode_fuse;
+            allowfuseread = 0;
             }
 		if (verbose > 2)
 			{
@@ -136,6 +137,12 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     }
   } 
 
+	//Programmer does not allow fuse reading.... no point trying anymore
+    if (allowfuseread == 0)
+		{
+		return -5;
+		}
+
     if (fusegood == 0)   {
         fprintf(stderr,
            "%s: safemode: Verify error - unable to read fuse properly. "
@@ -155,15 +162,15 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     fusegood = 0; /* By default fuse is a failure */
     if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
         {
-        safemode_lfuse = 1 + value;
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
-		fprintf(stderr, "%s: safemode read 1, lfuse value: %x\n",progname,  safemode_fuse);
+		fprintf(stderr, "%s: safemode read 1, lfuse value: %x\n",progname,  safemode_lfuse);
 		}
     if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
         {
-        value = safemode_lfuse + 1;
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
@@ -172,7 +179,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     if (value == safemode_lfuse) {
         if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
             {
-            value = safemode_lfuse + 1;
+            allowfuseread = 0;
             }
 		if (verbose > 2)
 			{
@@ -184,6 +191,13 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     }
   }
 
+	//Programmer does not allow fuse reading.... no point trying anymore
+    if (allowfuseread == 0)
+		{
+		return -5;
+		}
+
+
     if (fusegood == 0)	 {
         fprintf(stderr,
            "%s: safemode: Verify error - unable to read lfuse properly. "
@@ -202,15 +216,15 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     fusegood = 0; /* By default fuse is a failure */
     if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
         {
-        safemode_hfuse = value + 1;
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
-		fprintf(stderr, "%s: safemode read 1, hfuse value: %x\n",progname,  safemode_fuse);
+		fprintf(stderr, "%s: safemode read 1, hfuse value: %x\n",progname,  safemode_hfuse);
 		}
     if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
         {
-        value = safemode_hfuse + 1;
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
@@ -219,7 +233,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     if (value == safemode_hfuse) {
         if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
             {
-            value = safemode_hfuse + 1;
+            allowfuseread = 0;
             }
 		if (verbose > 2)
 			{
@@ -231,6 +245,12 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     }
   }
 
+	//Programmer does not allow fuse reading.... no point trying anymore
+    if (allowfuseread == 0)
+		{
+		return -5;
+		}
+
     if (fusegood == 0)	 {
             fprintf(stderr,
            "%s: safemode: Verify error - unable to read hfuse properly. "
@@ -249,15 +269,15 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     fusegood = 0; /* By default fuse is a failure */
     if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
         {
-        safemode_efuse = value + 1;
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
-		fprintf(stderr, "%s: safemode read 1, efuse value: %x\n",progname, safemode_fuse);
+		fprintf(stderr, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
 		}
     if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
         {
-        value = safemode_efuse + 1;
+        allowfuseread = 0;
         }
 	if (verbose > 2)
 		{
@@ -266,7 +286,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
     if (value == safemode_efuse) {
         if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
             {
-            value = safemode_efuse + 1;
+            allowfuseread = 0;
             }
 		if (verbose > 2)
 			{
@@ -277,7 +297,13 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
         }
     }
   }
-    
+   
+	//Programmer does not allow fuse reading.... no point trying anymore
+    if (allowfuseread == 0)
+		{
+		return -5;
+		}
+ 
     if (fusegood == 0)	 {
         fprintf(stderr,
            "%s: safemode: Verify error - unable to read efuse properly. "