Forráskód Böngészése

Merge pull request #20 from ZuluSCSI/update-to-v1.0.3

Bug fixes for v1.0.3
Alex Perez 3 éve
szülő
commit
a5735890db

+ 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