Browse Source

Use larger read buffer to enable multi-sector transfers

Petteri Aimonen 3 years ago
parent
commit
c79ea622b3
2 changed files with 45 additions and 33 deletions
  1. 41 33
      src/AzulSCSI.cpp
  2. 4 0
      src/AzulSCSI_config.h

+ 41 - 33
src/AzulSCSI.cpp

@@ -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();

+ 4 - 0
src/AzulSCSI_config.h

@@ -18,6 +18,10 @@
 #define MAX_FILE_PATH 32                // Maximum file name length
 #define MAX_BLOCKSIZE 1024              // Maximum BLOCK size
 
+// Read buffer size
+// Should be at least MAX_BLOCKSIZE.
+#define READBUFFER_SIZE 4096
+
 // SCSI config
 #define NUM_SCSIID  7          // Maximum number of supported SCSI-IDs (The minimum is 0)
 #define NUM_SCSILUN 2          // Maximum number of LUNs supported     (The minimum is 0)