diff --git a/ChangeLog b/ChangeLog
index 92032451..c9d215f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2021-11-24  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by David Mosberger-Tang:
+	patch #9327: ft245r.c: add TPI support (patches 1-4)
+	* ft245r.c (ft245r_recv):  Optimize TPI programming
+	speed by reducing number of USB reads.
+
 2021-11-24  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	Submitted by David Mosberger-Tang:
diff --git a/ft245r.c b/ft245r.c
index 588b099d..c2bfb561 100644
--- a/ft245r.c
+++ b/ft245r.c
@@ -161,6 +161,9 @@ static pthread_t readerthread;
 static sem_t buf_data, buf_space;
 static unsigned char buffer[BUFSIZE];
 static int head, tail;
+static struct {
+    int discard;	// # of bytes to discard during read
+} rx;
 
 static void add_to_buf (unsigned char c) {
     int nh;
@@ -206,15 +209,24 @@ static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
     return 0;
 }
 
+static int ft245r_send_and_discard(PROGRAMMER * pgm, unsigned char * buf,
+				   size_t len) {
+    rx.discard += len;
+    return ft245r_send(pgm, buf, len);
+}
+
 static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
-    int i;
+    int i = 0;
 
     // Copy over data from the circular buffer..
     // XXX This should timeout, and return error if there isn't enough
     // data.
-    for (i=0; i<len; i++) {
+    while (i < len) {
         sem_wait (&buf_data);
-        buf[i] = buffer[tail];
+	if (rx.discard > 0)
+	    --rx.discard;
+	else
+	    buf[i++] = buffer[tail];
         if (tail == (BUFSIZE -1)) tail = 0;
         else                      tail++;
         sem_post (&buf_space);
@@ -645,8 +657,7 @@ static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte) {
     int len;
 
     len = set_tpi_data(pgm, buf, byte);
-    ft245r_send(pgm, buf, len);
-    ft245r_recv(pgm, buf, len);
+    ft245r_send_and_discard(pgm, buf, len);
     return 0;
 }