mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 13:12:37 -05:00
ata: Heavily rework sleep and poweroff logic
* Use of ata_disk_can_poweroff() was inverted, resulting in SATA SSDs getting powered off but leaving _everything_ else on, including spinning rust! * Replace the can_poweroff() heuristic with a test for the mandatory ATA power mgmt feature flag. Notably, the CF->SD adapters don't claim to support this! * Eliminate duplicated tests in sleep code * Wrap all poweroff-related code with HAVE_ATA_POWER_OFF * Don't ever use SLEEP command, only STANDBY_IMMEDIATE * Gate call to STANDBY_IMMEDIATE behind a can_poweroff() test * Prefer FLUSH_CACHE_EXT to FLUSH_CACHE where available. * Improve SSD detection heuristics to any of these: * Explicltly identifies as SSD (covers newer CF and SATA) * TRIM support * CFA compliant AND (CF level 0 OR high speed support) * Report SSD detection in debug menu Change-Id: I7fcb83b6d6eabddc11c64326a573b08ab85412b5
This commit is contained in:
parent
6cbcde13b9
commit
886060475e
3 changed files with 87 additions and 80 deletions
|
|
@ -166,10 +166,58 @@ long ata_last_disk_activity(void);
|
|||
int ata_spinup_time(void); /* ticks */
|
||||
|
||||
/* Returns 1 if drive is solid-state */
|
||||
int ata_disk_isssd(void);
|
||||
static inline int ata_disk_isssd(void)
|
||||
{
|
||||
unsigned short *identify_info = ata_get_identify();
|
||||
/*
|
||||
Offset 217 is "Nominal Rotation rate"
|
||||
0x0000 == Not reported
|
||||
0x0001 == Solid State
|
||||
0x0401 -> 0xffe == RPM
|
||||
All others reserved
|
||||
|
||||
Some CF cards return 0x0100 (ie byteswapped 0x0001) so accept either.
|
||||
However, this is a relatively recent change, and we can't rely on it,
|
||||
especially for the FC1307A CF->SD adapters!
|
||||
|
||||
Offset 168 is "Nominal Form Factor"
|
||||
all values >= 0x06 are guaranteed to be Solid State (mSATA, m.2, etc)
|
||||
|
||||
Offset 169 b0 is set to show device implements TRIM.
|
||||
|
||||
Unreliable mechanisms:
|
||||
|
||||
Offset 83 b2 shows device implements CFA commands.
|
||||
However microdrives pose a problem as they support CFA but are not
|
||||
SSD.
|
||||
|
||||
Offset 160 b15 indicates support for CF+ power level 1, if not set
|
||||
then device is standard flash CF. However this is not foolproof
|
||||
as newer CF cards may support it for extra performance.
|
||||
|
||||
Offset 163 shows CF Advanced timing modes; microdrive seems to
|
||||
report 0, but all others (including iFlash) report higher!
|
||||
|
||||
So if device support CFA _AND_ reports higher speeds modes, it is SSD.
|
||||
|
||||
*/
|
||||
return ( (identify_info[217] == 0x0001 || identify_info[217] == 0x0100) /* "Solid state" rotational rate */
|
||||
|| ((identify_info[168] & 0x0f) >= 0x06) /* Explicit SSD form factors */
|
||||
|| (identify_info[169] & (1<<0)) /* TRIM supported */
|
||||
|| ((identify_info[83] & (1<<2)) && /* CFA compliant */
|
||||
(((identify_info[160] & (1<<15)) == 0) || /* CF level 0 */
|
||||
(identify_info[163] > 0))) /* Advanced timing modes */
|
||||
);
|
||||
}
|
||||
|
||||
/* Returns 1 if the drive can be powered off safely */
|
||||
int ata_disk_can_poweroff(void);
|
||||
static inline int ata_disk_can_poweroff(void)
|
||||
{
|
||||
unsigned short *identify_info = ata_get_identify();
|
||||
/* Only devices that claim to support PM can be safely powered off.
|
||||
This notably excludes the various SD adapters! */
|
||||
return (identify_info[82] & (1<<3) && identify_info[85] & (1<<3));
|
||||
}
|
||||
|
||||
#ifdef HAVE_ATA_DMA
|
||||
/* Returns current DMA mode */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue