| 
					
				 | 
			
			
				@@ -79,6 +79,7 @@ uint8_t   g_scsi_id_mask;    // Mask list of responding SCSI IDs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t   g_scsi_id;         // Currently responding SCSI-ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t   g_scsi_lun;        // Logical unit number currently responding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 uint8_t   g_scsi_sts;        // Status byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+uint8_t   g_scsi_buffer[READBUFFER_SIZE] __attribute__((aligned(4))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*********************************/ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -400,14 +401,17 @@ void writeDataPhase_FromSD(uint32_t adds, uint32_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SCSI_OUT(IO ,  active); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   delay_ns(g_scsi_timing.REQ_TYPE_SETUP_NS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  uint8_t buf[MAX_BLOCKSIZE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for(uint32_t i = 0; i < len; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (len > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#if STREAM_SD_TRANSFERS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    azplatform_prepare_stream(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    g_currentimg->m_file.read(buf, g_currentimg->m_blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t max_transfer_len = READBUFFER_SIZE / g_currentimg->m_blocksize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t transfer_len = (len < max_transfer_len) ? len : max_transfer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    len -= transfer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transfer_len *= g_currentimg->m_blocksize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if STREAM_SD_TRANSFERS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    azplatform_prepare_stream(g_scsi_buffer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_currentimg->m_file.read(g_scsi_buffer, transfer_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (g_busreset) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     size_t status = azplatform_finish_stream(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -415,17 +419,17 @@ void writeDataPhase_FromSD(uint32_t adds, uint32_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // Streaming did not happen, send data now 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       azdbg("Streaming from SD failed, using fallback"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      writeDataPhase(g_currentimg->m_blocksize, buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      writeDataPhase(transfer_len, g_scsi_buffer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else if (status != g_currentimg->m_blocksize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if (status != transfer_len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       azlog("Streaming failed halfway, data may be corrupt, aborting!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       g_scsi_sts |= 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    g_currentimg->m_file.read(buf, g_currentimg->m_blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    writeDataPhase(g_currentimg->m_blocksize, buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_currentimg->m_file.read(g_scsi_buffer, transfer_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    writeDataPhase(transfer_len, g_scsi_buffer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -462,37 +466,41 @@ void readDataPhase_ToSD(uint32_t adds, uint32_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SCSI_OUT(IO ,inactive); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   delay_ns(g_scsi_timing.REQ_TYPE_SETUP_NS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  uint8_t buf[MAX_BLOCKSIZE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (uint32_t i = 0; i < len; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (len > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t max_transfer_len = READBUFFER_SIZE / g_currentimg->m_blocksize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t transfer_len = (len < max_transfer_len) ? len : max_transfer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    len -= transfer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transfer_len *= g_currentimg->m_blocksize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #if STREAM_SD_TRANSFERS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  azplatform_prepare_stream(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  g_currentimg->m_file.write(buf, g_currentimg->m_blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    azplatform_prepare_stream(g_scsi_buffer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_currentimg->m_file.write(g_scsi_buffer, transfer_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pos += transfer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (g_busreset) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (g_busreset) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  size_t status = azplatform_finish_stream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    size_t status = azplatform_finish_stream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (status == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Streaming did not happen, rewrite 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    azdbg("Streaming to SD failed, using fallback"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (status == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Streaming did not happen, rewrite 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      azdbg("Streaming to SD failed, using fallback"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    g_currentimg->m_file.seek(pos + i * g_currentimg->m_blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      g_currentimg->m_file.seek(pos - transfer_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    readDataPhase(g_currentimg->m_blocksize, buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    g_currentimg->m_file.write(buf, g_currentimg->m_blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  else if (status != g_currentimg->m_blocksize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    azlog("Streaming to SD failed halfway, data may be corrupt, aborting!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    g_scsi_sts |= 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      readDataPhase(transfer_len, g_scsi_buffer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      g_currentimg->m_file.write(g_scsi_buffer, transfer_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else if (status != transfer_len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      azlog("Streaming to SD failed halfway, data may be corrupt, aborting!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      g_scsi_sts |= 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    readDataPhase(g_currentimg->m_blocksize, buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    g_currentimg->m_file.write(buf, g_currentimg->m_blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    readDataPhase(transfer_len, g_scsi_buffer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g_currentimg->m_file.write(g_scsi_buffer, transfer_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   g_currentimg->m_file.flush(); 
			 |