Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
301 theseven 1
/***************************************************************************
2
 *             __________               __   ___.
3
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7
 *                     \/            \/     \/    \/            \/
8
 * $Id$
9
 *
10
 * Copyright (C) 2007 Dave Chapman
11
 *
12
 * This program is free software; you can redistribute it and/or
13
 * modify it under the terms of the GNU General Public License
14
 * as published by the Free Software Foundation; either version 2
15
 * of the License, or (at your option) any later version.
16
 *
17
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18
 * KIND, either express or implied.
19
 *
20
 ****************************************************************************/
21
#include "global.h"
22
#include "thread.h"
23
#include "disk.h"
24
#include "storage.h"
339 theseven 25
#include "storage_ata-target.h"
301 theseven 26
#include "timer.h"
27
#include "../ipodnano3g/s5l8702.h"
28
 
613 theseven 29
 
30
#ifndef ATA_RETRIES
31
#define ATA_RETRIES 3
32
#endif
33
 
34
 
301 theseven 35
/** static, private data **/ 
36
uint16_t ata_identify_data[0x100];
37
bool ata_lba48;
38
bool ata_dma;
39
uint64_t ata_total_sectors;
601 theseven 40
struct mutex ata_mutex;
301 theseven 41
static struct wakeup ata_wakeup;
42
static uint32_t ata_dma_flags;
43
static long ata_last_activity_value = -1;
44
static long ata_sleep_timeout = 20000000;
429 theseven 45
static struct scheduler_thread ata_thread_handle;
46
static uint32_t ata_stack[0x80] STACK_ATTR;
301 theseven 47
static bool ata_powered;
620 theseven 48
static int ata_retries = ATA_RETRIES;
49
static bool ata_error_srst = true;
301 theseven 50
 
328 theseven 51
#ifdef ATA_HAVE_BBT
52
#include "panic.h"
430 theseven 53
uint16_t (*ata_bbt)[0x20];
339 theseven 54
uint64_t ata_virtual_sectors;
337 theseven 55
uint32_t ata_last_offset;
56
uint64_t ata_last_phys;
301 theseven 57
 
620 theseven 58
int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
328 theseven 59
{
620 theseven 60
    if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset();
328 theseven 61
    int rc = ata_rw_sectors_internal(sector, count, buffer, false);
620 theseven 62
    if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false);
63
    ata_last_phys = sector + count - 1;
64
    ata_last_offset = 0;
328 theseven 65
    if (IS_ERR(rc))
620 theseven 66
        cprintf(CONSOLE_BOOT, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
67
                rc, sector, count);
68
    return rc;
328 theseven 69
}
70
#endif
71
 
613 theseven 72
static struct ata_target_driverinfo drvinfo =
73
{
620 theseven 74
    .set_retries = ata_set_retries,
75
    .srst_after_error = ata_srst_after_error,
613 theseven 76
#ifdef ATA_HAVE_BBT
77
    .bbt_translate = ata_bbt_translate,
78
    .bbt_reload = ata_bbt_reload,
79
    .bbt_disable = ata_bbt_disable
80
#endif
81
};
328 theseven 82
 
613 theseven 83
 
620 theseven 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
 
301 theseven 94
static uint16_t ata_read_cbr(uint32_t volatile* reg)
95
{
317 theseven 96
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 97
    volatile uint32_t dummy = *reg;
317 theseven 98
    while (!(ATA_PIO_READY & 1)) yield();
301 theseven 99
    return ATA_PIO_RDATA;
100
}
101
 
102
static void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
103
{
317 theseven 104
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 105
    *reg = data;
106
}
107
 
108
static int ata_wait_for_not_bsy(long timeout)
109
{
110
    long startusec = USEC_TIMER;
111
    while (true)
112
    {
113
        uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
114
        if (!(csd & BIT(7))) return 0;
115
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0);
116
    }
117
}
118
 
119
static int ata_wait_for_rdy(long timeout)
120
{
121
    long startusec = USEC_TIMER;
122
    PASS_RC(ata_wait_for_not_bsy(timeout), 1, 0);
123
    while (true)
124
    {
125
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
126
        if (dad & BIT(6)) return 0;
127
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1);
128
    }
129
}
130
 
131
static int ata_wait_for_start_of_transfer(long timeout)
132
{
133
    long startusec = USEC_TIMER;
134
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
135
    while (true)
136
    {
137
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
138
        if (dad & BIT(0)) RET_ERR(1);
139
        if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0;
140
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2);
141
    }
142
}
143
 
144
static int ata_wait_for_end_of_transfer(long timeout)
145
{
146
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
147
    uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
148
    if (dad & BIT(0)) RET_ERR(1);
149
    if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0;
150
    RET_ERR(2);
151
}    
152
 
153
int ata_identify(uint16_t* buf)
154
{
155
    int i;
156
    PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
157
    ata_write_cbr(&ATA_PIO_DVR, 0);
158
    ata_write_cbr(&ATA_PIO_CSD, 0xec);
159
    PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
160
    for (i = 0; i < 0x100; i++)
161
    {
162
        uint16_t word = ata_read_cbr(&ATA_PIO_DTR);
163
        buf[i] = (word >> 8) | (word << 8);
164
    }
165
}
166
 
167
void ata_set_active(void)
168
{
169
    ata_last_activity_value = USEC_TIMER;
170
}
171
 
620 theseven 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
 
317 theseven 182
int ata_set_feature(uint32_t feature, uint32_t param)
183
{
184
    PASS_RC(ata_wait_for_rdy(500000), 1, 0);
185
    ata_write_cbr(&ATA_PIO_DVR, 0);
186
    ata_write_cbr(&ATA_PIO_FED, 3);
187
    ata_write_cbr(&ATA_PIO_SCR, param);
188
    ata_write_cbr(&ATA_PIO_CSD, feature);
189
    PASS_RC(ata_wait_for_rdy(500000), 1, 1);
190
    return 0;
191
}
192
 
301 theseven 193
int ata_power_up()
194
{
195
    ata_set_active();
357 theseven 196
    if (ata_powered) return 0;
301 theseven 197
    i2c_sendbyte(0, 0xe6, 0x1b, 1);
198
    clockgate_enable(5, true);
199
    ATA_CFG = BIT(0);
200
    sleep(1000);
201
    ATA_CFG = 0;
202
    sleep(6000);
203
    ATA_SWRST = BIT(0);
204
    sleep(500);
205
    ATA_SWRST = 0;
206
    sleep(90000);
207
    ATA_CONTROL = BIT(0);
208
    sleep(200000);
209
    ATA_PIO_TIME = 0x191f7;
210
    ATA_PIO_LHR = 0;
211
    while (!(ATA_PIO_READY & BIT(1))) sleep(100);
212
    PASS_RC(ata_identify(ata_identify_data), 2, 0);
213
    uint32_t piotime = 0x11f3;
214
    uint32_t mdmatime = 0x1c175;
215
    uint32_t udmatime = 0x5071152;
216
    uint32_t param = 0;
217
    ata_dma_flags = 0;
218
    ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
219
    if (ata_lba48)
220
        ata_total_sectors = ata_identify_data[100]
221
                          | (((uint64_t)ata_identify_data[101]) << 16)
222
                          | (((uint64_t)ata_identify_data[102]) << 32)
223
                          | (((uint64_t)ata_identify_data[103]) << 48);
224
    else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
328 theseven 225
    ata_total_sectors >>= 3;
301 theseven 226
    if (ata_identify_data[53] & BIT(1))
227
    {
228
        if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
229
        else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
230
    }
231
    if (ata_identify_data[63] & BIT(2))
232
    {
233
        mdmatime = 0x5072;
234
        param = 0x22;
235
    }
236
    else if (ata_identify_data[63] & BIT(1))
237
    {
238
        mdmatime = 0x7083;
239
        param = 0x21;
240
    }
241
    if (ata_identify_data[63] & BITRANGE(0, 2))
242
    {
243
        ata_dma_flags = BIT(3) | BIT(10);
244
        param |= 0x20;
245
    }
246
    if (ata_identify_data[53] & BIT(2))
247
    {
248
        if (ata_identify_data[88] & BIT(4))
249
        {
250
            udmatime = 0x2010a52;
251
            param = 0x44;
252
        }
253
        else if (ata_identify_data[88] & BIT(3))
254
        {
255
            udmatime = 0x2020a52;
256
            param = 0x43;
257
        }
258
        else if (ata_identify_data[88] & BIT(2))
259
        {
260
            udmatime = 0x3030a52;
261
            param = 0x42;
262
        }
263
        else if (ata_identify_data[88] & BIT(1))
264
        {
265
            udmatime = 0x3050a52;
266
            param = 0x41;
267
        }
268
        if (ata_identify_data[88] & BITRANGE(0, 4))
269
        {
270
            ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
271
            param |= 0x40;
272
        }
273
    }
274
    ata_dma = param ? true : false;
317 theseven 275
    PASS_RC(ata_set_feature(0xef, param), 2, 1);
337 theseven 276
    if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
277
    if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
301 theseven 278
    ATA_PIO_TIME = piotime;
279
    ATA_MDMA_TIME = mdmatime;
280
    ATA_UDMA_TIME = udmatime;
281
    ata_powered = true;
282
    ata_set_active();
283
    return 0;
284
}
285
 
286
void ata_power_down()
287
{
357 theseven 288
    if (!ata_powered) return;
301 theseven 289
    ata_powered = false;
290
    ata_wait_for_rdy(1000000);
291
    ata_write_cbr(&ATA_PIO_DVR, 0);
292
    ata_write_cbr(&ATA_PIO_CSD, 0xe0);
293
    ata_wait_for_rdy(1000000);
294
    sleep(30000);
295
    ATA_CONTROL = 0;
317 theseven 296
    while (!(ATA_CONTROL & BIT(1))) yield();
301 theseven 297
    clockgate_enable(5, false);
298
    i2c_sendbyte(0, 0xe6, 0x1b, 0);
299
}
300
 
337 theseven 301
int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
302
{
303
    PASS_RC(ata_wait_for_rdy(100000), 2, 0);
304
    ata_write_cbr(&ATA_PIO_DVR, 0);
305
    if (ata_lba48)
306
    {
307
        ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
308
        ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
309
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
310
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
311
        ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
312
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
313
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
314
        ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
315
        ata_write_cbr(&ATA_PIO_DVR, BIT(6));
316
        if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
317
        else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
318
    }
319
    else
320
    {
321
        ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
322
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
323
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
324
        ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
325
        ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
326
        if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
327
        else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
328
    }
329
    if (ata_dma)
330
    {
331
        PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
332
        if (write)
333
        {
334
            ATA_SBUF_START = buffer;
335
            ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
336
            ATA_CFG |= BIT(4);
337
        }
338
        else
339
        {
340
            ATA_TBUF_START = buffer;
341
            ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
342
            ATA_CFG &= ~BIT(4);
343
        }
344
        ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
345
        ATA_CFG |= ata_dma_flags;
346
        ATA_CFG &= ~(BIT(7) | BIT(8));
347
        wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
348
        ATA_IRQ = BITRANGE(0, 4);
349
        ATA_IRQ_MASK = BIT(0);
350
        ATA_COMMAND = BIT(0);
351
        if (wakeup_wait(&ata_wakeup, 500000) == THREAD_TIMEOUT)
352
        {
353
            ATA_COMMAND = BIT(1);
354
            ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
355
            RET_ERR(2);
356
        }
357
        ATA_COMMAND = BIT(1);
358
        ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
359
    }
360
    else
361
    {
362
        cnt *= SECTOR_SIZE / 512;
363
        while (cnt--)
364
        {
365
            int i;
366
            PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
367
            if (write)
368
                for (i = 0; i < 256; i++)
369
                    ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
370
            else
371
                for (i = 0; i < 256; i++)
372
                    ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
373
            buffer += 512;
374
        }
375
    }
376
    PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
377
    return 0;
378
}
379
 
613 theseven 380
#ifdef ATA_HAVE_BBT
381
int ata_bbt_translate(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount)
382
{
383
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
384
    if (!ata_bbt)
385
    {
386
        *phys = sector;
387
        *physcount = count;
388
        return 0;
389
    }
390
    if (!count)
391
    {
392
        *phys = 0;
393
        *physcount = 0;
394
        return 0;
395
    }
396
    uint32_t offset;
397
    uint32_t l0idx = sector >> 15;
398
    uint32_t l0offs = sector & 0x7fff;
399
    *physcount = MIN(count, 0x8000 - l0offs);
400
    uint32_t l0data = ata_bbt[0][l0idx << 1];
401
    uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
402
    if (l0data < 0x8000) offset = l0data + base;
403
    else
404
    {
405
        uint32_t l1idx = (sector >> 10) & 0x1f;
406
        uint32_t l1offs = sector & 0x3ff;
407
        *physcount = MIN(count, 0x400 - l1offs);
408
        uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
409
        if (l1data < 0x8000) offset = l1data + base;
410
        else
411
        {
412
            uint32_t l2idx = (sector >> 5) & 0x1f;
413
            uint32_t l2offs = sector & 0x1f;
414
            *physcount = MIN(count, 0x20 - l2offs);
415
            uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
416
            if (l2data < 0x8000) offset = l2data + base;
417
            else
418
            {
419
                uint32_t l3idx = sector & 0x1f;
420
                uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
421
                for (*physcount = 1; *physcount < count && l3idx + *physcount < 0x20; *physcount++)
422
                    if (ata_bbt[l2data & 0x7fff][l3idx + *physcount] != l3data)
423
                        break;
424
                offset = l3data + base;
425
            }
426
        }
427
    }
428
    *phys = sector + offset;
429
    return 0;
430
}
431
#endif
432
 
301 theseven 433
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
434
{
328 theseven 435
#ifdef ATA_HAVE_BBT
436
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
430 theseven 437
    if (ata_bbt)
438
        while (count)
328 theseven 439
        {
613 theseven 440
            uint64_t phys;
441
            uint32_t cnt;
442
            PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0);
443
            uint32_t offset = phys - sector;
430 theseven 444
            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
445
            ata_last_offset = offset;
446
            ata_last_phys = phys + cnt;
447
            PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
448
            buffer += cnt * SECTOR_SIZE;
449
            sector += cnt;
450
            count -= cnt;
328 theseven 451
        }
430 theseven 452
    else PASS_RC(ata_rw_sectors_internal(sector, count, buffer, write), 0, 0);
328 theseven 453
    return 0;
454
}
455
 
456
int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write)
457
{
458
#endif
301 theseven 459
    if (sector + count > ata_total_sectors) RET_ERR(0);
460
    if (!ata_powered) ata_power_up();
461
    ata_set_active();
462
    if (ata_dma && write) clean_dcache();
463
    else if (ata_dma) invalidate_dcache();
464
    ATA_COMMAND = BIT(1);
465
    while (count)
466
    {
317 theseven 467
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
337 theseven 468
        int rc = -1;
613 theseven 469
        rc = ata_rw_chunk(sector, cnt, buffer, write);
620 theseven 470
        if (rc && ata_error_srst) ata_soft_reset();
471
        if (rc && ata_retries)
301 theseven 472
        {
337 theseven 473
            void* buf = buffer;
405 theseven 474
            uint64_t sect;
337 theseven 475
            for (sect = sector; sect < sector + cnt; sect++)
476
            {
477
                rc = -1;
620 theseven 478
                int tries = ata_retries;
337 theseven 479
                while (tries-- && rc)
480
                {
481
                    rc = ata_rw_chunk(sect, 1, buf, write);
620 theseven 482
                    if (rc && ata_error_srst) ata_soft_reset();
337 theseven 483
                }
484
                if (rc) break;
485
                buf += SECTOR_SIZE;
486
            }
301 theseven 487
        }
337 theseven 488
        PASS_RC(rc, 1, 1);
489
        buffer += SECTOR_SIZE * cnt;
301 theseven 490
        sector += cnt;
491
        count -= cnt;
492
    }
493
    ata_set_active();
494
    return 0;
495
}
496
 
497
static void ata_thread(void)
498
{
499
    while (true)
500
    {
501
        mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
502
        if (TIME_AFTER(USEC_TIMER, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
503
            ata_power_down();
504
        mutex_unlock(&ata_mutex);
505
        sleep(1000000);
506
    }
507
}
508
 
509
/* API Functions */
510
int ata_soft_reset()
511
{
512
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
513
    if (!ata_powered) ata_power_up();
514
    ata_set_active();
515
    ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
516
    sleep(10);
517
    ata_write_cbr(&ATA_PIO_DAD, 0);
613 theseven 518
    int rc = ata_wait_for_rdy(20000000);
519
    if (IS_ERR(rc))
520
    {
521
        ata_power_down();
522
        sleep(3000000);
523
        ata_power_up();
524
    }
301 theseven 525
    ata_set_active();
526
    mutex_unlock(&ata_mutex);
620 theseven 527
    return rc;
301 theseven 528
}
529
 
530
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
531
                     void* inbuf)
532
{
533
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 534
    int rc = ata_rw_sectors(start, incount, inbuf, false);
301 theseven 535
    mutex_unlock(&ata_mutex);
536
    return rc;
537
}
538
 
539
int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
540
                      const void* outbuf)
541
{
542
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 543
    int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
301 theseven 544
    mutex_unlock(&ata_mutex);
545
    return rc;
546
}
547
 
337 theseven 548
void ata_spindown(int seconds)
549
{
550
    ata_sleep_timeout = seconds * 1000000;
551
}
301 theseven 552
 
553
void ata_sleep(void)
554
{
555
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
556
    ata_power_down();
557
    mutex_unlock(&ata_mutex);
558
}
559
 
560
void ata_sleepnow(void)
561
{
562
    ata_sleep();
563
}
564
 
565
void ata_close(void)
566
{
567
    ata_sleep();
568
}
569
 
570
void ata_spin(void)
571
{
572
    ata_power_up();
573
}
574
 
575
void ata_get_info(IF_MD2(int drive,) struct storage_info *info)
576
{
577
    (*info).sector_size = SECTOR_SIZE;
328 theseven 578
#ifdef ATA_HAVE_BBT
579
    (*info).num_sectors = ata_virtual_sectors;
580
#else
301 theseven 581
    (*info).num_sectors = ata_total_sectors;
328 theseven 582
#endif
301 theseven 583
    (*info).vendor = "Apple";
584
    (*info).product = "iPod Classic";
585
    (*info).revision = "1.0";
613 theseven 586
    (*info).driverinfo = &drvinfo;
301 theseven 587
}
588
 
589
long ata_last_disk_activity(void)
590
{
591
    return ata_last_activity_value;
592
}
593
 
613 theseven 594
#ifdef ATA_HAVE_BBT
595
void ata_bbt_disable()
301 theseven 596
{
328 theseven 597
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
613 theseven 598
    if (ata_bbt) free(ata_bbt);
430 theseven 599
    ata_bbt = NULL;
613 theseven 600
    ata_virtual_sectors = ata_total_sectors;
601
    mutex_unlock(&ata_mutex);
602
}
603
 
604
void ata_bbt_reload()
605
{
606
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
607
    ata_bbt_disable();
328 theseven 608
    ata_power_up();
430 theseven 609
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
610
    if (buf)
328 theseven 611
    {
620 theseven 612
        if (IS_ERR(ata_bbt_read_sectors(0, 1, buf)))
613
            ata_virtual_sectors = ata_total_sectors;
614
        else if (!memcmp(buf, "emBIbbth", 8))
328 theseven 615
        {
430 theseven 616
            ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
617
            uint32_t count = buf[0x1ff];
618
            ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
620 theseven 619
            if (!ata_bbt)
430 theseven 620
            {
620 theseven 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
                {
631
                    uint32_t phys = buf[0x200 + i];
632
                    for (cnt = 1; cnt < count; 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;
430 theseven 639
                        break;
620 theseven 640
                    }
641
                }
642
                if (ata_bbt) reownalloc(ata_bbt, NULL);
430 theseven 643
            }
328 theseven 644
        }
430 theseven 645
        else ata_virtual_sectors = ata_total_sectors;
646
        free(buf);
328 theseven 647
    }
437 theseven 648
    else ata_virtual_sectors = ata_total_sectors;
328 theseven 649
    mutex_unlock(&ata_mutex);
613 theseven 650
}
328 theseven 651
#endif
613 theseven 652
 
653
int ata_init(void)
654
{
655
    mutex_init(&ata_mutex);
656
    wakeup_init(&ata_wakeup);
657
    PCON(7) = 0x44444444;
658
    PCON(8) = 0x44444444;
659
    PCON(9) = 0x44444444;
660
    PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
661
    ata_powered = false;
662
    ata_total_sectors = 0;
663
#ifdef ATA_HAVE_BBT
664
    ata_bbt_reload();
665
#endif
429 theseven 666
    thread_create(&ata_thread_handle, "ATA idle monitor", ata_thread, ata_stack,
543 theseven 667
                  sizeof(ata_stack), OS_THREAD, 1, true);
301 theseven 668
    return 0;
669
}
670
 
671
#ifdef CONFIG_STORAGE_MULTI
672
int ata_num_drives(int first_drive)
673
{
674
    /* We don't care which logical drive number(s) we have been assigned */
675
    (void)first_drive;
676
 
677
    return 1;
678
}
679
#endif
680
 
681
void INT_ATA()
682
{
683
    uint32_t ata_irq = ATA_IRQ;
684
    ATA_IRQ = ata_irq;
685
    if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
686
    ATA_IRQ_MASK = 0;
687
}