diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index d6a2bcb1..1f8266aa 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,60 @@
+2011-09-15  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* stk500v2.c (stk600_xprog_paged_load, stk600_xprog_paged_write):
+	Fix regression in the AVRISPmkII/STK600 TPI handling introduced
+	by the USBasp's TPI implementation which added a pagesize even for
+	the minor memory regions of TPI devices.
+
+2011-09-15  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* avr.c (avr_read, avr_write): Don't bail out on TPI parts if
+	their programmer doesn't provide a (low-level) cmd_tpi method;
+	instead, fall back to the normal programmer methods which are
+	supposed to handle the situation.
+	This fixes a regression where the recent bitbang-TPI implementation
+	broke TPI handling of STK600/AVRISPmkII.
+
+2011-09-13  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* stk500v2.c (stk500v2_command): Treat warnings as errors rather than
+	success.
+
+2011-08-30  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	bug #34027: avrdude AT90S1200 Problem (part 3 - documentation)
+	* avrdude.1: Document the programmer type restrictions for AT90S1200
+	devices.
+	* doc/avrdude.texi: (Ditto.)
+
+2011-08-30  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	bug #34027: avrdude AT90S1200 Problem (part 2 - stk500v2 and relatives)
+	* stk500v2.c (stk500v2_initialize): For the AT90S1200, release
+	/RESET for a moment before reinitializing, as this is required by
+	its programming protocol.
+
+2011-08-30  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* configure.ac: In AC_CHECK_LIB for libftdi, check for
+	ftdi_usb_get_strings() rathern than ftdi_init(), as this is a more
+	specific thing to search for in order to make sure getting a
+	recent enough libftdi.
+
+2011-08-29  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	bug #34027: avrdude AT90S1200 Problem (part 1 - bitbang
+	programmers)
+	* config_gram.y: Introduce new keyword "is_at90s1200".
+	* lexer.l: (Ditto.)
+	* avrdude.conf.in: Applew new keyword to the AT90S1200 device.
+	* avrpart.h: Introduce new flag AVRPART_IS_AT90S1200, reflecting
+	the is_at90s1200 configuration keyword.
+	* bitbang.c (bitbang_initialize): Replace existing test for
+	AT90S1200 by AVRPART_IS_AT90S1200
+	* avr.c (avr_write_byte_default): Avoid the pre-write reading for
+	the AT90S1200, as this appears to sometimes corrupt the high byte
+	by pre-programming the low byte just written into it.
+
 2011-08-27  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* configure.ac: Bump version for releasing AVRDUDE 5.11.
diff --git a/avrdude/NEWS b/avrdude/NEWS
index c83a41d5..8e64dd08 100644
--- a/avrdude/NEWS
+++ b/avrdude/NEWS
@@ -5,7 +5,14 @@ Approximate change log for AVRDUDE by version.
 (For more detailed changes, see the ChangeLog file.)
 
 ----------------------------------------------------------------------
-Current:
+Version 5.11.1:
+
+  * Bugfixes
+      (see ChangeLog for details)
+      - Fix AT90S1200 (bug #34027: avrdude AT90S1200 Problem)
+      - Fix TPI devices for STK600/AVRISPmkII (no bug ID)
+
+Version 5.11:
 
   * New devices supported:
       - ATmega88P/168P
diff --git a/avrdude/avr.c b/avrdude/avr.c
index 09dab1fe..01390f4f 100644
--- a/avrdude/avr.c
+++ b/avrdude/avr.c
@@ -239,12 +239,8 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
   memset(buf, 0xff, size);
 
   /* supports "paged load" thru post-increment */
-  if ((p->flags & AVRPART_HAS_TPI) && mem->page_size != 0) {
-    if (pgm->cmd_tpi == NULL) {
-      fprintf(stderr, "%s: Error: %s programmer does not support TPI\n",
-          progname, pgm->type);
-      return -1;
-    }
+  if ((p->flags & AVRPART_HAS_TPI) && mem->page_size != 0 &&
+      pgm->cmd_tpi != NULL) {
 
     while (avr_tpi_poll_nvmbsy(pgm));
 
@@ -443,11 +439,17 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     return 0;
   }
 
-  if (!mem->paged) {
+  if (!mem->paged &&
+      (p->flags & AVRPART_IS_AT90S1200) == 0) {
     /* 
      * check to see if the write is necessary by reading the existing
      * value and only write if we are changing the value; we can't
      * use this optimization for paged addressing.
+     *
+     * For mysterious reasons, on the AT90S1200, this read operation
+     * sometimes causes the high byte of the same word to be
+     * programmed to the value of the low byte that has just been
+     * programmed before.  Avoid that optimization on this device.
      */
     rc = pgm->read_byte(pgm, p, mem, addr, &b);
     if (rc != 0) {
@@ -708,13 +710,8 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
   }
 
 
-  if ((p->flags & AVRPART_HAS_TPI) && m->page_size != 0) {
-    if (pgm->cmd_tpi == NULL) {
-      fprintf(stderr,
-          "%s: Error: %s programmer does not support TPI\n",
-          progname, pgm->type);
-      return -1;
-    }
+  if ((p->flags & AVRPART_HAS_TPI) && m->page_size != 0 &&
+      pgm->cmd_tpi != NULL) {
 
     while (avr_tpi_poll_nvmbsy(pgm));
 
diff --git a/avrdude/avrdude.1 b/avrdude/avrdude.1
index f63f527e..354da762 100644
--- a/avrdude/avrdude.1
+++ b/avrdude/avrdude.1
@@ -19,7 +19,7 @@
 .\"
 .\" $Id$
 .\"
-.Dd DATE August 17, 2011
+.Dd DATE August 30, 2011
 .Os
 .Dt AVRDUDE 1
 .Sh NAME
@@ -211,7 +211,7 @@ the format.  Currently, the following MCU types are understood:
 .TS
 ll.
 \fBOption tag\fP	\fBOfficial part name\fP
-1200	AT90S1200
+1200	AT90S1200 (****)
 2313	AT90S2313
 2333	AT90S2333
 2343	AT90S2343 (*)
@@ -322,6 +322,11 @@ and bit-bang programmers.
 .It "(***)"
 The ATtiny11 uses the same algorithm, but can only be
 programmed in high-voltage serial mode.
+.It "(****)"
+The ISP programming protocol of the AT90S1200 differs in subtle ways
+from that of other AVRs.  Thus, not all programmers support this
+device.  Known to work are all direct bitbang programmers, and all
+programmers talking the STK500v2 protocol.
 .El
 .It Fl b Ar baudrate
 Override the RS-232 connection baud rate specified in the respective
diff --git a/avrdude/avrdude.conf.in b/avrdude/avrdude.conf.in
index 39e21568..5d2d2d1a 100644
--- a/avrdude/avrdude.conf.in
+++ b/avrdude/avrdude.conf.in
@@ -1523,6 +1523,7 @@ part
 part
     id               = "1200";
     desc             = "AT90S1200";
+    is_at90s1200     = yes;
     stk500_devcode   = 0x33;
     avr910_devcode   = 0x13;
     signature        = 0x1e 0x90 0x01;
diff --git a/avrdude/avrpart.h b/avrdude/avrpart.h
index 04334609..f868e948 100644
--- a/avrdude/avrpart.h
+++ b/avrdude/avrpart.h
@@ -93,6 +93,7 @@ typedef struct opcode {
 #define AVRPART_INIT_SMC       0x0200  /* part will undergo chip erase */
 #define AVRPART_WRITE          0x0400  /* at least one write operation specified */
 #define AVRPART_HAS_TPI        0x0800  /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
+#define AVRPART_IS_AT90S1200   0x1000  /* part is an AT90S1200 (needs special treatment) */
 
 #define AVR_DESCLEN 64
 #define AVR_IDLEN   32
diff --git a/avrdude/bitbang.c b/avrdude/bitbang.c
index ada885ac..00eb8277 100644
--- a/avrdude/bitbang.c
+++ b/avrdude/bitbang.c
@@ -606,7 +606,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
    * order to possibly get back into sync with the chip if we are out
    * of sync.
    */
-  if (strcmp(p->desc, "AT90S1200")==0) {
+  if (p->flags & AVRPART_IS_AT90S1200) {
     pgm->program_enable(pgm, p);
   }
   else {
diff --git a/avrdude/config_gram.y b/avrdude/config_gram.y
index 3e10cd46..c676c828 100644
--- a/avrdude/config_gram.y
+++ b/avrdude/config_gram.y
@@ -225,6 +225,7 @@ static int parse_cmdbits(OPCODE * op);
 %token K_HAS_PDI                /* MCU has PDI i/f rather than ISP (ATxmega). */
 %token K_HAS_TPI                /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
 %token K_IDR			/* address of OCD register in IO space */
+%token K_IS_AT90S1200		/* chip is an AT90S1200 (needs special treatment) */
 %token K_IS_AVR32               /* chip is in the avr32 family */
 %token K_RAMPZ			/* address of RAMPZ reg. in IO space */
 %token K_SPMCR			/* address of SPMC[S]R in memory space */
@@ -1166,6 +1167,16 @@ part_parm :
       free_token($3);
     } |
 
+  K_IS_AT90S1200 TKN_EQUAL yesno
+    {
+      if ($3->primary == K_YES)
+        current_part->flags |= AVRPART_IS_AT90S1200;
+      else if ($3->primary == K_NO)
+        current_part->flags &= AVRPART_IS_AT90S1200;
+
+      free_token($3);
+    } |
+
   K_IS_AVR32 TKN_EQUAL yesno
     {
       if ($3->primary == K_YES)
@@ -1175,7 +1186,7 @@ part_parm :
 
       free_token($3);
     } |
-    
+
   K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
     {
       if ($3->primary == K_YES)
diff --git a/avrdude/configure.ac b/avrdude/configure.ac
index b5ba7cf8..3118fe5a 100644
--- a/avrdude/configure.ac
+++ b/avrdude/configure.ac
@@ -24,7 +24,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.57)
-AC_INIT(avrdude, 5.11, avrdude-dev@nongnu.org)
+AC_INIT(avrdude, 5.11.1rc, avrdude-dev@nongnu.org)
 
 AC_CANONICAL_BUILD
 AC_CANONICAL_HOST
@@ -105,7 +105,7 @@ fi
 AC_SUBST(LIBUSB_1_0, $LIBUSB_1_0)
 AH_TEMPLATE([HAVE_LIBFTDI],
             [Define if FTDI support is enabled via libftdi])
-AC_CHECK_LIB([ftdi], [ftdi_init], [have_libftdi=yes], [], [-lusb])
+AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
 if test x$have_libftdi = xyes; then
    LIBFTDI="-lftdi -lusb"
    AC_DEFINE([HAVE_LIBFTDI])
diff --git a/avrdude/doc/avrdude.texi b/avrdude/doc/avrdude.texi
index 4ea19bf5..a24ca226 100644
--- a/avrdude/doc/avrdude.texi
+++ b/avrdude/doc/avrdude.texi
@@ -307,7 +307,7 @@ datasheet so that you can enter the programming specifications.
 Currently, the following MCU types are understood:
 
 @multitable @columnfractions .15 .3
-@item @code{1200}  @tab AT90S1200
+@item @code{1200}  @tab AT90S1200 (****)
 @item @code{2313}  @tab AT90S2313
 @item @code{2333}  @tab AT90S2333
 @item @code{2343}  @tab AT90S2343 (*)
@@ -419,6 +419,12 @@ and bit-bang programmers.
 The ATtiny11 uses the same algorithm, but can only be
 programmed in high-voltage serial mode.
 
+(****)
+The ISP programming protocol of the AT90S1200 differs in subtle ways
+from that of other AVRs.  Thus, not all programmers support this
+device.  Known to work are all direct bitbang programmers, and all
+programmers talking the STK500v2 protocol.
+
 @item -b @var{baudrate}
 Override the RS-232 connection baud rate specified in the respective
 programmer's entry of the configuration file.
diff --git a/avrdude/lexer.l b/avrdude/lexer.l
index 6f1698f8..9870e7c6 100644
--- a/avrdude/lexer.l
+++ b/avrdude/lexer.l
@@ -155,6 +155,7 @@ has_pdi          { yylval=NULL; return K_HAS_PDI; }
 has_tpi          { yylval=NULL; return K_HAS_TPI; }
 id               { yylval=NULL; return K_ID; }
 idr              { yylval=NULL; return K_IDR; }
+is_at90s1200     { yylval=NULL; return K_IS_AT90S1200; }
 is_avr32         { yylval=NULL; return K_IS_AVR32; }
 jtagmki          { yylval=NULL; return K_JTAG_MKI; }
 jtagmkii         { yylval=NULL; return K_JTAG_MKII; }
diff --git a/avrdude/stk500v2.c b/avrdude/stk500v2.c
index 276d6f58..7f436b79 100644
--- a/avrdude/stk500v2.c
+++ b/avrdude/stk500v2.c
@@ -787,18 +787,20 @@ retry:
                 msg = msgbuf;
                 break;
             }
-            if (quell_progress < 2)
+            if (quell_progress < 2) {
                 fprintf(stderr, "%s: stk500v2_command(): warning: %s\n",
                         progname, msg);
-            buf[1] = STATUS_CMD_OK; /* pretend success */
-        }
-        if (buf[1] == STATUS_CMD_OK)
+            }
+        } else if (buf[1] == STATUS_CMD_OK) {
             return status;
-        if (buf[1] == STATUS_CMD_FAILED)
-            fprintf(stderr, "%s: stk500v2_command(): command failed\n", progname);
-        else
+        } else if (buf[1] == STATUS_CMD_FAILED) {
+            fprintf(stderr,
+                    "%s: stk500v2_command(): command failed\n",
+                    progname);
+        } else {
             fprintf(stderr, "%s: stk500v2_command(): unknown status 0x%02x\n",
                     progname, buf[1]);
+        }
         return -1;
     }
   }
@@ -1099,6 +1101,14 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
     stk600_setup_isp(pgm);
   }
 
+  if (p->flags & AVRPART_IS_AT90S1200) {
+    /*
+     * AT90S1200 needs a positive reset pulse after a chip erase.
+     */
+    pgm->disable(pgm);
+    usleep(10000);
+  }
+
   return pgm->program_enable(pgm, p);
 }
 
@@ -3328,6 +3338,16 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
             use_ext_addr = (1UL << 31);
     } else if (strcmp(mem->desc, "eeprom") == 0) {
         memtype = XPRG_MEM_TYPE_EEPROM;
+    } else if (strcmp(mem->desc, "signature") == 0) {
+        memtype = XPRG_MEM_TYPE_APPL;
+    } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+        memtype = XPRG_MEM_TYPE_FUSE;
+    } else if (strcmp(mem->desc, "lockbits") == 0) {
+        memtype = XPRG_MEM_TYPE_LOCKBITS;
+    } else if (strcmp(mem->desc, "calibration") == 0) {
+        memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
+    } else if (strcmp(mem->desc, "usersig") == 0) {
+        memtype = XPRG_MEM_TYPE_USERSIG;
     } else {
         fprintf(stderr,
                 "%s: stk600_xprog_paged_load(): unknown paged memory \"%s\"\n",
@@ -3419,6 +3439,21 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     } else if (strcmp(mem->desc, "eeprom") == 0) {
         memtype = XPRG_MEM_TYPE_EEPROM;
         writemode = (1 << XPRG_MEM_WRITE_WRITE) | (1 << XPRG_MEM_WRITE_ERASE);
+    } else if (strcmp(mem->desc, "signature") == 0) {
+        memtype = XPRG_MEM_TYPE_APPL;
+        writemode = (1 << XPRG_MEM_WRITE_WRITE);
+    } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+        memtype = XPRG_MEM_TYPE_FUSE;
+        writemode = (1 << XPRG_MEM_WRITE_WRITE);
+    } else if (strcmp(mem->desc, "lockbits") == 0) {
+        memtype = XPRG_MEM_TYPE_LOCKBITS;
+        writemode = (1 << XPRG_MEM_WRITE_WRITE);
+    } else if (strcmp(mem->desc, "calibration") == 0) {
+        memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
+        writemode = (1 << XPRG_MEM_WRITE_WRITE);
+    } else if (strcmp(mem->desc, "usersig") == 0) {
+        memtype = XPRG_MEM_TYPE_USERSIG;
+        writemode = (1 << XPRG_MEM_WRITE_WRITE);
     } else {
         fprintf(stderr,
                 "%s: stk600_xprog_paged_write(): unknown paged memory \"%s\"\n",