Subversion Repositories freemyipod

Rev

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

Rev 601 Rev 613
Line 24... Line 24...
24
#include "storage.h"
24
#include "storage.h"
25
#include "storage_ata-target.h"
25
#include "storage_ata-target.h"
26
#include "timer.h"
26
#include "timer.h"
27
#include "../ipodnano3g/s5l8702.h"
27
#include "../ipodnano3g/s5l8702.h"
28
 
28
 
-
 
29
 
-
 
30
#ifndef ATA_RETRIES
-
 
31
#define ATA_RETRIES 3
-
 
32
#endif
-
 
33
 
-
 
34
 
29
/** static, private data **/ 
35
/** static, private data **/ 
30
uint16_t ata_identify_data[0x100];
36
uint16_t ata_identify_data[0x100];
31
bool ata_lba48;
37
bool ata_lba48;
32
bool ata_dma;
38
bool ata_dma;
33
uint64_t ata_total_sectors;
39
uint64_t ata_total_sectors;
Line 54... Line 60...
54
        panicf(PANIC_KILLTHREAD, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
60
        panicf(PANIC_KILLTHREAD, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
55
               rc, sector, count);
61
               rc, sector, count);
56
}
62
}
57
#endif
63
#endif
58
 
64
 
-
 
65
static struct ata_target_driverinfo drvinfo =
-
 
66
{
-
 
67
    .soft_reset = ata_soft_reset,
-
 
68
#ifdef ATA_HAVE_BBT
-
 
69
    .bbt_translate = ata_bbt_translate,
-
 
70
    .bbt_reload = ata_bbt_reload,
-
 
71
    .bbt_disable = ata_bbt_disable
-
 
72
#endif
-
 
73
};
-
 
74
 
59
 
75
 
60
static uint16_t ata_read_cbr(uint32_t volatile* reg)
76
static uint16_t ata_read_cbr(uint32_t volatile* reg)
61
{
77
{
62
    while (!(ATA_PIO_READY & 2)) yield();
78
    while (!(ATA_PIO_READY & 2)) yield();
63
    volatile uint32_t dummy = *reg;
79
    volatile uint32_t dummy = *reg;
Line 331... Line 347...
331
    }
347
    }
332
    PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
348
    PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
333
    return 0;
349
    return 0;
334
}
350
}
335
 
351
 
-
 
352
#ifdef ATA_HAVE_BBT
-
 
353
int ata_bbt_translate(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount)
-
 
354
{
-
 
355
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
-
 
356
    if (!ata_bbt)
-
 
357
    {
-
 
358
        *phys = sector;
-
 
359
        *physcount = count;
-
 
360
        return 0;
-
 
361
    }
-
 
362
    if (!count)
-
 
363
    {
-
 
364
        *phys = 0;
-
 
365
        *physcount = 0;
-
 
366
        return 0;
-
 
367
    }
-
 
368
    uint32_t offset;
-
 
369
    uint32_t l0idx = sector >> 15;
-
 
370
    uint32_t l0offs = sector & 0x7fff;
-
 
371
    *physcount = MIN(count, 0x8000 - l0offs);
-
 
372
    uint32_t l0data = ata_bbt[0][l0idx << 1];
-
 
373
    uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
-
 
374
    if (l0data < 0x8000) offset = l0data + base;
-
 
375
    else
-
 
376
    {
-
 
377
        uint32_t l1idx = (sector >> 10) & 0x1f;
-
 
378
        uint32_t l1offs = sector & 0x3ff;
-
 
379
        *physcount = MIN(count, 0x400 - l1offs);
-
 
380
        uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
-
 
381
        if (l1data < 0x8000) offset = l1data + base;
-
 
382
        else
-
 
383
        {
-
 
384
            uint32_t l2idx = (sector >> 5) & 0x1f;
-
 
385
            uint32_t l2offs = sector & 0x1f;
-
 
386
            *physcount = MIN(count, 0x20 - l2offs);
-
 
387
            uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
-
 
388
            if (l2data < 0x8000) offset = l2data + base;
-
 
389
            else
-
 
390
            {
-
 
391
                uint32_t l3idx = sector & 0x1f;
-
 
392
                uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
-
 
393
                for (*physcount = 1; *physcount < count && l3idx + *physcount < 0x20; *physcount++)
-
 
394
                    if (ata_bbt[l2data & 0x7fff][l3idx + *physcount] != l3data)
-
 
395
                        break;
-
 
396
                offset = l3data + base;
-
 
397
            }
-
 
398
        }
-
 
399
    }
-
 
400
    *phys = sector + offset;
-
 
401
    return 0;
-
 
402
}
-
 
403
#endif
-
 
404
 
336
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
405
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
337
{
406
{
338
#ifdef ATA_HAVE_BBT
407
#ifdef ATA_HAVE_BBT
339
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
408
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
340
    if (ata_bbt)
409
    if (ata_bbt)
341
        while (count)
410
        while (count)
342
        {
411
        {
343
            uint32_t offset;
412
            uint64_t phys;
344
            uint32_t l0idx = sector >> 15;
-
 
345
            uint32_t l0offs = sector & 0x7fff;
-
 
346
            uint32_t cnt = MIN(count, 0x8000 - l0offs);
-
 
347
            uint32_t l0data = ata_bbt[0][l0idx << 1];
-
 
348
            uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
-
 
349
            if (l0data < 0x8000) offset = l0data + base;
-
 
350
            else
-
 
351
            {
-
 
352
                uint32_t l1idx = (sector >> 10) & 0x1f;
-
 
353
                uint32_t l1offs = sector & 0x3ff;
-
 
354
                cnt = MIN(count, 0x400 - l1offs);
-
 
355
                uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
-
 
356
                if (l1data < 0x8000) offset = l1data + base;
-
 
357
                else
-
 
358
                {
-
 
359
                    uint32_t l2idx = (sector >> 5) & 0x1f;
-
 
360
                    uint32_t l2offs = sector & 0x1f;
-
 
361
                    cnt = MIN(count, 0x20 - l2offs);
-
 
362
                    uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
-
 
363
                    if (l2data < 0x8000) offset = l2data + base;
-
 
364
                    else
413
            uint32_t cnt;
365
                    {
-
 
366
                        uint32_t l3idx = sector & 0x1f;
-
 
367
                        uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
-
 
368
                        for (cnt = 1; cnt < count && l3idx + cnt < 0x20; cnt++)
414
            PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0);
369
                            if (ata_bbt[l2data & 0x7fff][l3idx + cnt] != l3data)
-
 
370
                                break;
-
 
371
                        offset = l3data + base;
-
 
372
                    }
-
 
373
                }
-
 
374
            }
-
 
375
            uint64_t phys = sector + offset;
415
            uint32_t offset = phys - sector;
376
            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
416
            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
377
            ata_last_offset = offset;
417
            ata_last_offset = offset;
378
            ata_last_phys = phys + cnt;
418
            ata_last_phys = phys + cnt;
379
            PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
419
            PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
380
            buffer += cnt * SECTOR_SIZE;
420
            buffer += cnt * SECTOR_SIZE;
Line 396... Line 436...
396
    ATA_COMMAND = BIT(1);
436
    ATA_COMMAND = BIT(1);
397
    while (count)
437
    while (count)
398
    {
438
    {
399
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
439
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
400
        int rc = -1;
440
        int rc = -1;
401
        int tries = 3;
-
 
402
        while (tries-- && rc)
-
 
403
        {
-
 
404
            rc = ata_rw_chunk(sector, cnt, buffer, write);
441
        rc = ata_rw_chunk(sector, cnt, buffer, write);
405
            if (rc) ata_soft_reset();
442
        if (rc) ata_soft_reset();
406
        }
-
 
407
        if (rc)
443
        if (rc && ATA_RETRIES)
408
        {
444
        {
409
            void* buf = buffer;
445
            void* buf = buffer;
410
            uint64_t sect;
446
            uint64_t sect;
411
            for (sect = sector; sect < sector + cnt; sect++)
447
            for (sect = sector; sect < sector + cnt; sect++)
412
            {
448
            {
413
                rc = -1;
449
                rc = -1;
414
                tries = 3;
450
                tries = ATA_RETRIES;
415
                while (tries-- && rc)
451
                while (tries-- && rc)
416
                {
452
                {
417
                    rc = ata_rw_chunk(sect, 1, buf, write);
453
                    rc = ata_rw_chunk(sect, 1, buf, write);
418
                    if (rc) ata_soft_reset();
454
                    if (rc) ata_soft_reset();
419
                }
455
                }
Line 449... Line 485...
449
    if (!ata_powered) ata_power_up();
485
    if (!ata_powered) ata_power_up();
450
    ata_set_active();
486
    ata_set_active();
451
    ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
487
    ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
452
    sleep(10);
488
    sleep(10);
453
    ata_write_cbr(&ATA_PIO_DAD, 0);
489
    ata_write_cbr(&ATA_PIO_DAD, 0);
454
    PASS_RC_MTX(ata_wait_for_rdy(60000000), 0, 0, &ata_mutex);
490
    int rc = ata_wait_for_rdy(20000000);
-
 
491
    if (IS_ERR(rc))
-
 
492
    {
-
 
493
        ata_power_down();
-
 
494
        sleep(3000000);
-
 
495
        ata_power_up();
-
 
496
    }
455
    ata_set_active();
497
    ata_set_active();
456
    mutex_unlock(&ata_mutex);
498
    mutex_unlock(&ata_mutex);
457
}
499
}
458
 
500
 
459
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
501
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
Line 510... Line 552...
510
    (*info).num_sectors = ata_total_sectors;
552
    (*info).num_sectors = ata_total_sectors;
511
#endif
553
#endif
512
    (*info).vendor = "Apple";
554
    (*info).vendor = "Apple";
513
    (*info).product = "iPod Classic";
555
    (*info).product = "iPod Classic";
514
    (*info).revision = "1.0";
556
    (*info).revision = "1.0";
-
 
557
    (*info).driverinfo = &drvinfo;
515
}
558
}
516
 
559
 
517
long ata_last_disk_activity(void)
560
long ata_last_disk_activity(void)
518
{
561
{
519
    return ata_last_activity_value;
562
    return ata_last_activity_value;
520
}
563
}
521
 
564
 
522
int ata_init(void)
-
 
523
{
-
 
524
    mutex_init(&ata_mutex);
-
 
525
    wakeup_init(&ata_wakeup);
-
 
526
    PCON(7) = 0x44444444;
-
 
527
    PCON(8) = 0x44444444;
-
 
528
    PCON(9) = 0x44444444;
-
 
529
    PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
-
 
530
    ata_powered = false;
-
 
531
    ata_total_sectors = 0;
-
 
532
#ifdef ATA_HAVE_BBT
565
#ifdef ATA_HAVE_BBT
-
 
566
void ata_bbt_disable()
-
 
567
{
533
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
568
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
-
 
569
    if (ata_bbt) free(ata_bbt);
534
    ata_bbt = NULL;
570
    ata_bbt = NULL;
-
 
571
    ata_virtual_sectors = ata_total_sectors;
-
 
572
    mutex_unlock(&ata_mutex);
-
 
573
}
-
 
574
 
-
 
575
void ata_bbt_reload()
-
 
576
{
-
 
577
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
-
 
578
    ata_bbt_disable();
535
    ata_power_up();
579
    ata_power_up();
536
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
580
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
537
    if (buf)
581
    if (buf)
538
    {
582
    {
539
        ata_bbt_read_sectors(0, 1, buf);
583
        ata_bbt_read_sectors(0, 1, buf);
Line 557... Line 601...
557
        else ata_virtual_sectors = ata_total_sectors;
601
        else ata_virtual_sectors = ata_total_sectors;
558
        free(buf);
602
        free(buf);
559
    }
603
    }
560
    else ata_virtual_sectors = ata_total_sectors;
604
    else ata_virtual_sectors = ata_total_sectors;
561
    mutex_unlock(&ata_mutex);
605
    mutex_unlock(&ata_mutex);
-
 
606
}
-
 
607
#endif
-
 
608
 
-
 
609
int ata_init(void)
-
 
610
{
-
 
611
    mutex_init(&ata_mutex);
-
 
612
    wakeup_init(&ata_wakeup);
-
 
613
    PCON(7) = 0x44444444;
-
 
614
    PCON(8) = 0x44444444;
-
 
615
    PCON(9) = 0x44444444;
-
 
616
    PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
-
 
617
    ata_powered = false;
-
 
618
    ata_total_sectors = 0;
-
 
619
#ifdef ATA_HAVE_BBT
-
 
620
    ata_bbt_reload();
562
#endif
621
#endif
563
    thread_create(&ata_thread_handle, "ATA idle monitor", ata_thread, ata_stack,
622
    thread_create(&ata_thread_handle, "ATA idle monitor", ata_thread, ata_stack,
564
                  sizeof(ata_stack), OS_THREAD, 1, true);
623
                  sizeof(ata_stack), OS_THREAD, 1, true);
565
    return 0;
624
    return 0;
566
}
625
}