Index: avrftdi.c
===================================================================
--- avrftdi.c	(revision 1139)
+++ avrftdi.c	(working copy)
@@ -518,45 +518,65 @@
 
 /* Send 'buf_size' bytes from 'cmd' to device and return data from device in
  * buffer 'data'.
- * Write is only performed when mode contains MPSSE_DO_WRITE.
+ * Write is only performed when mode contains MPSSE_DO_WRITE (must always be set).
  * Read is only performed when mode contains MPSSE_DO_READ.
+ * cmd is the input MPSSE data stream.
+ * data is a buffer of the raw MPSSE output data.
  */
 static int avrftdi_transmit(avrftdi_t* pdata, unsigned char mode, unsigned char *cmd,
 			    unsigned char *data, int buf_size)
 {
-	int k = 0;
+    const int header_length = 3;
+    const int footer_length = 1;
+    const int protocol_length = header_length + footer_length;
+    int bytes_read = 0;
+    int bytes_written = 0;
 	int n;
-	unsigned char buf[4 + buf_size];
+    unsigned char buf[protocol_length + buf_size];
+    E(!(mode & MPSSE_DO_WRITE), pdata);
 
 	if (mode & MPSSE_DO_WRITE) {
 		buf[0] = mode | MPSSE_WRITE_NEG;
 		buf[1] = ((buf_size - 1) & 0xff);
 		buf[2] = (((buf_size - 1) >> 8) & 0xff);
 
-		memcpy(buf + 3, cmd, buf_size);
-		buf[buf_size + 3] = 0x87;
+        memcpy(buf + header_length, cmd, buf_size);
+        buf[buf_size + header_length] = 0x87; //Send immediate
 
+        //TODO: Dry run
+        /* All writes must be <= 384 bytes (including the 3 byte header +
+           1 byte send immediate command) to fit into the 384 byte FIFO. */
+        do {
+            int current_length = buf_size + protocol_length - bytes_written;
+            E(current_length < 0, pdata);
+            if (current_length > 384) {
+                current_length = 384;
+            }
+            avrftdi_print(3, "Writing %d bytes of data. Total length: %d\n",
+                          current_length, buf_size + protocol_length);
 #ifndef DRYRUN
-		E(ftdi_write_data(pdata->ftdic, buf, buf_size + 4) != buf_size + 4, pdata->ftdic);
+            E(ftdi_write_data(pdata->ftdic, buf + bytes_written, current_length) != current_length, pdata->ftdic);
 #endif
-	}
-
-	if (mode & MPSSE_DO_READ) {
-		memset(buf, 0, sizeof(buf));
-		do {
+            bytes_written += current_length;
+            if (mode & MPSSE_DO_READ) {
+                do {
+                    avrftdi_print(3, "Trying to read %d bytes of data. Total bytes already read: %d\n",
+                                  bytes_written - protocol_length - bytes_read, bytes_read);
 #ifndef DRYRUN
-			n = ftdi_read_data(pdata->ftdic, buf + k, buf_size - k);
-			E(n < 0, pdata->ftdic);
+                    n = ftdi_read_data(pdata->ftdic,
+                                       data + bytes_read,
+                                       bytes_written - protocol_length - bytes_read);
+                    E(n < 0, pdata->ftdic);
 #else
-			n = buf_size - k;
+                    n = bytes_written - overhead_length - bytes_read;
 #endif
-			k += n;
-		} while (k < buf_size);
-
-		memcpy(data, buf, buf_size);
+                    bytes_read += n;
+                } while (bytes_read < bytes_written - protocol_length);
+            }
+        } while (bytes_written < buf_size + protocol_length);
 	}
 
-	return k;
+    return bytes_read;
 }
 
 static int write_flush(avrftdi_t* pdata)
@@ -1006,7 +1026,7 @@
 		avr_set_bits(m->op[AVR_OP_READ], cmd);
 		avr_set_addr(m->op[AVR_OP_READ], cmd, add);
 
-		avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4);
+        if (avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4) < 4) return -1;
 
 		avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++);
 	}
@@ -1106,7 +1126,7 @@
 
 	avrftdi_print(2, "%s info: buffer size: %d\n", progname, buf_size);
 
-	avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size);
+    if (avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size) < 0) return -1;
 
 	bufptr = buf;
 	/* find a poll byte. we cannot poll a value of 0xff, so look
@@ -1200,7 +1220,7 @@
 		buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32);
 	}
 
-	avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4);
+    if (avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4) < len * 4) return -1;
 				
 	if(verbose > 2) {
 		buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32);
