Index: emcore/trunk/target/ipodclassic/storage_ata-target.h |
— | — | @@ -29,7 +29,8 @@ |
30 | 30 |
|
31 | 31 | struct ata_target_driverinfo
|
32 | 32 | {
|
33 | | - int (*soft_reset)();
|
| 33 | + void (*srst_after_error)(bool enable);
|
| 34 | + void (*set_retries)(int retries);
|
34 | 35 | int (*bbt_translate)(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount);
|
35 | 36 | void (*bbt_reload)();
|
36 | 37 | void (*bbt_disable)();
|
— | — | @@ -40,6 +41,9 @@ |
41 | 42 | extern uint64_t ata_total_sectors;
|
42 | 43 | extern struct mutex ata_mutex;
|
43 | 44 |
|
| 45 | +void ata_set_retries(int retries);
|
| 46 | +void ata_srst_after_error(bool enable);
|
| 47 | +
|
44 | 48 | #ifdef ATA_HAVE_BBT
|
45 | 49 | extern uint16_t (*ata_bbt)[0x20];
|
46 | 50 | extern uint64_t ata_virtual_sectors;
|
Index: emcore/trunk/target/ipodclassic/storage_ata.c |
— | — | @@ -45,6 +45,8 @@ |
46 | 46 | static struct scheduler_thread ata_thread_handle;
|
47 | 47 | static uint32_t ata_stack[0x80] STACK_ATTR;
|
48 | 48 | static bool ata_powered;
|
| 49 | +static int ata_retries = ATA_RETRIES;
|
| 50 | +static bool ata_error_srst = true;
|
49 | 51 |
|
50 | 52 | #ifdef ATA_HAVE_BBT
|
51 | 53 | #include "panic.h"
|
— | — | @@ -53,18 +55,24 @@ |
54 | 56 | uint32_t ata_last_offset;
|
55 | 57 | uint64_t ata_last_phys;
|
56 | 58 |
|
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)
|
58 | 60 | {
|
| 61 | + if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset();
|
59 | 62 | 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;
|
60 | 66 | 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;
|
63 | 70 | }
|
64 | 71 | #endif
|
65 | 72 |
|
66 | 73 | static struct ata_target_driverinfo drvinfo =
|
67 | 74 | {
|
68 | | - .soft_reset = ata_soft_reset,
|
| 75 | + .set_retries = ata_set_retries,
|
| 76 | + .srst_after_error = ata_srst_after_error,
|
69 | 77 | #ifdef ATA_HAVE_BBT
|
70 | 78 | .bbt_translate = ata_bbt_translate,
|
71 | 79 | .bbt_reload = ata_bbt_reload,
|
— | — | @@ -73,6 +81,16 @@ |
74 | 82 | };
|
75 | 83 |
|
76 | 84 |
|
| 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 | +
|
77 | 95 | static uint16_t ata_read_cbr(uint32_t volatile* reg)
|
78 | 96 | {
|
79 | 97 | while (!(ATA_PIO_READY & 2)) yield();
|
— | — | @@ -151,6 +169,16 @@ |
152 | 170 | ata_last_activity_value = USEC_TIMER;
|
153 | 171 | }
|
154 | 172 |
|
| 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 | +
|
155 | 183 | int ata_set_feature(uint32_t feature, uint32_t param)
|
156 | 184 | {
|
157 | 185 | PASS_RC(ata_wait_for_rdy(500000), 1, 0);
|
— | — | @@ -439,8 +467,8 @@ |
440 | 468 | uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
|
441 | 469 | int rc = -1;
|
442 | 470 | 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)
|
445 | 473 | {
|
446 | 474 | void* buf = buffer;
|
447 | 475 | uint64_t sect;
|
— | — | @@ -447,11 +475,11 @@ |
448 | 476 | for (sect = sector; sect < sector + cnt; sect++)
|
449 | 477 | {
|
450 | 478 | rc = -1;
|
451 | | - int tries = ATA_RETRIES;
|
| 479 | + int tries = ata_retries;
|
452 | 480 | while (tries-- && rc)
|
453 | 481 | {
|
454 | 482 | rc = ata_rw_chunk(sect, 1, buf, write);
|
455 | | - if (rc) ata_soft_reset();
|
| 483 | + if (rc && ata_error_srst) ata_soft_reset();
|
456 | 484 | }
|
457 | 485 | if (rc) break;
|
458 | 486 | buf += SECTOR_SIZE;
|
— | — | @@ -496,6 +524,7 @@ |
497 | 525 | }
|
498 | 526 | ata_set_active();
|
499 | 527 | mutex_unlock(&ata_mutex);
|
| 528 | + return rc;
|
500 | 529 | }
|
501 | 530 |
|
502 | 531 | int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
|
— | — | @@ -580,23 +609,38 @@ |
581 | 610 | uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
|
582 | 611 | if (buf)
|
583 | 612 | {
|
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))
|
586 | 616 | {
|
587 | 617 | ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
|
588 | 618 | uint32_t count = buf[0x1ff];
|
589 | 619 | 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)
|
593 | 621 | {
|
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;
|
597 | 640 | break;
|
598 | | - ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
|
| 641 | + }
|
| 642 | + }
|
| 643 | + if (ata_bbt) reownalloc(ata_bbt, NULL);
|
599 | 644 | }
|
600 | | - reownalloc(ata_bbt, NULL);
|
601 | 645 | }
|
602 | 646 | else ata_virtual_sectors = ata_total_sectors;
|
603 | 647 | free(buf);
|