--- avrdude-5.3.1-org/avr910.c	2006-12-11 21:47:35.000000000 +0900
+++ avrdude-5.3.1/avr910.c	2007-03-27 23:18:29.000000000 +0900
@@ -44,6 +44,9 @@
 
 static char has_auto_incr_addr;
 
+static char is_usb = 0;
+#define READ_SIZE 64
+static unsigned char extra_buf[1024+7];
 
 static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
 {
@@ -145,6 +148,7 @@
   avr910_send(pgm, "S", 1);
   memset (id, 0, sizeof(id));
   avr910_recv(pgm, id, sizeof(id)-1);
+  is_usb = !strncmp(id, "USB910",6);
 
   /* Get the HW and SW versions to see if the programmer is present. */
 
@@ -419,35 +423,54 @@
   avr910_set_addr(pgm, addr>>1);
 
   while (addr < max_addr) {
-    page_wr_cmd_pending = 1;
-    buf[0] = cmd[addr & 0x01];
-    buf[1] = m->buf[addr];
-    avr910_send(pgm, buf, sizeof(buf));
-    avr910_vfy_cmd_sent(pgm, "write byte");
-
-    addr++;
-    page_bytes--;
-
-    if (m->paged && (page_bytes == 0)) {
-      /* Send the "Issue Page Write" if we have sent a whole page. */
-
-      avr910_set_addr(pgm, page_addr>>1);
-      avr910_send(pgm, "m", 1);
-      avr910_vfy_cmd_sent(pgm, "flush page");
-
-      page_wr_cmd_pending = 0;
-      usleep(m->max_write_delay);
-      avr910_set_addr(pgm, addr>>1);
-
-      /* Set page address for next page. */
-
-      page_addr = addr;
-      page_bytes = page_size;
-    }
-    else if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
-      avr910_set_addr(pgm, addr>>1);
+    if (is_usb && m->paged) {
+	int i;
+	int idx = 0;
+	extra_buf[idx++] = 'A';
+	extra_buf[idx++] = (addr>>(8+1)) & 0xff;
+	extra_buf[idx++] = (addr>>1) & 0xff;
+	for (i=0; i< page_size; i++) {
+		extra_buf[idx++] = cmd[(addr+i)&0x01];
+		extra_buf[idx++] = (addr + i >= max_addr)?0xff:m->buf[addr+i];
+	}
+	extra_buf[idx++] = 'A';
+	extra_buf[idx++] = (addr>>(8+1)) & 0xff;
+	extra_buf[idx++] = (addr>>1) & 0xff;
+	extra_buf[idx++] = 'm';
+        avr910_send(pgm, extra_buf, idx);
+        avr910_recv(pgm, extra_buf, 3 + page_size);
+	addr += page_size;
+        usleep(m->max_write_delay);
+    } else {
+        page_wr_cmd_pending = 1;
+        buf[0] = cmd[addr & 0x01];
+        buf[1] = m->buf[addr];
+        avr910_send(pgm, buf, sizeof(buf));
+        avr910_vfy_cmd_sent(pgm, "write byte");
+
+        addr++;
+        page_bytes--;
+
+        if (m->paged && (page_bytes == 0)) {
+          /* Send the "Issue Page Write" if we have sent a whole page. */
+
+          avr910_set_addr(pgm, page_addr>>1);
+          avr910_send(pgm, "m", 1);
+          avr910_vfy_cmd_sent(pgm, "flush page");
+
+          page_wr_cmd_pending = 0;
+          usleep(m->max_write_delay);
+          avr910_set_addr(pgm, addr>>1);
+
+          /* Set page address for next page. */
+
+          page_addr = addr;
+          page_bytes = page_size;
+        }
+        else if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
+          avr910_set_addr(pgm, addr>>1);
+        }
     }
-
     report_progress (addr, max_addr, NULL);
   }
 
@@ -536,22 +559,36 @@
   avr910_set_addr(pgm, addr);
 
   while (addr < max_addr) {
-    avr910_send(pgm, &cmd, 1);
-    if (cmd == 'R') {
-      /* The 'R' command returns two bytes, MSB first, we need to put the data
-         into the memory buffer LSB first. */
-      avr910_recv(pgm, buf, 2);
-      m->buf[addr*2]   = buf[1];  /* LSB */
-      m->buf[addr*2+1] = buf[0];  /* MSB */
-    }
-    else {
-      avr910_recv(pgm, (char *)&m->buf[addr], 1);
-    }
-
-    addr++;
-
-    if (has_auto_incr_addr != 'Y') {
-      avr910_set_addr(pgm, addr);
+    if (is_usb && cmd == 'R') {
+  	int i;
+	for (i=0; i<READ_SIZE/2; i++) {
+		extra_buf[i] = 'R';
+	}
+        avr910_send(pgm, extra_buf, READ_SIZE/2);
+        avr910_recv(pgm, extra_buf, READ_SIZE);
+	for (i=0; i< READ_SIZE; i+=2) {
+        	m->buf[addr*2+i]   = extra_buf[i+1];  /* LSB */
+        	m->buf[addr*2+i+1] = extra_buf[i];    /* MSB */
+	}
+        addr += READ_SIZE/2;
+    } else {
+        avr910_send(pgm, &cmd, 1);
+        if (cmd == 'R') {
+          /* The 'R' command returns two bytes, MSB first, we need to put the data
+             into the memory buffer LSB first. */
+          avr910_recv(pgm, buf, 2);
+          m->buf[addr*2]   = buf[1];  /* LSB */
+          m->buf[addr*2+1] = buf[0];  /* MSB */
+        }
+        else {
+          avr910_recv(pgm, (char *)&m->buf[addr], 1);
+        }
+
+        addr++;
+
+        if (has_auto_incr_addr != 'Y') {
+          avr910_set_addr(pgm, addr);
+        }
     }
 
     report_progress (addr, max_addr, NULL);
