summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2024-11-13 07:47:36 -0500
committerSolomon Peachy <pizza@shaftnet.org>2024-11-15 07:24:08 -0500
commit9bf033dd667a85d0f8ca84084bdf518b44bdb4bc (patch)
tree0e468c55c2d3a281b559dfd4f3ab2afec5d3e9d7
parent120906dc8b0ce53ec383828b31cc16cbafb81046 (diff)
downloadrockbox-9bf033dd66.tar.gz
rockbox-9bf033dd66.zip
ata: Prefer using "virtual" sector size where possible
Normally, if a device uses larger physical sector size than the logical size and supports so-called "512e" mode, we let the device deal with partial sector reads/writes. However, if MAX_VIRT_SECTOR_SIZE is defined, we support partitioning/filesystems that use a larger "virtual" sector than the logical sector. typically this matches the physical sector size of the drive, which means that despite a small logical sector size, all I/O is done in terms of the physical sector size. Therefore, when MAX_VIRT_SECTOR_SIZE and MAX_PHYS_SECTOR_SIZE are enabled (currently only ipod5g and ipod6g), prefer software-based partial sector I/O. Change-Id: I0815ad0a2f987b89bb2debfbf3d0ed64cdf85525
-rw-r--r--firmware/common/disk.c5
-rw-r--r--firmware/drivers/ata-common.c15
-rw-r--r--firmware/export/ata.h4
3 files changed, 24 insertions, 0 deletions
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__ */