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
This commit is contained in:
Solomon Peachy 2024-11-13 07:47:36 -05:00
parent 120906dc8b
commit 9bf033dd66
3 changed files with 24 additions and 0 deletions

View file

@ -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();

View file

@ -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 */

View file

@ -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__ */