iPod Classic: ATA SMART updates

- Add description for attributes supported by Samsung HS081HA (80Gb)
  and HS161JQ (CEATA 160Gb).
- Show error code when ata_read_smart() fails.

Change-Id: I618cc4f37d139fc90f596e2cf3a751346b27deb6
This commit is contained in:
Cástor Muñoz 2016-02-13 18:28:46 +01:00
parent 31d9084a8c
commit e9497dbf6d
3 changed files with 50 additions and 40 deletions

View file

@ -50,9 +50,6 @@
/** static, private data **/
static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR;
static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR;
#ifdef HAVE_ATA_SMART
static uint16_t ata_smart_data[0x100] STORAGE_ALIGN_ATTR;
#endif
static bool ceata;
static bool ata_swap;
static bool ata_lba48;
@ -1217,56 +1214,50 @@ int ata_init(void)
#ifdef HAVE_ATA_SMART
static int ata_smart(uint16_t* buf)
{
mutex_lock(&ata_mutex);
ata_power_up();
if (!ata_powered) PASS_RC(ata_power_up(), 3, 0);
if (ceata)
{
memset(ceata_taskfile, 0, 16);
ceata_taskfile[0xc] = 0x4f;
ceata_taskfile[0xd] = 0xc2;
ceata_taskfile[0xe] = 0x40; /* Device/Head Register, bit6: 0->CHS, 1->LBA */
ceata_taskfile[0xe] = BIT(6);
ceata_taskfile[0xf] = 0xb0;
PASS_RC(ceata_wait_idle(), 3, 0);
PASS_RC(ceata_wait_idle(), 3, 1);
if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */
{
ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */
PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 1);
PASS_RC(ceata_check_error(), 3, 2);
PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2);
PASS_RC(ceata_check_error(), 3, 3);
}
ceata_taskfile[0x9] = 0xd0; /* SMART read data */
PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 3);
PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 3, 4);
PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 4);
PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 3, 5);
}
else
{
int i;
uint32_t old = ATA_CFG;
ATA_CFG |= BIT(6); /* 16bit big-endian */
PASS_RC(ata_wait_for_not_bsy(10000000), 3, 5);
ata_write_cbr(&ATA_PIO_DAD, 0);
PASS_RC(ata_wait_for_not_bsy(10000000), 3, 6);
ata_write_cbr(&ATA_PIO_FED, 0xd0);
ata_write_cbr(&ATA_PIO_SCR, 0);
ata_write_cbr(&ATA_PIO_LLR, 0);
ata_write_cbr(&ATA_PIO_LMR, 0x4f);
ata_write_cbr(&ATA_PIO_LHR, 0xc2);
ata_write_cbr(&ATA_PIO_DVR, BIT(6));
ata_write_cbr(&ATA_PIO_CSD, 0xb0);
PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 6);
PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7);
for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR);
ATA_CFG = old;
}
ata_set_active();
mutex_unlock(&ata_mutex);
return 0;
}
void* ata_read_smart(void)
int ata_read_smart(struct ata_smart_values* smart_data)
{
ata_smart(ata_smart_data);
return ata_smart_data;
mutex_lock(&ata_mutex);
int rc = ata_smart((uint16_t*)smart_data);
mutex_unlock(&ata_mutex);
return rc;
}
#endif /* HAVE_ATA_SMART */