Procházet zdrojové kódy

Several bugfixes

- SD year reporting
- Watchdog tripped during SD card hotplug
- Handling of blocksize != 512
Petteri Aimonen před 3 roky
rodič
revize
3376afa204
2 změnil soubory, kde provedl 38 přidání a 38 odebrání
  1. 6 3
      src/AzulSCSI.cpp
  2. 32 35
      src/AzulSCSI_disk.cpp

+ 6 - 3
src/AzulSCSI.cpp

@@ -134,7 +134,9 @@ void print_sd_info()
     char sdname[6] = {sd_cid.pnm[0], sd_cid.pnm[1], sd_cid.pnm[2], sd_cid.pnm[3], sd_cid.pnm[4], 0};
     azlog("SD Name: ", sdname);
     
-    char sdyear[5] = {'2', '0', sd_cid.mdt_year_high, sd_cid.mdt_year_low, 0};
+    char sdyear[5] = "2000";
+    sdyear[2] += sd_cid.mdt_year_high;
+    sdyear[3] += sd_cid.mdt_year_low;
     azlog("SD Date: ", (int)sd_cid.mdt_month, "/", sdyear);
     
     azlog("SD Serial: ", sd_cid.psn);
@@ -207,7 +209,7 @@ bool findHDDImages()
         }
 
         if(id < NUM_SCSIID && lun < NUM_SCSILUN) {
-          azlog("-- Trying to open ", name, " for id:", id, " lun:", lun);
+          azlog("-- Opening ", name, " for id:", id, " lun:", lun);
           imageReady = scsiDiskOpenHDDImage(id, name, id, lun, blk);
           if(imageReady) { // Marked as a responsive ID
             foundImage = true;
@@ -216,7 +218,6 @@ bool findHDDImages()
           azlog("-- Invalid lun or id for image ", name);
         }
       } else {
-        azlog("-- Skipping file ", name);
       }
     }
   }
@@ -304,6 +305,7 @@ int main(void)
     {
       blinkStatus(BLINK_ERROR_NO_SD_CARD);
       delay(1000);
+      azplatform_reset_watchdog(15000);
     } while (!SD.begin(SD_CONFIG));
     azlog("SD card init succeeded after retry");
   }
@@ -348,6 +350,7 @@ int main(void)
           {
             blinkStatus(BLINK_ERROR_NO_SD_CARD);
             delay(1000);
+            azplatform_reset_watchdog(15000);
           } while (!SD.begin(SD_CONFIG));
           azlog("SD card reinit succeeded");
           print_sd_info();

+ 32 - 35
src/AzulSCSI_disk.cpp

@@ -26,7 +26,7 @@ SdDevice sdDev = {2, 256 * 1024 * 1024 * 2}; /* For SCSI2SD */
 
 struct image_config_t: public S2S_TargetCfg
 {
-    FsFile file;    
+    FsFile file;
 };
 
 static image_config_t g_DiskImages[S2S_MAX_TARGETS];
@@ -273,10 +273,9 @@ static void doReadCapacity()
         scsiDev.cdb[5];
     int pmi = scsiDev.cdb[8] & 1;
 
-    uint32_t capacity = getScsiCapacity(
-        scsiDev.target->cfg->sdSectorStart,
-        scsiDev.target->liveCfg.bytesPerSector,
-        scsiDev.target->cfg->scsiSectors);
+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
+    uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t capacity = img.file.size() / bytesPerSector;
 
     if (!pmi && lba)
     {
@@ -360,12 +359,11 @@ static int doTestUnitReady()
 
 static void doSeek(uint32_t lba)
 {
-    if (lba >=
-        getScsiCapacity(
-            scsiDev.target->cfg->sdSectorStart,
-            scsiDev.target->liveCfg.bytesPerSector,
-            scsiDev.target->cfg->scsiSectors)
-        )
+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
+    uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t capacity = img.file.size() / bytesPerSector;
+
+    if (lba >= capacity)
     {
         scsiDev.status = CHECK_CONDITION;
         scsiDev.target->sense.code = ILLEGAL_REQUEST;
@@ -405,7 +403,11 @@ static void doWrite(uint32_t lba, uint32_t blocks)
         s2s_delay_ms(10);
     }
 
+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
     uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t capacity = img.file.size() / bytesPerSector;
+
+    azdbg("------ Write ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba);
 
     if (unlikely(blockDev.state & DISK_WP) ||
         unlikely(scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL))
@@ -416,13 +418,7 @@ static void doWrite(uint32_t lba, uint32_t blocks)
         scsiDev.target->sense.asc = WRITE_PROTECTED;
         scsiDev.phase = STATUS;
     }
-    else if (unlikely(((uint64_t) lba) + blocks >
-        getScsiCapacity(
-            scsiDev.target->cfg->sdSectorStart,
-            bytesPerSector,
-            scsiDev.target->cfg->scsiSectors
-            )
-        ))
+    else if (unlikely(((uint64_t) lba) + blocks > capacity))
     {
         scsiDev.status = CHECK_CONDITION;
         scsiDev.target->sense.code = ILLEGAL_REQUEST;
@@ -439,12 +435,10 @@ static void doWrite(uint32_t lba, uint32_t blocks)
         scsiDev.dataLen = 0;
         scsiDev.dataPtr = 0;
 
-        azdbg("------ Write ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba);
-
         image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
         if (!img.file.seek(transfer.lba * bytesPerSector))
         {
-            azlog("Seek to ", transfer.lba, " failed for ", scsiDev.target->targetId);
+            azlog("Seek to ", transfer.lba, " failed for SCSI ID", (int)scsiDev.target->targetId);
             scsiDev.status = CHECK_CONDITION;
             scsiDev.target->sense.code = MEDIUM_ERROR;
             scsiDev.target->sense.asc = NO_SEEK_COMPLETE;
@@ -482,9 +476,10 @@ void diskDataOut()
 
     // Figure out how many blocks we can fit in buffer
     uint32_t blockcount = (transfer.blocks - transfer.currentBlock);
-    uint32_t maxblocks = sizeof(scsiDev.data) / scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t maxblocks = sizeof(scsiDev.data) / bytesPerSector;
     if (blockcount > maxblocks) blockcount = maxblocks;
-    uint32_t transferlen = blockcount * scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t transferlen = blockcount * bytesPerSector;
     scsiDev.dataLen = transferlen;
     scsiDev.dataPtr = 0;
     
@@ -532,10 +527,12 @@ static void doRead(uint32_t lba, uint32_t blocks)
         s2s_delay_ms(10);
     }
 
-    uint32_t capacity = getScsiCapacity(
-        scsiDev.target->cfg->sdSectorStart,
-        scsiDev.target->liveCfg.bytesPerSector,
-        scsiDev.target->cfg->scsiSectors);
+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
+    uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t capacity = img.file.size() / bytesPerSector;
+    
+    azdbg("------ Read ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba);
+
     if (unlikely(((uint64_t) lba) + blocks > capacity))
     {
         scsiDev.status = CHECK_CONDITION;
@@ -553,13 +550,9 @@ static void doRead(uint32_t lba, uint32_t blocks)
         scsiDev.dataLen = 0;
         scsiDev.dataPtr = 0;
 
-        uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
-        azdbg("------ Read ", (int)blocks, "x", (int)bytesPerSector, " starting at ", (int)lba);
-
-        image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
         if (!img.file.seek(transfer.lba * bytesPerSector))
         {
-            azlog("Seek to ", transfer.lba, " failed for ", scsiDev.target->targetId);
+            azlog("Seek to ", transfer.lba, " failed for SCSI ID", (int)scsiDev.target->targetId);
             scsiDev.status = CHECK_CONDITION;
             scsiDev.target->sense.code = MEDIUM_ERROR;
             scsiDev.target->sense.asc = NO_SEEK_COMPLETE;
@@ -571,7 +564,10 @@ static void doRead(uint32_t lba, uint32_t blocks)
 void diskDataIn_callback(uint32_t bytes_complete)
 {
     // For best performance, do writes in blocks of 4 or more bytes
-    bytes_complete &= ~3;
+    if (bytes_complete < scsiDev.dataLen)
+    {
+        bytes_complete &= ~3;
+    }
 
     if (bytes_complete > scsiDev.dataPtr)
     {
@@ -590,9 +586,10 @@ static void diskDataIn()
 
     // Figure out how many blocks we can fit in buffer
     uint32_t blockcount = (transfer.blocks - transfer.currentBlock);
-    uint32_t maxblocks = sizeof(scsiDev.data) / scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t bytesPerSector = scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t maxblocks = sizeof(scsiDev.data) / bytesPerSector;
     if (blockcount > maxblocks) blockcount = maxblocks;
-    uint32_t transferlen = blockcount * scsiDev.target->liveCfg.bytesPerSector;
+    uint32_t transferlen = blockcount * bytesPerSector;
 
     // Start reading from SD card.
     // The callback will write to SCSI bus.