freemyipod r620 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r619‎ | r620 | r621 >
Date:00:47, 17 February 2011
Author:theseven
Status:new
Tags:
Comment:
emCORE: Make iPod Classic ATA driver error handling configurable, handle BBT reading problems more gracefully
Modified paths:
  • /emcore/trunk/target/ipodclassic/storage_ata-target.h (modified) (history)
  • /emcore/trunk/target/ipodclassic/storage_ata.c (modified) (history)

Diff [purge]

Index: emcore/trunk/target/ipodclassic/storage_ata-target.h
@@ -29,7 +29,8 @@
3030
3131 struct ata_target_driverinfo
3232 {
33 - int (*soft_reset)();
 33+ void (*srst_after_error)(bool enable);
 34+ void (*set_retries)(int retries);
3435 int (*bbt_translate)(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount);
3536 void (*bbt_reload)();
3637 void (*bbt_disable)();
@@ -40,6 +41,9 @@
4142 extern uint64_t ata_total_sectors;
4243 extern struct mutex ata_mutex;
4344
 45+void ata_set_retries(int retries);
 46+void ata_srst_after_error(bool enable);
 47+
4448 #ifdef ATA_HAVE_BBT
4549 extern uint16_t (*ata_bbt)[0x20];
4650 extern uint64_t ata_virtual_sectors;
Index: emcore/trunk/target/ipodclassic/storage_ata.c
@@ -45,6 +45,8 @@
4646 static struct scheduler_thread ata_thread_handle;
4747 static uint32_t ata_stack[0x80] STACK_ATTR;
4848 static bool ata_powered;
 49+static int ata_retries = ATA_RETRIES;
 50+static bool ata_error_srst = true;
4951
5052 #ifdef ATA_HAVE_BBT
5153 #include "panic.h"
@@ -53,18 +55,24 @@
5456 uint32_t ata_last_offset;
5557 uint64_t ata_last_phys;
5658
57 -void ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
 59+int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
5860 {
 61+ if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset();
5962 int rc = ata_rw_sectors_internal(sector, count, buffer, false);
 63+ if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false);
 64+ ata_last_phys = sector + count - 1;
 65+ ata_last_offset = 0;
6066 if (IS_ERR(rc))
61 - panicf(PANIC_KILLTHREAD, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
62 - rc, sector, count);
 67+ cprintf(CONSOLE_BOOT, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
 68+ rc, sector, count);
 69+ return rc;
6370 }
6471 #endif
6572
6673 static struct ata_target_driverinfo drvinfo =
6774 {
68 - .soft_reset = ata_soft_reset,
 75+ .set_retries = ata_set_retries,
 76+ .srst_after_error = ata_srst_after_error,
6977 #ifdef ATA_HAVE_BBT
7078 .bbt_translate = ata_bbt_translate,
7179 .bbt_reload = ata_bbt_reload,
@@ -73,6 +81,16 @@
7482 };
7583
7684
 85+void ata_set_retries(int retries)
 86+{
 87+ ata_retries = retries;
 88+}
 89+
 90+void ata_srst_after_error(bool enable)
 91+{
 92+ ata_error_srst = enable;
 93+}
 94+
7795 static uint16_t ata_read_cbr(uint32_t volatile* reg)
7896 {
7997 while (!(ATA_PIO_READY & 2)) yield();
@@ -151,6 +169,16 @@
152170 ata_last_activity_value = USEC_TIMER;
153171 }
154172
 173+bool ata_disk_is_active(void)
 174+{
 175+ return ata_powered;
 176+}
 177+
 178+int ata_num_drives(void)
 179+{
 180+ return 1;
 181+}
 182+
155183 int ata_set_feature(uint32_t feature, uint32_t param)
156184 {
157185 PASS_RC(ata_wait_for_rdy(500000), 1, 0);
@@ -439,8 +467,8 @@
440468 uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
441469 int rc = -1;
442470 rc = ata_rw_chunk(sector, cnt, buffer, write);
443 - if (rc) ata_soft_reset();
444 - if (rc && ATA_RETRIES)
 471+ if (rc && ata_error_srst) ata_soft_reset();
 472+ if (rc && ata_retries)
445473 {
446474 void* buf = buffer;
447475 uint64_t sect;
@@ -447,11 +475,11 @@
448476 for (sect = sector; sect < sector + cnt; sect++)
449477 {
450478 rc = -1;
451 - int tries = ATA_RETRIES;
 479+ int tries = ata_retries;
452480 while (tries-- && rc)
453481 {
454482 rc = ata_rw_chunk(sect, 1, buf, write);
455 - if (rc) ata_soft_reset();
 483+ if (rc && ata_error_srst) ata_soft_reset();
456484 }
457485 if (rc) break;
458486 buf += SECTOR_SIZE;
@@ -496,6 +524,7 @@
497525 }
498526 ata_set_active();
499527 mutex_unlock(&ata_mutex);
 528+ return rc;
500529 }
501530
502531 int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
@@ -580,23 +609,38 @@
581610 uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
582611 if (buf)
583612 {
584 - ata_bbt_read_sectors(0, 1, buf);
585 - if (!memcmp(buf, "emBIbbth", 8))
 613+ if (IS_ERR(ata_bbt_read_sectors(0, 1, buf)))
 614+ ata_virtual_sectors = ata_total_sectors;
 615+ else if (!memcmp(buf, "emBIbbth", 8))
586616 {
587617 ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
588618 uint32_t count = buf[0x1ff];
589619 ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
590 - uint32_t i;
591 - uint32_t cnt;
592 - for (i = 0; i < count; i += cnt)
 620+ if (!ata_bbt)
593621 {
594 - uint32_t phys = buf[0x200 + i];
595 - for (cnt = 1; cnt < count; cnt++)
596 - if (buf[0x200 + i + cnt] != phys + cnt)
 622+ cprintf(CONSOLE_BOOT, "ATA: Failed to allocate memory for BBT! (%d bytes)",
 623+ 0x1000 * count);
 624+ ata_virtual_sectors = ata_total_sectors;
 625+ }
 626+ else
 627+ {
 628+ uint32_t i;
 629+ uint32_t cnt;
 630+ for (i = 0; i < count; i += cnt)
 631+ {
 632+ uint32_t phys = buf[0x200 + i];
 633+ for (cnt = 1; cnt < count; cnt++)
 634+ if (buf[0x200 + i + cnt] != phys + cnt)
 635+ break;
 636+ if (IS_ERR(ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6])))
 637+ {
 638+ free(ata_bbt);
 639+ ata_virtual_sectors = ata_total_sectors;
597640 break;
598 - ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
 641+ }
 642+ }
 643+ if (ata_bbt) reownalloc(ata_bbt, NULL);
599644 }
600 - reownalloc(ata_bbt, NULL);
601645 }
602646 else ata_virtual_sectors = ata_total_sectors;
603647 free(buf);