summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/ata.h106
-rw-r--r--firmware/export/config/ipod6g.h2
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c59
3 files changed, 167 insertions, 0 deletions
diff --git a/firmware/export/ata.h b/firmware/export/ata.h
index 0bcb144e63..6f0d0b699f 100644
--- a/firmware/export/ata.h
+++ b/firmware/export/ata.h
@@ -25,6 +25,107 @@
25#include "config.h" /* for HAVE_MULTIVOLUME or not */ 25#include "config.h" /* for HAVE_MULTIVOLUME or not */
26#include "mv.h" /* for IF_MV() and friends */ 26#include "mv.h" /* for IF_MV() and friends */
27 27
28#ifdef HAVE_ATA_SMART
29/* S.M.A.R.T. headers from smartmontools-5.42 */
30#define NUMBER_ATA_SMART_ATTRIBUTES 30
31
32struct ata_smart_attribute {
33 unsigned char id;
34 /* meaning of flag bits: see MACROS just below */
35 /* WARNING: MISALIGNED! */
36 unsigned short flags;
37 unsigned char current;
38 unsigned char worst;
39 unsigned char raw[6];
40 unsigned char reserv;
41} __attribute__((packed));
42
43/* MACROS to interpret the flags bits in the previous structure. */
44/* These have not been implemented using bitflags and a union, to make */
45/* it portable across bit/little endian and different platforms. */
46
47/* 0: Prefailure bit */
48
49/* From SFF 8035i Revision 2 page 19: Bit 0 (pre-failure/advisory bit) */
50/* - If the value of this bit equals zero, an attribute value less */
51/* than or equal to its corresponding attribute threshold indicates an */
52/* advisory condition where the usage or age of the device has */
53/* exceeded its intended design life period. If the value of this bit */
54/* equals one, an attribute value less than or equal to its */
55/* corresponding attribute threshold indicates a prefailure condition */
56/* where imminent loss of data is being predicted. */
57#define ATTRIBUTE_FLAGS_PREFAILURE(x) (x & 0x01)
58
59/* 1: Online bit */
60
61/* From SFF 8035i Revision 2 page 19: Bit 1 (on-line data collection */
62/* bit) - If the value of this bit equals zero, then the attribute */
63/* value is updated only during off-line data collection */
64/* activities. If the value of this bit equals one, then the attribute */
65/* value is updated during normal operation of the device or during */
66/* both normal operation and off-line testing. */
67#define ATTRIBUTE_FLAGS_ONLINE(x) (x & 0x02)
68
69/* The following are (probably) IBM's, Maxtors and Quantum's definitions for the */
70/* vendor-specific bits: */
71/* 2: Performance type bit */
72#define ATTRIBUTE_FLAGS_PERFORMANCE(x) (x & 0x04)
73
74/* 3: Errorrate type bit */
75#define ATTRIBUTE_FLAGS_ERRORRATE(x) (x & 0x08)
76
77/* 4: Eventcount bit */
78#define ATTRIBUTE_FLAGS_EVENTCOUNT(x) (x & 0x10)
79
80/* 5: Selfpereserving bit */
81#define ATTRIBUTE_FLAGS_SELFPRESERVING(x) (x & 0x20)
82
83/* 6-15: Reserved for future use */
84#define ATTRIBUTE_FLAGS_OTHER(x) ((x) & 0xffc0)
85
86struct ata_smart_values
87{
88 unsigned short int revnumber;
89 struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES];
90 unsigned char offline_data_collection_status;
91 unsigned char self_test_exec_status;
92 unsigned short int total_time_to_complete_off_line;
93 unsigned char vendor_specific_366;
94 unsigned char offline_data_collection_capability;
95 unsigned short int smart_capability;
96 unsigned char errorlog_capability;
97 unsigned char vendor_specific_371;
98 unsigned char short_test_completion_time;
99 unsigned char extend_test_completion_time;
100 unsigned char conveyance_test_completion_time;
101 unsigned char reserved_375_385[11];
102 unsigned char vendor_specific_386_510[125];
103 unsigned char chksum;
104} __attribute__((packed));
105
106/* Raw attribute value print formats */
107enum ata_attr_raw_format
108{
109 RAWFMT_DEFAULT,
110 RAWFMT_RAW8,
111 RAWFMT_RAW16,
112 RAWFMT_RAW48,
113 RAWFMT_HEX48,
114 RAWFMT_RAW64,
115 RAWFMT_HEX64,
116 RAWFMT_RAW16_OPT_RAW16,
117 RAWFMT_RAW16_OPT_AVG16,
118 RAWFMT_RAW24_DIV_RAW24,
119 RAWFMT_RAW24_DIV_RAW32,
120 RAWFMT_SEC2HOUR,
121 RAWFMT_MIN2HOUR,
122 RAWFMT_HALFMIN2HOUR,
123 RAWFMT_MSEC24_HOUR32,
124 RAWFMT_TEMPMINMAX,
125 RAWFMT_TEMP10X,
126};
127#endif /* HAVE_ATA_SMART */
128
28struct storage_info; 129struct storage_info;
29 130
30void ata_enable(bool on); 131void ata_enable(bool on);
@@ -69,4 +170,9 @@ int ata_spinup_time(void); /* ticks */
69int ata_get_dma_mode(void); 170int ata_get_dma_mode(void);
70#endif /* HAVE_ATA_DMA */ 171#endif /* HAVE_ATA_DMA */
71 172
173#ifdef HAVE_ATA_SMART
174/* Returns current S.M.A.R.T. data */
175void* ata_read_smart(void);
176#endif
177
72#endif /* __ATA_H__ */ 178#endif /* __ATA_H__ */
diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h
index 7e7025e157..0a40108699 100644
--- a/firmware/export/config/ipod6g.h
+++ b/firmware/export/config/ipod6g.h
@@ -201,6 +201,8 @@
201 201
202#define STORAGE_NEEDS_ALIGN 202#define STORAGE_NEEDS_ALIGN
203 203
204#define HAVE_ATA_SMART
205
204/* define this if the device has larger sectors when accessed via USB */ 206/* define this if the device has larger sectors when accessed via USB */
205/* (only relevant in disk.c, fat.c now always supports large virtual sectors) */ 207/* (only relevant in disk.c, fat.c now always supports large virtual sectors) */
206//#define MAX_LOG_SECTOR_SIZE 4096 208//#define MAX_LOG_SECTOR_SIZE 4096
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
index c629fd583a..53ec45ec6d 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
@@ -50,6 +50,9 @@
50/** static, private data **/ 50/** static, private data **/
51static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; 51static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR;
52static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR; 52static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR;
53#ifdef HAVE_ATA_SMART
54static uint16_t ata_smart_data[0x100] STORAGE_ALIGN_ATTR;
55#endif
53static bool ceata; 56static bool ceata;
54static bool ata_swap; 57static bool ata_swap;
55static bool ata_lba48; 58static bool ata_lba48;
@@ -1211,6 +1214,62 @@ int ata_init(void)
1211 return 0; 1214 return 0;
1212} 1215}
1213 1216
1217#ifdef HAVE_ATA_SMART
1218static int ata_smart(uint16_t* buf)
1219{
1220 mutex_lock(&ata_mutex);
1221 ata_power_up();
1222
1223 if (ceata)
1224 {
1225 memset(ceata_taskfile, 0, 16);
1226 ceata_taskfile[0xc] = 0x4f;
1227 ceata_taskfile[0xd] = 0xc2;
1228 ceata_taskfile[0xe] = 0x40; /* Device/Head Register, bit6: 0->CHS, 1->LBA */
1229 ceata_taskfile[0xf] = 0xb0;
1230 PASS_RC(ceata_wait_idle(), 3, 0);
1231 if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */
1232 {
1233 ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */
1234 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 1);
1235 PASS_RC(ceata_check_error(), 3, 2);
1236 }
1237 ceata_taskfile[0x9] = 0xd0; /* SMART read data */
1238 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 3);
1239 PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 3, 4);
1240 }
1241 else
1242 {
1243 int i;
1244 uint32_t old = ATA_CFG;
1245 ATA_CFG |= BIT(6); /* 16bit big-endian */
1246 PASS_RC(ata_wait_for_not_bsy(10000000), 3, 5);
1247 ata_write_cbr(&ATA_PIO_DAD, 0);
1248 ata_write_cbr(&ATA_PIO_FED, 0xd0);
1249 ata_write_cbr(&ATA_PIO_SCR, 0);
1250 ata_write_cbr(&ATA_PIO_LLR, 0);
1251 ata_write_cbr(&ATA_PIO_LMR, 0x4f);
1252 ata_write_cbr(&ATA_PIO_LHR, 0xc2);
1253 ata_write_cbr(&ATA_PIO_DVR, BIT(6));
1254 ata_write_cbr(&ATA_PIO_CSD, 0xb0);
1255 PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 6);
1256 for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR);
1257 ATA_CFG = old;
1258 }
1259
1260 ata_set_active();
1261 mutex_unlock(&ata_mutex);
1262
1263 return 0;
1264}
1265
1266void* ata_read_smart(void)
1267{
1268 ata_smart(ata_smart_data);
1269 return ata_smart_data;
1270}
1271#endif /* HAVE_ATA_SMART */
1272
1214#ifdef CONFIG_STORAGE_MULTI 1273#ifdef CONFIG_STORAGE_MULTI
1215static int ata_num_drives(int first_drive) 1274static int ata_num_drives(int first_drive)
1216{ 1275{