diff options
Diffstat (limited to 'firmware/export')
-rw-r--r-- | firmware/export/ata.h | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/firmware/export/ata.h b/firmware/export/ata.h index 7c7c60e898..62c9467643 100644 --- a/firmware/export/ata.h +++ b/firmware/export/ata.h | |||
@@ -166,10 +166,58 @@ long ata_last_disk_activity(void); | |||
166 | int ata_spinup_time(void); /* ticks */ | 166 | int ata_spinup_time(void); /* ticks */ |
167 | 167 | ||
168 | /* Returns 1 if drive is solid-state */ | 168 | /* Returns 1 if drive is solid-state */ |
169 | int ata_disk_isssd(void); | 169 | static inline int ata_disk_isssd(void) |
170 | { | ||
171 | unsigned short *identify_info = ata_get_identify(); | ||
172 | /* | ||
173 | Offset 217 is "Nominal Rotation rate" | ||
174 | 0x0000 == Not reported | ||
175 | 0x0001 == Solid State | ||
176 | 0x0401 -> 0xffe == RPM | ||
177 | All others reserved | ||
178 | |||
179 | Some CF cards return 0x0100 (ie byteswapped 0x0001) so accept either. | ||
180 | However, this is a relatively recent change, and we can't rely on it, | ||
181 | especially for the FC1307A CF->SD adapters! | ||
182 | |||
183 | Offset 168 is "Nominal Form Factor" | ||
184 | all values >= 0x06 are guaranteed to be Solid State (mSATA, m.2, etc) | ||
185 | |||
186 | Offset 169 b0 is set to show device implements TRIM. | ||
187 | |||
188 | Unreliable mechanisms: | ||
189 | |||
190 | Offset 83 b2 shows device implements CFA commands. | ||
191 | However microdrives pose a problem as they support CFA but are not | ||
192 | SSD. | ||
193 | |||
194 | Offset 160 b15 indicates support for CF+ power level 1, if not set | ||
195 | then device is standard flash CF. However this is not foolproof | ||
196 | as newer CF cards may support it for extra performance. | ||
197 | |||
198 | Offset 163 shows CF Advanced timing modes; microdrive seems to | ||
199 | report 0, but all others (including iFlash) report higher! | ||
200 | |||
201 | So if device support CFA _AND_ reports higher speeds modes, it is SSD. | ||
202 | |||
203 | */ | ||
204 | return ( (identify_info[217] == 0x0001 || identify_info[217] == 0x0100) /* "Solid state" rotational rate */ | ||
205 | || ((identify_info[168] & 0x0f) >= 0x06) /* Explicit SSD form factors */ | ||
206 | || (identify_info[169] & (1<<0)) /* TRIM supported */ | ||
207 | || ((identify_info[83] & (1<<2)) && /* CFA compliant */ | ||
208 | (((identify_info[160] & (1<<15)) == 0) || /* CF level 0 */ | ||
209 | (identify_info[163] > 0))) /* Advanced timing modes */ | ||
210 | ); | ||
211 | } | ||
170 | 212 | ||
171 | /* Returns 1 if the drive can be powered off safely */ | 213 | /* Returns 1 if the drive can be powered off safely */ |
172 | int ata_disk_can_poweroff(void); | 214 | static inline int ata_disk_can_poweroff(void) |
215 | { | ||
216 | unsigned short *identify_info = ata_get_identify(); | ||
217 | /* Only devices that claim to support PM can be safely powered off. | ||
218 | This notably excludes the various SD adapters! */ | ||
219 | return (identify_info[82] & (1<<3) && identify_info[85] & (1<<3)); | ||
220 | } | ||
173 | 221 | ||
174 | #ifdef HAVE_ATA_DMA | 222 | #ifdef HAVE_ATA_DMA |
175 | /* Returns current DMA mode */ | 223 | /* Returns current DMA mode */ |