summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8702')
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c59
1 files changed, 59 insertions, 0 deletions
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{