diff --git a/ChangeLog b/ChangeLog
index e69de29b..1f1bff35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1,26 @@
+2018-01-10  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
+	patch #9507: Fix UPDI chip erase
+	* lexer.l (family_id): New keyword.
+	* config_gram.y: (Ditto)
+	* doc/avrdude.texi: Document new keyword
+	* avrdude.conf.in: Add family_id for avr8x devices
+	* avr.c: Pass error code up.
+	* jtag3.c: Pass error code from memory read up; implement
+	jtag3_read_sib()
+	* libavrdude.h: Add new items.
+	* main.c: Implement different chip erase handling required
+	for UPDI devices.
+
+2018-01-10  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
+	patch #9506: Script to create device configuration stub from Atmel ATDF files
+	* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
+	(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
+	(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
+	(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
+	(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
+	(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
+
diff --git a/NEWS b/NEWS
index d39268e9..9b9671fd 100644
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,13 @@ Current:
   * New devices supported:
 
     - ATmega328PB
-    - AVR8X family, ATtiny1617, ATtiny817
+    - AVR8X family, ATtiny1617, ATtiny817, ATtiny202, ATtiny204,
+      ATtiny402, ATtiny404, ATtiny406, ATtiny804, ATtiny806,
+      ATtiny807, ATtiny1604, ATtiny1606, ATtiny1607, ATtiny212,
+      ATtiny214, ATtiny412, ATTiny414, ATtiny416, ATtiny417,
+      ATtiny814, ATtiny816, ATtiny1614, ATtiny1616, ATtiny3214,
+      ATtiny3216, ATtiny3217, ATmega3208, ATmega3209, ATmega4808,
+      ATmega4809
 
   * New programmers supported:
 
diff --git a/avr.c b/avr.c
index 8df586a3..fa46f498 100644
--- a/avr.c
+++ b/avr.c
@@ -438,11 +438,15 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
     {
       rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
       if (rc != 0) {
-	avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
-	if (rc == -1)
-	  avrdude_message(MSG_INFO, "    read operation not supported for memory \"%s\"\n",
+        avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
+        if (rc == -1) {
+          avrdude_message(MSG_INFO, "    read operation not supported for memory \"%s\"\n",
                           memtype);
-	return -2;
+          return -2;
+        }
+        avrdude_message(MSG_INFO, "    read operation failed for memory \"%s\"\n",
+                        memtype);
+        return rc;
       }
     }
     report_progress(i, mem->size, NULL);
@@ -1051,7 +1055,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
   if (rc < 0) {
     avrdude_message(MSG_INFO, "%s: error reading signature data for part \"%s\", rc=%d\n",
                     progname, p->desc, rc);
-    return -1;
+    return rc;
   }
   report_progress (1,1,NULL);
 
diff --git a/avrdude.conf.in b/avrdude.conf.in
index a1f03024..339b90f4 100644
--- a/avrdude.conf.in
+++ b/avrdude.conf.in
@@ -15140,26 +15140,482 @@ part
 ;
 
 #------------------------------------------------------------
-# ATtiny1617
+# AVR8X tiny family common values
 #------------------------------------------------------------
 
-part parent ".avr8x"
-    id		= "tn1617";
-    desc	= "ATtiny1617";
-    signature	= 0x1e 0x94 0x20;
+part parent    ".avr8x"
+    id			= ".avr8x_tiny";
+    desc		= "AVR8X tiny family common values";
+    family_id	= "tinyAVR";
+;
 
-    memory "eeprom"
-        size		= 0x0100;
-        offset		= 0x1400;
-        page_size	= 0x20;
-        readsize	= 0x100;
-    ;
+#------------------------------------------------------------
+# AVR8X mega family common values
+#------------------------------------------------------------
+
+part parent    ".avr8x"
+    id			= ".avr8x_mega";
+    desc		= "AVR8X mega family common values";
+    family_id	= "megaAVR";
+;
+
+#------------------------------------------------------------
+# ATtiny202
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t202";
+    desc      = "ATtiny202";
+    signature = 0x1E 0x91 0x23;
 
     memory "flash"
-        size		= 0x4000;
-        offset		= 0x8000;
-        page_size	= 0x40;
-        readsize	= 0x100;
+        size      = 0x800;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x40;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny204
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t204";
+    desc      = "ATtiny204";
+    signature = 0x1E 0x91 0x22;
+
+    memory "flash"
+        size      = 0x800;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x40;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny402
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t402";
+    desc      = "ATtiny402";
+    signature = 0x1E 0x92 0x23;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny404
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t404";
+    desc      = "ATtiny404";
+    signature = 0x1E 0x92 0x26;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny406
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t406";
+    desc      = "ATtiny406";
+    signature = 0x1E 0x92 0x25;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny804
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t804";
+    desc      = "ATtiny804";
+    signature = 0x1E 0x93 0x25;
+
+    memory "flash"
+        size      = 0x2000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny806
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t806";
+    desc      = "ATtiny806";
+    signature = 0x1E 0x93 0x24;
+
+    memory "flash"
+        size      = 0x2000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny807
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t807";
+    desc      = "ATtiny807";
+    signature = 0x1E 0x93 0x23;
+
+    memory "flash"
+        size      = 0x2000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny1604
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t1604";
+    desc      = "ATtiny1604";
+    signature = 0x1E 0x94 0x25;
+
+    memory "flash"
+        size      = 0x4000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny1606
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t1606";
+    desc      = "ATtiny1606";
+    signature = 0x1E 0x94 0x24;
+
+    memory "flash"
+        size      = 0x4000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny1607
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t1607";
+    desc      = "ATtiny1607";
+    signature = 0x1E 0x94 0x23;
+
+    memory "flash"
+        size      = 0x4000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny212
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t212";
+    desc      = "ATtiny212";
+    signature = 0x1E 0x91 0x21;
+
+    memory "flash"
+        size      = 0x800;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x40;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny214
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t214";
+    desc      = "ATtiny214";
+    signature = 0x1E 0x91 0x20;
+
+    memory "flash"
+        size      = 0x800;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x40;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny412
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t412";
+    desc      = "ATtiny412";
+    signature = 0x1E 0x92 0x23;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+
+#------------------------------------------------------------
+# ATtiny414
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t414";
+    desc      = "ATtiny414";
+    signature = 0x1E 0x92 0x22;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny416
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t416";
+    desc      = "ATtiny416";
+    signature = 0x1E 0x92 0x21;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+
+#------------------------------------------------------------
+# ATtiny417
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t417";
+    desc      = "ATtiny417";
+    signature = 0x1E 0x92 0x20;
+
+    memory "flash"
+        size      = 0x1000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+
+#------------------------------------------------------------
+# ATtiny814
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t814";
+    desc      = "ATtiny814";
+    signature = 0x1E 0x93 0x22;
+
+    memory "flash"
+        size      = 0x2000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+
+#------------------------------------------------------------
+# ATtiny816
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t816";
+    desc      = "ATtiny816";
+    signature = 0x1E 0x93 0x21;
+
+    memory "flash"
+        size      = 0x2000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
     ;
 ;
 
@@ -15167,22 +15623,262 @@ part parent ".avr8x"
 # ATtiny817
 #------------------------------------------------------------
 
-part parent ".avr8x"
-    id		= "tn817";
-    desc	= "ATtiny817";
-    signature	= 0x1e 0x93 0x20;
-
-    memory "eeprom"
-        size		= 0x0100;
-        offset		= 0x1400;
-        page_size	= 0x20;
-        readsize	= 0x100;
-    ;
+part parent    ".avr8x_tiny"
+    id        = "t817";
+    desc      = "ATtiny817";
+    signature = 0x1E 0x93 0x20;
 
     memory "flash"
-        size		= 0x2000;
-        offset		= 0x8000;
-        page_size	= 0x40;
-        readsize	= 0x100;
+        size      = 0x2000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x80;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny1614
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t1614";
+    desc      = "ATtiny1614";
+    signature = 0x1E 0x94 0x22;
+
+    memory "flash"
+        size      = 0x4000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny1616
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t1616";
+    desc      = "ATtiny1616";
+    signature = 0x1E 0x94 0x21;
+
+    memory "flash"
+        size      = 0x4000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny1617
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t1617";
+    desc      = "ATtiny1617";
+    signature = 0x1E 0x94 0x20;
+
+    memory "flash"
+        size      = 0x4000;
+        offset    = 0x8000;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x20;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny3214
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t3214";
+    desc      = "ATtiny3214";
+    signature = 0x1E 0x95 0x20;
+
+    memory "flash"
+        size      = 0x8000;
+        offset    = 0x8000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny3216
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t3216";
+    desc      = "ATtiny3216";
+    signature = 0x1E 0x95 0x21;
+
+    memory "flash"
+        size      = 0x8000;
+        offset    = 0x8000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATtiny3217
+#------------------------------------------------------------
+
+part parent    ".avr8x_tiny"
+    id        = "t3217";
+    desc      = "ATtiny3217";
+    signature = 0x1E 0x95 0x22;
+
+    memory "flash"
+        size      = 0x8000;
+        offset    = 0x8000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATmega3208
+#------------------------------------------------------------
+
+part parent    ".avr8x_mega"
+    id        = "m3208";
+    desc      = "ATmega3208";
+    signature = 0x1E 0x95 0x52;
+
+    memory "flash"
+        size      = 0x8000;
+        offset    = 0x4000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATmega3209
+#------------------------------------------------------------
+
+part parent    ".avr8x_mega"
+    id        = "m3209";
+    desc      = "ATmega3209";
+    signature = 0x1E 0x95 0x53;
+
+    memory "flash"
+        size      = 0x8000;
+        offset    = 0x4000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATmega4808
+#------------------------------------------------------------
+
+part parent    ".avr8x_mega"
+    id        = "m4808";
+    desc      = "ATmega4808";
+    signature = 0x1E 0x96 0x50;
+
+    memory "flash"
+        size      = 0xC000;
+        offset    = 0x4000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
+    ;
+;
+
+#------------------------------------------------------------
+# ATmega4809
+#------------------------------------------------------------
+
+part parent    ".avr8x_mega"
+    id        = "m4809";
+    desc      = "ATmega4809";
+    signature = 0x1E 0x96 0x51;
+
+    memory "flash"
+        size      = 0xC000;
+        offset    = 0x4000;
+        page_size = 0x80;
+        readsize  = 0x100;
+    ;
+
+    memory "eeprom"
+        size      = 0x100;
+        offset    = 0x1400;
+        page_size = 0x40;
+        readsize  = 0x100;
     ;
 ;
diff --git a/config_gram.y b/config_gram.y
index 21dccb0b..0b50064f 100644
--- a/config_gram.y
+++ b/config_gram.y
@@ -80,6 +80,7 @@ static int pin_name;
 %token K_DEFAULT_SAFEMODE
 %token K_DEFAULT_SERIAL
 %token K_DESC
+%token K_FAMILY_ID
 %token K_DEVICECODE
 %token K_STK500_DEVCODE
 %token K_AVR910_DEVCODE
@@ -676,6 +677,13 @@ part_parm :
       free_token($3);
     } |
 
+  K_FAMILY_ID TKN_EQUAL TKN_STRING
+    {
+      strncpy(current_part->family_id, $3->value.string, AVR_FAMILYIDLEN);
+      current_part->family_id[AVR_FAMILYIDLEN] = 0;
+      free_token($3);
+    } |
+
   K_DEVICECODE TKN_EQUAL TKN_NUMBER {
     {
       yyerror("devicecode is deprecated, use "
diff --git a/doc/avrdude.texi b/doc/avrdude.texi
index 161c6473..227399fa 100644
--- a/doc/avrdude.texi
+++ b/doc/avrdude.texi
@@ -1437,6 +1437,7 @@ Following programmer types are currently implemented:
 part
     id               = <id> ;                 # quoted string
     desc             = <description> ;        # quoted string
+    family_id        = <description> ;        # quoted string
     has_jtag         = <yes/no> ;             # part has JTAG i/f
     has_debugwire    = <yes/no> ;             # part has debugWire i/f
     has_pdi          = <yes/no> ;             # part has PDI i/f
diff --git a/jtag3.c b/jtag3.c
index 57d87b4f..1dbf3280 100644
--- a/jtag3.c
+++ b/jtag3.c
@@ -848,9 +848,10 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
       avrdude_message(MSG_INFO, "%s: bad response to %s command: 0x%02x\n",
 		      progname, descr, c);
     }
+    status = (*resp)[3];
     free(*resp);
     resp = 0;
-    return -1;
+    return -status;
   }
 
   return status;
@@ -949,6 +950,7 @@ static int jtag3_program_enable_dummy(PROGRAMMER * pgm, AVRPART * p)
 static int jtag3_program_enable(PROGRAMMER * pgm)
 {
   unsigned char buf[3], *resp;
+  int status;
 
   if (PDATA(pgm)->prog_enabled)
     return 0;
@@ -957,14 +959,14 @@ static int jtag3_program_enable(PROGRAMMER * pgm)
   buf[1] = CMD3_ENTER_PROGMODE;
   buf[2] = 0;
 
-  if (jtag3_command(pgm, buf, 3, &resp, "enter progmode") >= 0) {
+  if ((status = jtag3_command(pgm, buf, 3, &resp, "enter progmode")) >= 0) {
     free(resp);
     PDATA(pgm)->prog_enabled = 1;
 
     return 0;
   }
 
-  return -1;
+  return status;
 }
 
 static int jtag3_program_disable(PROGRAMMER * pgm)
@@ -1286,17 +1288,28 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
   }
 
   /*
-   * Depending on the target connection, there are two different
+   * Depending on the target connection, there are three different
    * possible replies of the ICE.  For a JTAG connection, the reply
    * format is RSP3_DATA, followed by 4 bytes of the JTAG ID read from
-   * the device (followed by a trailing 0).  For all other connections
+   * the device (followed by a trailing 0).
+   * For a UPDI connection the reply format is RSP3_DATA, followed by
+   * 4 bytes of the SIB Family_ID read from the device (followed by a
+   * trailing 0).
+   * For all other connections
    * (except ISP which is handled completely differently, but that
    * doesn't apply here anyway), the response is just RSP_OK.
    */
-  if (resp[1] == RSP3_DATA && status >= 7)
-    /* JTAG ID has been returned */
-    avrdude_message(MSG_NOTICE, "%s: JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n",
-	    progname, resp[3], resp[4], resp[5], resp[6]);
+  if (resp[1] == RSP3_DATA && status >= 7) {
+    if (p->flags & AVRPART_HAS_UPDI) {
+      /* Partial Family_ID has been returned */
+      avrdude_message(MSG_NOTICE, "%s: Partial Family_ID returned: \"%c%c%c%c\"\n",
+	      progname, resp[3], resp[4], resp[5], resp[6]);
+    }
+    else
+      /* JTAG ID has been returned */
+      avrdude_message(MSG_NOTICE, "%s: JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+	      progname, resp[3], resp[4], resp[5], resp[6]);
+  }
 
   free(resp);
 
@@ -1806,8 +1819,9 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   avrdude_message(MSG_NOTICE2, "%s: jtag3_read_byte(.., %s, 0x%lx, ...)\n",
 	    progname, mem->desc, addr);
 
-  if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
-    return -1;
+  if (!(pgm->flag & PGM_FL_IS_DW))
+    if ((status = jtag3_program_enable(pgm)) < 0)
+      return status;
 
   cmd[0] = SCOPE_AVR;
   cmd[1] = CMD3_READ_MEMORY;
@@ -1886,7 +1900,7 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 
     if (addr == 0) {
       if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
-	return -1;
+	return status;
 
       signature_cache[0] = resp[4];
       signature_cache[1] = resp[5];
@@ -1935,7 +1949,7 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   }
 
   if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
-    return -1;
+    return status;
 
   if (resp[1] != RSP3_DATA ||
       status < (pagesize? pagesize: 1) + 4) {
@@ -2061,7 +2075,7 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   cmd[13] = data;
 
   if ((status = jtag3_command(pgm, cmd, 14, &resp, "write memory")) < 0)
-    return -1;
+    return status;
 
   free(resp);
 
@@ -2178,6 +2192,28 @@ int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
   return status;
 }
 
+int jtag3_read_sib(PROGRAMMER * pgm, AVRPART * p, char * sib)
+{
+  int status;
+  unsigned char cmd[12];
+  unsigned char *resp = NULL;
+
+  cmd[0] = SCOPE_AVR;
+  cmd[1] = CMD3_READ_MEMORY;
+  cmd[2] = 0;
+  cmd[3] = MTYPE_SIB;
+  u32_to_b4(cmd + 4, 0);
+  u32_to_b4(cmd + 8, AVR_SIBLEN);
+
+  if ((status = jtag3_command(pgm, cmd, 12, &resp, "read SIB")) < 0)
+	return status;
+
+  memcpy(sib, resp+3, AVR_SIBLEN);
+  sib[AVR_SIBLEN] = 0; // Zero terminate string
+  avrdude_message(MSG_DEBUG, "%s: jtag3_read_sib(): Received SIB: \"%s\"\n", progname, sib);
+  free(resp);
+  return 0;
+}
 
 static void jtag3_display(PROGRAMMER * pgm, const char * p)
 {
@@ -2430,5 +2466,6 @@ void jtag3_updi_initpgm(PROGRAMMER * pgm)
   pgm->teardown       = jtag3_teardown;
   pgm->page_size      = 256;
   pgm->flag           = PGM_FL_IS_UPDI;
+  pgm->read_sib       = jtag3_read_sib;
 }
 
diff --git a/lexer.l b/lexer.l
index ab7feb70..6e930a1e 100644
--- a/lexer.l
+++ b/lexer.l
@@ -140,6 +140,7 @@ default_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; }
 default_serial   { yylval=NULL; return K_DEFAULT_SERIAL; }
 delay            { yylval=NULL; return K_DELAY; }
 desc             { yylval=NULL; return K_DESC; }
+family_id        { yylval=NULL; return K_FAMILY_ID; }
 devicecode       { yylval=NULL; return K_DEVICECODE; }
 eecr             { yylval=NULL; return K_EECR; }
 eeprom           { yylval=NULL; return K_EEPROM; }
diff --git a/libavrdude.h b/libavrdude.h
index 5636f20c..7ba3a719 100644
--- a/libavrdude.h
+++ b/libavrdude.h
@@ -203,6 +203,8 @@ typedef struct opcode {
 
 #define AVR_DESCLEN 64
 #define AVR_IDLEN   32
+#define AVR_FAMILYIDLEN 7
+#define AVR_SIBLEN 16
 #define CTL_STACK_SIZE 32
 #define FLASH_INSTR_SIZE 3
 #define EEPROM_INSTR_SIZE 20
@@ -212,6 +214,7 @@ typedef struct opcode {
 typedef struct avrpart {
   char          desc[AVR_DESCLEN];  /* long part name */
   char          id[AVR_IDLEN];      /* short part name */
+  char          family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */
   int           stk500_devcode;     /* stk500 device code */
   int           avr910_devcode;     /* avr910 device code */
   int           chip_erase_delay;   /* microseconds */
@@ -666,6 +669,7 @@ typedef struct programmer_t {
   int  (*read_byte)      (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
                           unsigned long addr, unsigned char * value);
   int  (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
+  int  (*read_sib)       (struct programmer_t * pgm, AVRPART * p, char *sib);
   void (*print_parms)    (struct programmer_t * pgm);
   int  (*set_vtarget)    (struct programmer_t * pgm, double v);
   int  (*set_varef)      (struct programmer_t * pgm, unsigned int chan, double v);
diff --git a/main.c b/main.c
index abd96555..4521aea5 100644
--- a/main.c
+++ b/main.c
@@ -1045,6 +1045,44 @@ int main(int argc, char * argv [])
     if (init_ok) {
       rc = avr_signature(pgm, p);
       if (rc != 0) {
+        // -68 == -(0x44) == -(RSP3_FAIL_OCD_LOCKED)
+        if ((rc == -68) && (p->flags & AVRPART_HAS_UPDI) && (attempt < 1)) {
+          attempt++;
+          if (pgm->read_sib) {
+             // Read SIB and compare FamilyID
+             char sib[AVR_SIBLEN + 1];
+             pgm->read_sib(pgm, p, sib);
+             avrdude_message(MSG_NOTICE, "%s: System Information Block: \"%s\"\n",
+                             progname, sib);
+            if (quell_progress < 2) {
+              avrdude_message(MSG_INFO, "%s: Received FamilyID: \"%.*s\"\n", progname, AVR_FAMILYIDLEN, sib);
+            }
+            if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) {
+              avrdude_message(MSG_INFO, "%s: Expected FamilyID: \"%s\"\n", progname, p->family_id);
+              if (!ovsigck) {
+                avrdude_message(MSG_INFO, "%sDouble check chip, "
+                        "or use -F to override this check.\n",
+                        progbuf);
+                exitrc = 1;
+                goto main_exit;
+              }
+            }
+          }
+          if(erase) {
+            erase = 0;
+            if (uflags & UF_NOWRITE) {
+              avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n",
+                              progname);
+            } else {
+              if (quell_progress < 2) {
+                avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
+              }
+              exitrc = avr_chip_erase(pgm, p);
+              if(exitrc) goto main_exit;
+              goto sig_again;
+            }
+          }
+        }
         avrdude_message(MSG_INFO, "%s: error reading signature data, rc=%d\n",
           progname, rc);
         exitrc = 1;