Skip to content

Commit

Permalink
Patch from dev repo fixes for v1.0.3
Browse files Browse the repository at this point in the history
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
  • Loading branch information
morio committed Jul 28, 2022
1 parent 10d0109 commit 8aa229d
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 66 deletions.
2 changes: 1 addition & 1 deletion lib/SdFat_NoArduino/src/ExFatLib/ExFatPartition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

This comment has been minimized.

Copy link
@PetteriAimonen

PetteriAimonen Dec 7, 2022

Collaborator

Can you expand on this? When is this loosening of the check needed, should it be upstreamed to SdFat library and included for RP2040 also?

This comment has been minimized.

Copy link
@PetteriAimonen

PetteriAimonen Dec 7, 2022

Collaborator

Ok, based on Wikipedia some systems put other values in the boot marker field if the drive is marked bootable. I'm trying to upstream this change as part of pull req #118 GPT support.

DBG_FAIL_MACRO;
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SdFat_NoArduino/src/FatLib/FatPartition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
74 changes: 35 additions & 39 deletions lib/ZuluSCSI_platform_GD32F205/gd32_sdio_sdcard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
18 changes: 17 additions & 1 deletion lib/ZuluSCSI_platform_GD32F205/sd_card_sdio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)));
}
Expand Down
69 changes: 48 additions & 21 deletions src/ZuluSCSI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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';
Expand All @@ -238,45 +267,43 @@ 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))
{
azlog("-- Ignoring ", fullname, ", SCSI ID ", id, " is already in use!");
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);
Expand Down
19 changes: 17 additions & 2 deletions src/ZuluSCSI_disk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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--;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ZuluSCSI_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8aa229d

Please sign in to comment.