diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index 7ead2d4b..505450a2 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,13 @@
+2013-01-02  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* usb_libusb.c (usbdev_open): Downgrade the max transfer size for
+	the main data endpoints when being forced so by the USB; this can
+	happen when attaching the JTAGICE3 to a USB 1.1 connection
+	* jtag3.c (jtag3_initialize): When detecting a downgraded max
+	transfer size on the JTAGICE3 (presumably, due to being connected
+	to USB 1.1 only), bail out as its firmware cannot properly handle
+	this (by now)
+
 2013-01-02  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* ChangeLog: annual ChangeLog rotation time
diff --git a/avrdude/jtag3.c b/avrdude/jtag3.c
index 7ecbe01a..da789b39 100644
--- a/avrdude/jtag3.c
+++ b/avrdude/jtag3.c
@@ -701,6 +701,36 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
   unsigned char cmd[4], *resp, b;
   int status;
 
+  /*
+   * At least, as of firmware 2.12, the JTAGICE3 doesn't handle
+   * splitting packets correctly.  On a large transfer, the first
+   * split packets are correct, but remaining packets contain just
+   * garbage.
+   *
+   * We move the check here so in case future firmware versions fix
+   * this, the check below can be made dependended on the actual
+   * firmware level.  Retrieving the firmware version can always be
+   * accomplished with USB 1.1 (64 byte max) packets.
+   *
+   * Allow to override the check by -F (so users could try on newer
+   * firmware), but warn loudly.
+   */
+  if (jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_FW_MAJOR, parm, 2) < 0)
+    return -1;
+  if (pgm->fd.usb.max_xfer < USBDEV_MAX_XFER_3) {
+    fprintf(stderr,
+	    "%s: the JTAGICE3's firmware %d.%d is broken on USB 1.1 connections, sorry\n",
+	    progname, parm[0], parm[1]);
+    if (ovsigck) {
+      fprintf(stderr,
+	      "%s: forced to continue by option -F; THIS PUTS THE DEVICE'S DATA INTEGRITY AT RISK!\n",
+	      progname);
+    } else {
+      serial_close(&pgm->fd);
+      return -1;
+    }
+  }
+
   if (pgm->flag & PGM_FL_IS_DW) {
     ifname = "debugWire";
     if (p->flags & AVRPART_HAS_DW)
diff --git a/avrdude/usb_libusb.c b/avrdude/usb_libusb.c
index 73ec6120..22570fb2 100644
--- a/avrdude/usb_libusb.c
+++ b/avrdude/usb_libusb.c
@@ -230,6 +230,22 @@ static int usbdev_open(char * port, long baud, union filedescriptor *fd)
 		      fd->usb.rep = USBDEV_BULK_EP_READ_MKII;
 		    }
 		  }
+		  for (i = 0; i < dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
+		    {
+		      if ((dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.rep ||
+			   dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.wep) &&
+			  dev->config[0].interface[0].altsetting[0].endpoint[i].wMaxPacketSize < fd->usb.max_xfer)
+			{
+			  if (verbose != 0)
+			    fprintf(stderr,
+				    "%s: max packet size expected %d, but found %d due to EP 0x%02x's wMaxPacketSize\n",
+				    progname,
+				    fd->usb.max_xfer,
+				    dev->config[0].interface[0].altsetting[0].endpoint[i].wMaxPacketSize,
+				    dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress);
+			  fd->usb.max_xfer = dev->config[0].interface[0].altsetting[0].endpoint[i].wMaxPacketSize;
+			}
+		    }
                   return 0;
 		}
 	      trynext: