Przeglądaj źródła

Patch from dev repo fixes for v1.0.3

Patches from
============
Improve filename handling (#62, #63)
80228b6c01aa6e95e0060c07e3308f6217021996

GD32: fix reading of very last SD card sector
3c41957068ae87582e3ac65fd4e2a28beebe2b68

Fix spurious read error messages due to prefetch when image is at end…
cb6d102435c5c599ed110cb40875626f829699e8

Narrow down error for spec 1.x sd cards
7ed375d8e30f08226703d781b13a9c06777b6042
to
786dffd3476b64882c11f0525b24087354ebc6d6
skipping
e7c8fe7293276957b494ffa533fe4c7c2e954ff2

Remove boot flag check from SdFat
d004cc3d862a9b2cc7b8575c5833581c65308254
J. Morio Sakaguchi 3 lat temu
rodzic
commit
8aa229dcd2

+ 1 - 1
lib/SdFat_NoArduino/src/ExFatLib/ExFatPartition.cpp

@@ -285,7 +285,7 @@ bool ExFatPartition::init(FsBlockDevice* dev, uint8_t part) {
   if (part >= 1) {
     mbr = reinterpret_cast<MbrSector_t*>(cache);
     mp = &mbr->part[part - 1];
-    if ((mp->boot != 0 && mp->boot != 0X80) || mp->type == 0) {
+    if (mp->type == 0) {
       DBG_FAIL_MACRO;
       goto fail;
     }

+ 1 - 1
lib/SdFat_NoArduino/src/FatLib/FatPartition.cpp

@@ -416,7 +416,7 @@ bool FatPartition::init(FsBlockDevice* dev, uint8_t part) {
           (dataCachePrepare(0, FsCache::CACHE_FOR_READ));
     MbrPart_t* mp = mbr->part + part - 1;
 
-    if (!mbr || mp->type == 0 || (mp->boot != 0 && mp->boot != 0X80)) {
+    if (!mbr || mp->type == 0) {
       DBG_FAIL_MACRO;
       goto fail;
     }

+ 35 - 39
lib/ZuluSCSI_platform_GD32F205/gd32_sdio_sdcard.c

@@ -305,50 +305,46 @@ sd_error_enum sd_power_on(void)
         sdcardtype = SD_HIGH_CAPACITY;
     }
 
-    /* send CMD55(APP_CMD) to indicate next command is application specific command */
-    sdio_csm_disable();
-    sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
-    sdio_wait_type_set(SDIO_WAITTYPE_NO);
-    sdio_csm_enable();
-
-    if(SD_OK == r1_error_check(SD_CMD_APP_CMD)) {
-        /* SD memory card */
-        while((!busyflag) && (count < SD_MAX_VOLT_VALIDATION)) {
-            /* send CMD55(APP_CMD) to indicate next command is application specific command */
-            sdio_csm_disable();
-            sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
-            sdio_wait_type_set(SDIO_WAITTYPE_NO);
-            sdio_csm_enable();
-            /* check if some error occurs */
-            status = r1_error_check(SD_CMD_APP_CMD);
-            if(SD_OK != status) {
-                return status;
-            }
+    while((!busyflag) && (count < SD_MAX_VOLT_VALIDATION)) {
+        /* send CMD55(APP_CMD) to indicate next command is application specific command */
+        sdio_csm_disable();
+        sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
+        sdio_wait_type_set(SDIO_WAITTYPE_NO);
+        sdio_csm_enable();
 
-            /* send ACMD41(SD_SEND_OP_COND) to get host capacity support information (HCS) and OCR content */
-            sdio_csm_disable();
-            sdio_command_response_config(SD_APPCMD_SD_SEND_OP_COND, (SD_VOLTAGE_WINDOW | sdcardtype), SDIO_RESPONSETYPE_SHORT);
-            sdio_wait_type_set(SDIO_WAITTYPE_NO);
-            sdio_csm_enable();
-            /* check if some error occurs */
-            status = r3_error_check();
-            if(SD_OK != status) {
-                return status;
-            }
-            /* get the response and check card power up status bit(busy) */
-            response = sdio_response_get(SDIO_RESPONSE0);
-            busyflag = (uint8_t)((response >> 31) & (uint32_t)0x01);
-            ++count;
-        }
-        if(count >= SD_MAX_VOLT_VALIDATION) {
-            status = SD_VOLTRANGE_INVALID;
+        
+        /* check if some error occurs */
+        /* ignoring return value, SD_ILLEGAL_COMMAND, for v1.x spec SD cards */
+        status = r1_error_check(SD_CMD_APP_CMD);
+        if(SD_OK != status && SD_ILLEGAL_COMMAND != status) {
             return status;
         }
-        if(response &= SD_HIGH_CAPACITY) {
-            /* SDHC card */
-            cardtype = SDIO_HIGH_CAPACITY_SD_CARD;
+        
+        /* send ACMD41(SD_SEND_OP_COND) to get host capacity support information (HCS) and OCR content */
+        sdio_csm_disable();
+        sdio_command_response_config(SD_APPCMD_SD_SEND_OP_COND, (SD_VOLTAGE_WINDOW | sdcardtype), SDIO_RESPONSETYPE_SHORT);
+        sdio_wait_type_set(SDIO_WAITTYPE_NO);
+        sdio_csm_enable();
+        /* check if some error occurs */
+
+        status = r3_error_check();
+        if(SD_OK != status) {
+            return status;
         }
+        /* get the response and check card power up status bit(busy) */
+        response = sdio_response_get(SDIO_RESPONSE0);
+        busyflag = (uint8_t)((response >> 31) & (uint32_t)0x01);
+        ++count;
     }
+    if(count >= SD_MAX_VOLT_VALIDATION) {
+        status = SD_VOLTRANGE_INVALID;
+        return status;
+    }
+    if(response &= SD_HIGH_CAPACITY) {
+        /* SDHC card */
+        cardtype = SDIO_HIGH_CAPACITY_SD_CARD;
+    }
+
     return status;
 }
 

+ 17 - 1
lib/ZuluSCSI_platform_GD32F205/sd_card_sdio.cpp

@@ -17,6 +17,7 @@ static uint32_t g_sdio_card_status;
 static uint32_t g_sdio_clk_kHz;
 static sdio_card_type_enum g_sdio_card_type;
 static uint16_t g_sdio_card_rca;
+static uint32_t g_sdio_sector_count;
 
 #define checkReturnOk(call) ((g_sdio_error = (call)) == SD_OK ? true : logSDError(__LINE__))
 static bool logSDError(int line)
@@ -44,7 +45,8 @@ bool SdioCard::begin(SdioConfig sdioConfig)
         && checkReturnOk(sd_card_select_deselect(g_sdio_card_rca))
         && checkReturnOk(sd_cardstatus_get(&g_sdio_card_status))
         && checkReturnOk(sd_bus_mode_config(SDIO_BUSMODE_4BIT))
-        && checkReturnOk(sd_transfer_mode_config(sdioConfig.useDma() ? SD_DMA_MODE : SD_POLLING_MODE));
+        && checkReturnOk(sd_transfer_mode_config(sdioConfig.useDma() ? SD_DMA_MODE : SD_POLLING_MODE))
+        && (g_sdio_sector_count = sectorCount());
 }
 
 uint8_t SdioCard::errorCode() const
@@ -262,6 +264,20 @@ bool SdioCard::readSector(uint32_t sector, uint8_t* dst)
 
 bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n)
 {
+    if (sector + n >= g_sdio_sector_count)
+    {
+        // sd_multiblocks_read() seems to have trouble reading the very last sector
+        for (int i = 0; i < n; i++)
+        {
+            if (!readSector(sector + i, dst + i * 512))
+            {
+                azlog("End of drive read failed at ", sector, " + ", i);
+                return false;
+            }
+        }
+        return true;
+    }
+
     return checkReturnOk(sd_multiblocks_read((uint32_t*)dst, (uint64_t)sector * 512, 512, n,
         get_stream_callback(dst, n * 512)));
 }

+ 48 - 21
src/ZuluSCSI.cpp

@@ -43,6 +43,7 @@
 #include <SdFat.h>
 #include <minIni.h>
 #include <string.h>
+#include <strings.h>
 #include <ctype.h>
 #include "ZuluSCSI_config.h"
 #include "ZuluSCSI_platform.h"
@@ -212,6 +213,35 @@ bool findHDDImages()
 
       if (is_hd || is_cd)
       {
+        // Check file extension
+        // We accept anything except known compressed files
+        bool is_compressed = false;
+        const char *extension = strrchr(name, '.');
+        if (extension)
+        {
+          const char *archive_exts[] = {
+            ".tar", ".tgz", ".gz", ".bz2", ".tbz2", ".xz", ".zst", ".z",
+            ".zip", ".zipx", ".rar", ".lzh", ".7z", ".s7z", ".arj",
+            ".dmg",
+            NULL
+          };
+
+          for (int i = 0; archive_exts[i]; i++)
+          {
+            if (strcasecmp(extension, archive_exts[i]) == 0)
+            {
+              is_compressed = true;
+              break;
+            }
+          }
+        }
+
+        if (is_compressed)
+        {
+          azlog("-- Ignoring compressed file ", name);
+          continue;
+        }
+
         // Defaults for Hard Disks
         int id  = 1; // 0 and 3 are common in Macs for physical HD and CD, so avoid them.
         int lun = 0;
@@ -223,8 +253,7 @@ bool findHDDImages()
           blk = 2048;
         }
 
-        // Positionally read in and coerase the chars to integers.
-        // We only require the minimum and read in the next if provided.
+        // Parse SCSI device ID
         int file_name_length = strlen(name);
         if(file_name_length > 2) { // HD[N]
           int tmp_id = name[HDIMG_ID_POS] - '0';
@@ -238,38 +267,35 @@ bool findHDDImages()
             id = usedDefaultId++;
           }
         }
+
+        // Parse SCSI LUN number
         if(file_name_length > 3) { // HD0[N]
           int tmp_lun = name[HDIMG_LUN_POS] - '0';
 
-          if(tmp_lun > -1 && tmp_lun < 2) {
+          if(tmp_lun > -1 && tmp_lun < NUM_SCSILUN) {
             lun = tmp_lun; // If valid id, set it, else use default
           }
         }
-        int blk1 = 0, blk2 = 0, blk3 = 0, blk4 = 0;
-        if(file_name_length > 8) { // HD00_[111]
-          blk1 = name[HDIMG_BLK_POS] - '0';
-          blk2 = name[HDIMG_BLK_POS+1] - '0';
-          blk3 = name[HDIMG_BLK_POS+2] - '0';
-          if(file_name_length > 9) // HD00_NNN[1]
-            blk4 = name[HDIMG_BLK_POS+3] - '0';
-        }
-        if(blk1 == 2 && blk2 == 5 && blk3 == 6) {
-          blk = 256;
-        } else if(blk1 == 1 && blk2 == 0 && blk3 == 2 && blk4 == 4) {
-          blk = 1024;
-        } else if(blk1 == 2 && blk2 == 0 && blk3 == 4 && blk4 == 8) {
-          blk  = 2048;
-        } else if(blk1 == 4 && blk2 == 0 && blk3 == 9 && blk4 == 6) {
-          blk = 4096;
-        } else if(blk1 == 8 && blk2 == 1 && blk3 == 9 && blk4 == 2) {
-          blk = 8192;
+
+        // Parse block size (HD00_NNNN)
+        const char *blksize = strchr(name, '_');
+        if (blksize)
+        {
+          int blktmp = strtoul(blksize + 1, NULL, 10);
+          if (blktmp == 256 || blktmp == 512 || blktmp == 1024 ||
+              blktmp == 2048 || blktmp == 4096 || blktmp == 8192)
+          {
+            blk = blktmp;
+          }
         }
 
+        // Add the directory name to get the full file path
         char fullname[MAX_FILE_PATH * 2 + 2] = {0};
         strncpy(fullname, imgdir, MAX_FILE_PATH);
         if (fullname[strlen(fullname) - 1] != '/') strcat(fullname, "/");
         strcat(fullname, name);
 
+        // Check whether this SCSI ID has been configured yet
         const S2S_TargetCfg* cfg = s2s_getConfigByIndex(id);
         if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
         {
@@ -277,6 +303,7 @@ bool findHDDImages()
           continue;
         }
 
+        // Open the image file
         if(id < NUM_SCSIID && lun < NUM_SCSILUN) {
           azlog("-- Opening ", fullname, " for id:", id, " lun:", lun);
           imageReady = scsiDiskOpenHDDImage(id, fullname, id, lun, blk, is_cd);

+ 17 - 2
src/ZuluSCSI_disk.cpp

@@ -1100,10 +1100,19 @@ static void diskDataIn()
         // This was the last block, verify that everything finishes
 
 #ifdef PREFETCH_BUFFER_SIZE
+        image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
         uint32_t prefetch_sectors = PREFETCH_BUFFER_SIZE / bytesPerSector;            
+        uint32_t img_sector_count = img.file.size() / bytesPerSector;
         g_scsi_prefetch.sector = transfer.lba + transfer.blocks;
         g_scsi_prefetch.bytes = 0;
         g_scsi_prefetch.scsiId = scsiDev.target->cfg->scsiId;
+        
+        if (g_scsi_prefetch.sector + prefetch_sectors > img_sector_count)
+        {
+            // Don't try to read past image end.
+            prefetch_sectors = img_sector_count - g_scsi_prefetch.sector;
+        }
+
         while (!scsiIsWriteFinished(NULL) && prefetch_sectors > 0)
         {
             // Check if prefetch buffer is free
@@ -1118,9 +1127,15 @@ static void diskDataIn()
             // is part of a longer linear read.
             g_disk_transfer.bytes_sd = bytesPerSector;
             g_disk_transfer.bytes_scsi = bytesPerSector; // Tell callback not to send to SCSI
-            image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
             azplatform_set_sd_callback(&diskDataIn_callback, g_disk_transfer.buffer);
-            g_scsi_prefetch.bytes += img.file.read(g_disk_transfer.buffer, bytesPerSector);
+            int status = img.file.read(g_disk_transfer.buffer, bytesPerSector);
+            if (status <= 0)
+            {
+                azlog("Prefetch read failed");
+                prefetch_sectors = 0;
+                break;
+            }
+            g_scsi_prefetch.bytes += status;
             azplatform_set_sd_callback(NULL, NULL);
             prefetch_sectors--;
         }

+ 1 - 1
src/ZuluSCSI_log.cpp

@@ -2,7 +2,7 @@
 #include "ZuluSCSI_config.h"
 #include "ZuluSCSI_platform.h"
 
-const char *g_azlog_firmwareversion = "1.0.1" " " __DATE__ " " __TIME__;
+const char *g_azlog_firmwareversion = "1.0.3" " " __DATE__ " " __TIME__;
 bool g_azlog_debug = true;
 
 // This memory buffer can be read by debugger and is also saved to zululog.txt