diff options
-rw-r--r-- | firmware/drivers/ata.c | 20 | ||||
-rw-r--r-- | firmware/export/ata.h | 3 |
2 files changed, 20 insertions, 3 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 910d42d3b5..1c85b7bd5f 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -155,7 +155,8 @@ static inline bool ata_sleep_timed_out(void) | |||
155 | static inline void schedule_ata_power_off(void) | 155 | static inline void schedule_ata_power_off(void) |
156 | { | 156 | { |
157 | #ifdef HAVE_ATA_POWER_OFF | 157 | #ifdef HAVE_ATA_POWER_OFF |
158 | power_off_tick = current_tick + ATA_POWER_OFF_TIMEOUT; | 158 | if (!ata_disk_can_poweroff()) |
159 | power_off_tick = current_tick + ATA_POWER_OFF_TIMEOUT; | ||
159 | #endif | 160 | #endif |
160 | } | 161 | } |
161 | 162 | ||
@@ -399,8 +400,8 @@ int ata_disk_isssd(void) | |||
399 | However, this is a relatively recent change, and we can't rely on it, | 400 | However, this is a relatively recent change, and we can't rely on it, |
400 | especially for the FC1307A CF->SD adapters! | 401 | especially for the FC1307A CF->SD adapters! |
401 | 402 | ||
402 | Offset 167 is "Nominal Form Factor" | 403 | Offset 168 is "Nominal Form Factor" |
403 | all values >= 0x06 are guaranteed to be solid State. | 404 | all values >= 0x06 are guaranteed to be Solid State (mSATA, m.2, etc) |
404 | 405 | ||
405 | Offset 83 b2 and/or 86 b2 is set to show device implementes CFA commands | 406 | Offset 83 b2 and/or 86 b2 is set to show device implementes CFA commands |
406 | 407 | ||
@@ -414,6 +415,19 @@ int ata_disk_isssd(void) | |||
414 | identify_info[217] == 0x0001 || identify_info[217] == 0x0100); | 415 | identify_info[217] == 0x0001 || identify_info[217] == 0x0100); |
415 | } | 416 | } |
416 | 417 | ||
418 | int ata_disk_can_poweroff(void) | ||
419 | { | ||
420 | /* Some SSDs don't like getting powered off, presumably because | ||
421 | in the real world they're not in removable form factors and | ||
422 | don't expect to have power removed. | ||
423 | |||
424 | In particular, mSATA, m.2, and MicroSSD are suspect. | ||
425 | */ | ||
426 | |||
427 | return ((identify_info[168] & 0x0f) < 0x06 || | ||
428 | (identify_info[168] & 0x0f) > 0x08); | ||
429 | } | ||
430 | |||
417 | static int ata_transfer_sectors(unsigned long start, | 431 | static int ata_transfer_sectors(unsigned long start, |
418 | int incount, | 432 | int incount, |
419 | void* inbuf, | 433 | void* inbuf, |
diff --git a/firmware/export/ata.h b/firmware/export/ata.h index 7c5fd3a8d0..7c7c60e898 100644 --- a/firmware/export/ata.h +++ b/firmware/export/ata.h | |||
@@ -168,6 +168,9 @@ int ata_spinup_time(void); /* ticks */ | |||
168 | /* Returns 1 if drive is solid-state */ | 168 | /* Returns 1 if drive is solid-state */ |
169 | int ata_disk_isssd(void); | 169 | int ata_disk_isssd(void); |
170 | 170 | ||
171 | /* Returns 1 if the drive can be powered off safely */ | ||
172 | int ata_disk_can_poweroff(void); | ||
173 | |||
171 | #ifdef HAVE_ATA_DMA | 174 | #ifdef HAVE_ATA_DMA |
172 | /* Returns current DMA mode */ | 175 | /* Returns current DMA mode */ |
173 | int ata_get_dma_mode(void); | 176 | int ata_get_dma_mode(void); |