Subversion Repositories freemyipod

Rev

Rev 614 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 614 Rev 620
Line 43... Line 43...
43
static long ata_last_activity_value = -1;
43
static long ata_last_activity_value = -1;
44
static long ata_sleep_timeout = 20000000;
44
static long ata_sleep_timeout = 20000000;
45
static struct scheduler_thread ata_thread_handle;
45
static struct scheduler_thread ata_thread_handle;
46
static uint32_t ata_stack[0x80] STACK_ATTR;
46
static uint32_t ata_stack[0x80] STACK_ATTR;
47
static bool ata_powered;
47
static bool ata_powered;
-
 
48
static int ata_retries = ATA_RETRIES;
-
 
49
static bool ata_error_srst = true;
48
 
50
 
49
#ifdef ATA_HAVE_BBT
51
#ifdef ATA_HAVE_BBT
50
#include "panic.h"
52
#include "panic.h"
51
uint16_t (*ata_bbt)[0x20];
53
uint16_t (*ata_bbt)[0x20];
52
uint64_t ata_virtual_sectors;
54
uint64_t ata_virtual_sectors;
53
uint32_t ata_last_offset;
55
uint32_t ata_last_offset;
54
uint64_t ata_last_phys;
56
uint64_t ata_last_phys;
55
 
57
 
56
void ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
58
int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
57
{
59
{
-
 
60
    if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset();
58
    int rc = ata_rw_sectors_internal(sector, count, buffer, false);
61
    int rc = ata_rw_sectors_internal(sector, count, buffer, false);
-
 
62
    if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false);
-
 
63
    ata_last_phys = sector + count - 1;
-
 
64
    ata_last_offset = 0;
59
    if (IS_ERR(rc))
65
    if (IS_ERR(rc))
60
        panicf(PANIC_KILLTHREAD, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
66
        cprintf(CONSOLE_BOOT, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
61
               rc, sector, count);
67
                rc, sector, count);
-
 
68
    return rc;
62
}
69
}
63
#endif
70
#endif
64
 
71
 
65
static struct ata_target_driverinfo drvinfo =
72
static struct ata_target_driverinfo drvinfo =
66
{
73
{
67
    .soft_reset = ata_soft_reset,
74
    .set_retries = ata_set_retries,
-
 
75
    .srst_after_error = ata_srst_after_error,
68
#ifdef ATA_HAVE_BBT
76
#ifdef ATA_HAVE_BBT
69
    .bbt_translate = ata_bbt_translate,
77
    .bbt_translate = ata_bbt_translate,
70
    .bbt_reload = ata_bbt_reload,
78
    .bbt_reload = ata_bbt_reload,
71
    .bbt_disable = ata_bbt_disable
79
    .bbt_disable = ata_bbt_disable
72
#endif
80
#endif
73
};
81
};
74
 
82
 
75
 
83
 
-
 
84
void ata_set_retries(int retries)
-
 
85
{
-
 
86
    ata_retries = retries;
-
 
87
}
-
 
88
 
-
 
89
void ata_srst_after_error(bool enable)
-
 
90
{
-
 
91
    ata_error_srst = enable;
-
 
92
}
-
 
93
 
76
static uint16_t ata_read_cbr(uint32_t volatile* reg)
94
static uint16_t ata_read_cbr(uint32_t volatile* reg)
77
{
95
{
78
    while (!(ATA_PIO_READY & 2)) yield();
96
    while (!(ATA_PIO_READY & 2)) yield();
79
    volatile uint32_t dummy = *reg;
97
    volatile uint32_t dummy = *reg;
80
    while (!(ATA_PIO_READY & 1)) yield();
98
    while (!(ATA_PIO_READY & 1)) yield();
Line 149... Line 167...
149
void ata_set_active(void)
167
void ata_set_active(void)
150
{
168
{
151
    ata_last_activity_value = USEC_TIMER;
169
    ata_last_activity_value = USEC_TIMER;
152
}
170
}
153
 
171
 
-
 
172
bool ata_disk_is_active(void)
-
 
173
{
-
 
174
    return ata_powered;
-
 
175
}
-
 
176
 
-
 
177
int ata_num_drives(void)
-
 
178
{
-
 
179
    return 1;
-
 
180
}
-
 
181
 
154
int ata_set_feature(uint32_t feature, uint32_t param)
182
int ata_set_feature(uint32_t feature, uint32_t param)
155
{
183
{
156
    PASS_RC(ata_wait_for_rdy(500000), 1, 0);
184
    PASS_RC(ata_wait_for_rdy(500000), 1, 0);
157
    ata_write_cbr(&ATA_PIO_DVR, 0);
185
    ata_write_cbr(&ATA_PIO_DVR, 0);
158
    ata_write_cbr(&ATA_PIO_FED, 3);
186
    ata_write_cbr(&ATA_PIO_FED, 3);
Line 437... Line 465...
437
    while (count)
465
    while (count)
438
    {
466
    {
439
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
467
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
440
        int rc = -1;
468
        int rc = -1;
441
        rc = ata_rw_chunk(sector, cnt, buffer, write);
469
        rc = ata_rw_chunk(sector, cnt, buffer, write);
442
        if (rc) ata_soft_reset();
470
        if (rc && ata_error_srst) ata_soft_reset();
443
        if (rc && ATA_RETRIES)
471
        if (rc && ata_retries)
444
        {
472
        {
445
            void* buf = buffer;
473
            void* buf = buffer;
446
            uint64_t sect;
474
            uint64_t sect;
447
            for (sect = sector; sect < sector + cnt; sect++)
475
            for (sect = sector; sect < sector + cnt; sect++)
448
            {
476
            {
449
                rc = -1;
477
                rc = -1;
450
                int tries = ATA_RETRIES;
478
                int tries = ata_retries;
451
                while (tries-- && rc)
479
                while (tries-- && rc)
452
                {
480
                {
453
                    rc = ata_rw_chunk(sect, 1, buf, write);
481
                    rc = ata_rw_chunk(sect, 1, buf, write);
454
                    if (rc) ata_soft_reset();
482
                    if (rc && ata_error_srst) ata_soft_reset();
455
                }
483
                }
456
                if (rc) break;
484
                if (rc) break;
457
                buf += SECTOR_SIZE;
485
                buf += SECTOR_SIZE;
458
            }
486
            }
459
        }
487
        }
Line 494... Line 522...
494
        sleep(3000000);
522
        sleep(3000000);
495
        ata_power_up();
523
        ata_power_up();
496
    }
524
    }
497
    ata_set_active();
525
    ata_set_active();
498
    mutex_unlock(&ata_mutex);
526
    mutex_unlock(&ata_mutex);
-
 
527
    return rc;
499
}
528
}
500
 
529
 
501
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
530
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
502
                     void* inbuf)
531
                     void* inbuf)
503
{
532
{
Line 578... Line 607...
578
    ata_bbt_disable();
607
    ata_bbt_disable();
579
    ata_power_up();
608
    ata_power_up();
580
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
609
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
581
    if (buf)
610
    if (buf)
582
    {
611
    {
583
        ata_bbt_read_sectors(0, 1, buf);
612
        if (IS_ERR(ata_bbt_read_sectors(0, 1, buf)))
-
 
613
            ata_virtual_sectors = ata_total_sectors;
584
        if (!memcmp(buf, "emBIbbth", 8))
614
        else if (!memcmp(buf, "emBIbbth", 8))
585
        {
615
        {
586
            ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
616
            ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
587
            uint32_t count = buf[0x1ff];
617
            uint32_t count = buf[0x1ff];
588
            ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
618
            ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
589
            uint32_t i;
-
 
590
            uint32_t cnt;
619
            if (!ata_bbt)
591
            for (i = 0; i < count; i += cnt)
-
 
592
            {
620
            {
-
 
621
                cprintf(CONSOLE_BOOT, "ATA: Failed to allocate memory for BBT! (%d bytes)",
-
 
622
                        0x1000 * count);
-
 
623
                ata_virtual_sectors = ata_total_sectors;
-
 
624
            }
-
 
625
            else
-
 
626
            {
-
 
627
                uint32_t i;
-
 
628
                uint32_t cnt;
-
 
629
                for (i = 0; i < count; i += cnt)
-
 
630
                {
593
                uint32_t phys = buf[0x200 + i];
631
                    uint32_t phys = buf[0x200 + i];
594
                for (cnt = 1; cnt < count; cnt++)
632
                    for (cnt = 1; cnt < count; cnt++)
595
                    if (buf[0x200 + i + cnt] != phys + cnt)
633
                        if (buf[0x200 + i + cnt] != phys + cnt)
-
 
634
                            break;
-
 
635
                    if (IS_ERR(ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6])))
-
 
636
                    {
-
 
637
                        free(ata_bbt);
-
 
638
                        ata_virtual_sectors = ata_total_sectors;
596
                        break;
639
                        break;
-
 
640
                    }
-
 
641
                }
597
                ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
642
                if (ata_bbt) reownalloc(ata_bbt, NULL);
598
            }
643
            }
599
            reownalloc(ata_bbt, NULL);
-
 
600
        }
644
        }
601
        else ata_virtual_sectors = ata_total_sectors;
645
        else ata_virtual_sectors = ata_total_sectors;
602
        free(buf);
646
        free(buf);
603
    }
647
    }
604
    else ata_virtual_sectors = ata_total_sectors;
648
    else ata_virtual_sectors = ata_total_sectors;