diff --git a/firmware/common/disk.c b/firmware/common/disk.c index e681fb64e3..d409c68ee1 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c @@ -434,6 +434,11 @@ int disk_mount(int drive) } #endif /* MAX_VIRT_SECTOR_SIZE */ } + +#if defined(MAX_VIRT_SECTOR_SIZE) && defined(MAX_PHYS_SECTOR_SIZE) + if (mounted) + ata_set_phys_sector_mult(disk_sector_multiplier[drive]); +#endif } disk_writer_unlock(); diff --git a/firmware/drivers/ata-common.c b/firmware/drivers/ata-common.c index 016c93967a..3a1cea2dca 100644 --- a/firmware/drivers/ata-common.c +++ b/firmware/drivers/ata-common.c @@ -238,6 +238,10 @@ static int ata_get_phys_sector_mult(void) /* Check if drive really needs emulation - if we can access sector 1 then assume the drive supports "512e" and will handle it better than us, so ignore the large physical sectors. + + The exception here is if the device is partitioned to use + larger-than-logical "virtual" sectors; in that case we will + use whichever one (ie physical/"virtual") is larger. */ char throwaway[__MAX_VARIABLE_LOG_SECTOR]; rc = ata_transfer_sectors(1, 1, &throwaway, false); @@ -254,4 +258,15 @@ static int ata_get_phys_sector_mult(void) return 0; } +void ata_set_phys_sector_mult(unsigned int mult) +{ + unsigned int max = MAX_PHYS_SECTOR_SIZE/log_sector_size; + /* virtual sector could be larger than pyhsical sector */ + if (!mult || mult > max) + mult = max; + /* It needs to be at _least_ the size of the real multiplier */ + if (mult > phys_sector_mult) + phys_sector_mult = mult; +} + #endif /* MAX_PHYS_SECTOR_SIZE */ diff --git a/firmware/export/ata.h b/firmware/export/ata.h index dfa73eebf5..f29c052be3 100644 --- a/firmware/export/ata.h +++ b/firmware/export/ata.h @@ -235,4 +235,8 @@ int ata_read_smart(struct ata_smart_values*); #define ATA_IDENTIFY_WORDS 256 +#ifdef MAX_PHYS_SECTOR_SIZE +void ata_set_phys_sector_mult(unsigned int mult); +#endif + #endif /* __ATA_H__ */