Browse Source

Fix streaming with blocksize > 512

Petteri Aimonen 3 years ago
parent
commit
e13a7b31bb

+ 10 - 12
lib/AzulSCSI_platform_GD32F205/AzulSCSI_platform.cpp

@@ -349,7 +349,7 @@ public:
         wait_idle();
         (void)SPI_DATA(SD_SPI);
 
-        if (buf == m_stream_buffer)
+        if (buf == m_stream_buffer + m_stream_status)
         {
             // Stream data directly to SCSI bus
             return stream_receive(count);
@@ -411,8 +411,7 @@ public:
         SCSI_RELEASE_DATA_REQ();
         SCSI_WAIT_INACTIVE(ACK);
 
-        m_stream_status = true;
-        m_stream_buffer = NULL;
+        m_stream_status += count;
         return 0;
     }
 
@@ -422,7 +421,7 @@ public:
     }
 
     void send(const uint8_t* buf, size_t count) {
-        if (buf == m_stream_buffer)
+        if (buf == m_stream_buffer + m_stream_status)
         {
             stream_send(count);
             return;
@@ -452,8 +451,7 @@ public:
         }
         wait_idle();
 
-        m_stream_status = true;
-        m_stream_buffer = NULL;
+        m_stream_status += count;
     }
 
     void setSckSpeed(uint32_t maxSck) {
@@ -463,13 +461,13 @@ public:
     void prepare_stream(uint8_t *buffer)
     {
         m_stream_buffer = buffer;
-        m_stream_status = false;
+        m_stream_status = 0;
     }
 
-    bool finish_stream()
+    size_t finish_stream()
     {
-        bool result = m_stream_status;
-        m_stream_status = false;
+        size_t result = m_stream_status;
+        m_stream_status = 0;
         m_stream_buffer = NULL;
         return result;
     }
@@ -477,7 +475,7 @@ public:
 private:
     uint32_t m_sckfreq;
     uint8_t *m_stream_buffer;
-    bool m_stream_status;
+    size_t m_stream_status; // Number of bytes transferred so far
 };
 
 void sdCsInit(SdCsPin_t pin)
@@ -500,7 +498,7 @@ void azplatform_prepare_stream(uint8_t *buffer)
     g_sd_spi_port.prepare_stream(buffer);
 }
 
-bool azplatform_finish_stream()
+size_t azplatform_finish_stream()
 {
     return g_sd_spi_port.finish_stream();
 }

+ 2 - 3
lib/AzulSCSI_platform_GD32F205/AzulSCSI_platform.h

@@ -142,9 +142,8 @@ void azplatform_emergency_log_save();
 void azplatform_prepare_stream(uint8_t *buffer);
 
 // Get status of latest streaming operation.
-// If this returns false, the caller should do the SCSI write themselves.
-// Usually that happens if the read goes through SdFs cache.
-bool azplatform_finish_stream();
+// Returns number of bytes transferred.
+size_t azplatform_finish_stream();
 
 // Write a single SCSI pin.
 // Example use: SCSI_OUT(ATN, 1) sets SCSI_ATN to low (active) state.

+ 18 - 3
src/AzulSCSI.cpp

@@ -59,7 +59,7 @@ SdFs SD;
 
 void blinkStatus(int count)
 {
-  azlog("Blinking status code: ", count);
+  azdbg("Blinking status code: ", count);
   for (int i = 0; i < count; i++)
   {
     LED_ON();
@@ -375,12 +375,19 @@ void writeDataPhase_FromSD(uint32_t adds, uint32_t len)
 
     if (g_busreset) return;
 
-    if (!azplatform_finish_stream())
+    size_t status = azplatform_finish_stream();
+    if (status == 0)
     {
       // Streaming did not happen, send data now
       azdbg("Streaming from SD failed, using fallback");
       writeDataPhase(g_currentimg->m_blocksize, buf);
     }
+    else if (status != g_currentimg->m_blocksize)
+    {
+      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);
@@ -427,7 +434,9 @@ void readDataPhase_ToSD(uint32_t adds, uint32_t len)
 
   if (g_busreset) return;
 
-  if (!azplatform_finish_stream())
+  size_t status = azplatform_finish_stream();
+
+  if (status == 0)
   {
     // Streaming did not happen, rewrite
     azdbg("Streaming to SD failed, using fallback");
@@ -437,6 +446,12 @@ void readDataPhase_ToSD(uint32_t adds, uint32_t 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;
+  }
 #else
     readDataPhase(g_currentimg->m_blocksize, buf);
     g_currentimg->m_file.write(buf, g_currentimg->m_blocksize);