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;
48
 
328 theseven 49
#ifdef ATA_HAVE_BBT
50
#include "panic.h"
430 theseven 51
uint16_t (*ata_bbt)[0x20];
339 theseven 52
uint64_t ata_virtual_sectors;
337 theseven 53
uint32_t ata_last_offset;
54
uint64_t ata_last_phys;
301 theseven 55
 
328 theseven 56
void ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
57
{
58
    int rc = ata_rw_sectors_internal(sector, count, buffer, false);
59
    if (IS_ERR(rc))
60
        panicf(PANIC_KILLTHREAD, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
61
               rc, sector, count);
62
}
63
#endif
64
 
613 theseven 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
};
328 theseven 74
 
613 theseven 75
 
301 theseven 76
static uint16_t ata_read_cbr(uint32_t volatile* reg)
77
{
317 theseven 78
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 79
    volatile uint32_t dummy = *reg;
317 theseven 80
    while (!(ATA_PIO_READY & 1)) yield();
301 theseven 81
    return ATA_PIO_RDATA;
82
}
83
 
84
static void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
85
{
317 theseven 86
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 87
    *reg = data;
88
}
89
 
90
static int ata_wait_for_not_bsy(long timeout)
91
{
92
    long startusec = USEC_TIMER;
93
    while (true)
94
    {
95
        uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
96
        if (!(csd & BIT(7))) return 0;
97
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0);
98
    }
99
}
100
 
101
static int ata_wait_for_rdy(long timeout)
102
{
103
    long startusec = USEC_TIMER;
104
    PASS_RC(ata_wait_for_not_bsy(timeout), 1, 0);
105
    while (true)
106
    {
107
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
108
        if (dad & BIT(6)) return 0;
109
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1);
110
    }
111
}
112
 
113
static int ata_wait_for_start_of_transfer(long timeout)
114
{
115
    long startusec = USEC_TIMER;
116
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
117
    while (true)
118
    {
119
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
120
        if (dad & BIT(0)) RET_ERR(1);
121
        if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0;
122
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2);
123
    }
124
}
125
 
126
static int ata_wait_for_end_of_transfer(long timeout)
127
{
128
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
129
    uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
130
    if (dad & BIT(0)) RET_ERR(1);
131
    if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0;
132
    RET_ERR(2);
133
}    
134
 
135
int ata_identify(uint16_t* buf)
136
{
137
    int i;
138
    PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
139
    ata_write_cbr(&ATA_PIO_DVR, 0);
140
    ata_write_cbr(&ATA_PIO_CSD, 0xec);
141
    PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
142
    for (i = 0; i < 0x100; i++)
143
    {
144
        uint16_t word = ata_read_cbr(&ATA_PIO_DTR);
145
        buf[i] = (word >> 8) | (word << 8);
146
    }
147
}
148
 
149
void ata_set_active(void)
150
{
151
    ata_last_activity_value = USEC_TIMER;
152
}
153
 
317 theseven 154
int ata_set_feature(uint32_t feature, uint32_t param)
155
{
156
    PASS_RC(ata_wait_for_rdy(500000), 1, 0);
157
    ata_write_cbr(&ATA_PIO_DVR, 0);
158
    ata_write_cbr(&ATA_PIO_FED, 3);
159
    ata_write_cbr(&ATA_PIO_SCR, param);
160
    ata_write_cbr(&ATA_PIO_CSD, feature);
161
    PASS_RC(ata_wait_for_rdy(500000), 1, 1);
162
    return 0;
163
}
164
 
301 theseven 165
int ata_power_up()
166
{
167
    ata_set_active();
357 theseven 168
    if (ata_powered) return 0;
301 theseven 169
    i2c_sendbyte(0, 0xe6, 0x1b, 1);
170
    clockgate_enable(5, true);
171
    ATA_CFG = BIT(0);
172
    sleep(1000);
173
    ATA_CFG = 0;
174
    sleep(6000);
175
    ATA_SWRST = BIT(0);
176
    sleep(500);
177
    ATA_SWRST = 0;
178
    sleep(90000);
179
    ATA_CONTROL = BIT(0);
180
    sleep(200000);
181
    ATA_PIO_TIME = 0x191f7;
182
    ATA_PIO_LHR = 0;
183
    while (!(ATA_PIO_READY & BIT(1))) sleep(100);
184
    PASS_RC(ata_identify(ata_identify_data), 2, 0);
185
    uint32_t piotime = 0x11f3;
186
    uint32_t mdmatime = 0x1c175;
187
    uint32_t udmatime = 0x5071152;
188
    uint32_t param = 0;
189
    ata_dma_flags = 0;
190
    ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
191
    if (ata_lba48)
192
        ata_total_sectors = ata_identify_data[100]
193
                          | (((uint64_t)ata_identify_data[101]) << 16)
194
                          | (((uint64_t)ata_identify_data[102]) << 32)
195
                          | (((uint64_t)ata_identify_data[103]) << 48);
196
    else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
328 theseven 197
    ata_total_sectors >>= 3;
301 theseven 198
    if (ata_identify_data[53] & BIT(1))
199
    {
200
        if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
201
        else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
202
    }
203
    if (ata_identify_data[63] & BIT(2))
204
    {
205
        mdmatime = 0x5072;
206
        param = 0x22;
207
    }
208
    else if (ata_identify_data[63] & BIT(1))
209
    {
210
        mdmatime = 0x7083;
211
        param = 0x21;
212
    }
213
    if (ata_identify_data[63] & BITRANGE(0, 2))
214
    {
215
        ata_dma_flags = BIT(3) | BIT(10);
216
        param |= 0x20;
217
    }
218
    if (ata_identify_data[53] & BIT(2))
219
    {
220
        if (ata_identify_data[88] & BIT(4))
221
        {
222
            udmatime = 0x2010a52;
223
            param = 0x44;
224
        }
225
        else if (ata_identify_data[88] & BIT(3))
226
        {
227
            udmatime = 0x2020a52;
228
            param = 0x43;
229
        }
230
        else if (ata_identify_data[88] & BIT(2))
231
        {
232
            udmatime = 0x3030a52;
233
            param = 0x42;
234
        }
235
        else if (ata_identify_data[88] & BIT(1))
236
        {
237
            udmatime = 0x3050a52;
238
            param = 0x41;
239
        }
240
        if (ata_identify_data[88] & BITRANGE(0, 4))
241
        {
242
            ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
243
            param |= 0x40;
244
        }
245
    }
246
    ata_dma = param ? true : false;
317 theseven 247
    PASS_RC(ata_set_feature(0xef, param), 2, 1);
337 theseven 248
    if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
249
    if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
301 theseven 250
    ATA_PIO_TIME = piotime;
251
    ATA_MDMA_TIME = mdmatime;
252
    ATA_UDMA_TIME = udmatime;
253
    ata_powered = true;
254
    ata_set_active();
255
    return 0;
256
}
257
 
258
void ata_power_down()
259
{
357 theseven 260
    if (!ata_powered) return;
301 theseven 261
    ata_powered = false;
262
    ata_wait_for_rdy(1000000);
263
    ata_write_cbr(&ATA_PIO_DVR, 0);
264
    ata_write_cbr(&ATA_PIO_CSD, 0xe0);
265
    ata_wait_for_rdy(1000000);
266
    sleep(30000);
267
    ATA_CONTROL = 0;
317 theseven 268
    while (!(ATA_CONTROL & BIT(1))) yield();
301 theseven 269
    clockgate_enable(5, false);
270
    i2c_sendbyte(0, 0xe6, 0x1b, 0);
271
}
272
 
337 theseven 273
int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
274
{
275
    PASS_RC(ata_wait_for_rdy(100000), 2, 0);
276
    ata_write_cbr(&ATA_PIO_DVR, 0);
277
    if (ata_lba48)
278
    {
279
        ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
280
        ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
281
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
282
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
283
        ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
284
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
285
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
286
        ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
287
        ata_write_cbr(&ATA_PIO_DVR, BIT(6));
288
        if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
289
        else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
290
    }
291
    else
292
    {
293
        ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
294
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
295
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
296
        ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
297
        ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
298
        if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
299
        else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
300
    }
301
    if (ata_dma)
302
    {
303
        PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
304
        if (write)
305
        {
306
            ATA_SBUF_START = buffer;
307
            ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
308
            ATA_CFG |= BIT(4);
309
        }
310
        else
311
        {
312
            ATA_TBUF_START = buffer;
313
            ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
314
            ATA_CFG &= ~BIT(4);
315
        }
316
        ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
317
        ATA_CFG |= ata_dma_flags;
318
        ATA_CFG &= ~(BIT(7) | BIT(8));
319
        wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
320
        ATA_IRQ = BITRANGE(0, 4);
321
        ATA_IRQ_MASK = BIT(0);
322
        ATA_COMMAND = BIT(0);
323
        if (wakeup_wait(&ata_wakeup, 500000) == THREAD_TIMEOUT)
324
        {
325
            ATA_COMMAND = BIT(1);
326
            ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
327
            RET_ERR(2);
328
        }
329
        ATA_COMMAND = BIT(1);
330
        ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
331
    }
332
    else
333
    {
334
        cnt *= SECTOR_SIZE / 512;
335
        while (cnt--)
336
        {
337
            int i;
338
            PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
339
            if (write)
340
                for (i = 0; i < 256; i++)
341
                    ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
342
            else
343
                for (i = 0; i < 256; i++)
344
                    ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
345
            buffer += 512;
346
        }
347
    }
348
    PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
349
    return 0;
350
}
351
 
613 theseven 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
 
301 theseven 405
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
406
{
328 theseven 407
#ifdef ATA_HAVE_BBT
408
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
430 theseven 409
    if (ata_bbt)
410
        while (count)
328 theseven 411
        {
613 theseven 412
            uint64_t phys;
413
            uint32_t cnt;
414
            PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0);
415
            uint32_t offset = phys - sector;
430 theseven 416
            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
417
            ata_last_offset = offset;
418
            ata_last_phys = phys + cnt;
419
            PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
420
            buffer += cnt * SECTOR_SIZE;
421
            sector += cnt;
422
            count -= cnt;
328 theseven 423
        }
430 theseven 424
    else PASS_RC(ata_rw_sectors_internal(sector, count, buffer, write), 0, 0);
328 theseven 425
    return 0;
426
}
427
 
428
int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write)
429
{
430
#endif
301 theseven 431
    if (sector + count > ata_total_sectors) RET_ERR(0);
432
    if (!ata_powered) ata_power_up();
433
    ata_set_active();
434
    if (ata_dma && write) clean_dcache();
435
    else if (ata_dma) invalidate_dcache();
436
    ATA_COMMAND = BIT(1);
437
    while (count)
438
    {
317 theseven 439
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
337 theseven 440
        int rc = -1;
613 theseven 441
        rc = ata_rw_chunk(sector, cnt, buffer, write);
442
        if (rc) ata_soft_reset();
443
        if (rc && ATA_RETRIES)
301 theseven 444
        {
337 theseven 445
            void* buf = buffer;
405 theseven 446
            uint64_t sect;
337 theseven 447
            for (sect = sector; sect < sector + cnt; sect++)
448
            {
449
                rc = -1;
613 theseven 450
                tries = ATA_RETRIES;
337 theseven 451
                while (tries-- && rc)
452
                {
453
                    rc = ata_rw_chunk(sect, 1, buf, write);
454
                    if (rc) ata_soft_reset();
455
                }
456
                if (rc) break;
457
                buf += SECTOR_SIZE;
458
            }
301 theseven 459
        }
337 theseven 460
        PASS_RC(rc, 1, 1);
461
        buffer += SECTOR_SIZE * cnt;
301 theseven 462
        sector += cnt;
463
        count -= cnt;
464
    }
465
    ata_set_active();
466
    return 0;
467
}
468
 
469
static void ata_thread(void)
470
{
471
    while (true)
472
    {
473
        mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
474
        if (TIME_AFTER(USEC_TIMER, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
475
            ata_power_down();
476
        mutex_unlock(&ata_mutex);
477
        sleep(1000000);
478
    }
479
}
480
 
481
/* API Functions */
482
int ata_soft_reset()
483
{
484
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
485
    if (!ata_powered) ata_power_up();
486
    ata_set_active();
487
    ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
488
    sleep(10);
489
    ata_write_cbr(&ATA_PIO_DAD, 0);
613 theseven 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
    }
301 theseven 497
    ata_set_active();
498
    mutex_unlock(&ata_mutex);
499
}
500
 
501
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
502
                     void* inbuf)
503
{
504
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 505
    int rc = ata_rw_sectors(start, incount, inbuf, false);
301 theseven 506
    mutex_unlock(&ata_mutex);
507
    return rc;
508
}
509
 
510
int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
511
                      const void* outbuf)
512
{
513
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 514
    int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
301 theseven 515
    mutex_unlock(&ata_mutex);
516
    return rc;
517
}
518
 
337 theseven 519
void ata_spindown(int seconds)
520
{
521
    ata_sleep_timeout = seconds * 1000000;
522
}
301 theseven 523
 
524
void ata_sleep(void)
525
{
526
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
527
    ata_power_down();
528
    mutex_unlock(&ata_mutex);
529
}
530
 
531
void ata_sleepnow(void)
532
{
533
    ata_sleep();
534
}
535
 
536
void ata_close(void)
537
{
538
    ata_sleep();
539
}
540
 
541
void ata_spin(void)
542
{
543
    ata_power_up();
544
}
545
 
546
void ata_get_info(IF_MD2(int drive,) struct storage_info *info)
547
{
548
    (*info).sector_size = SECTOR_SIZE;
328 theseven 549
#ifdef ATA_HAVE_BBT
550
    (*info).num_sectors = ata_virtual_sectors;
551
#else
301 theseven 552
    (*info).num_sectors = ata_total_sectors;
328 theseven 553
#endif
301 theseven 554
    (*info).vendor = "Apple";
555
    (*info).product = "iPod Classic";
556
    (*info).revision = "1.0";
613 theseven 557
    (*info).driverinfo = &drvinfo;
301 theseven 558
}
559
 
560
long ata_last_disk_activity(void)
561
{
562
    return ata_last_activity_value;
563
}
564
 
613 theseven 565
#ifdef ATA_HAVE_BBT
566
void ata_bbt_disable()
301 theseven 567
{
328 theseven 568
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
613 theseven 569
    if (ata_bbt) free(ata_bbt);
430 theseven 570
    ata_bbt = NULL;
613 theseven 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();
328 theseven 579
    ata_power_up();
430 theseven 580
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
581
    if (buf)
328 theseven 582
    {
430 theseven 583
        ata_bbt_read_sectors(0, 1, buf);
584
        if (!memcmp(buf, "emBIbbth", 8))
328 theseven 585
        {
430 theseven 586
            ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
587
            uint32_t count = buf[0x1ff];
588
            ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
589
            uint32_t i;
590
            uint32_t cnt;
591
            for (i = 0; i < count; i += cnt)
592
            {
593
                uint32_t phys = buf[0x200 + i];
594
                for (cnt = 1; cnt < count; cnt++)
595
                    if (buf[0x200 + i + cnt] != phys + cnt)
596
                        break;
597
                ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
598
            }
488 theseven 599
            reownalloc(ata_bbt, NULL);
328 theseven 600
        }
430 theseven 601
        else ata_virtual_sectors = ata_total_sectors;
602
        free(buf);
328 theseven 603
    }
437 theseven 604
    else ata_virtual_sectors = ata_total_sectors;
328 theseven 605
    mutex_unlock(&ata_mutex);
613 theseven 606
}
328 theseven 607
#endif
613 theseven 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();
621
#endif
429 theseven 622
    thread_create(&ata_thread_handle, "ATA idle monitor", ata_thread, ata_stack,
543 theseven 623
                  sizeof(ata_stack), OS_THREAD, 1, true);
301 theseven 624
    return 0;
625
}
626
 
627
#ifdef CONFIG_STORAGE_MULTI
628
int ata_num_drives(int first_drive)
629
{
630
    /* We don't care which logical drive number(s) we have been assigned */
631
    (void)first_drive;
632
 
633
    return 1;
634
}
635
#endif
636
 
637
void INT_ATA()
638
{
639
    uint32_t ata_irq = ATA_IRQ;
640
    ATA_IRQ = ata_irq;
641
    if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
642
    ATA_IRQ_MASK = 0;
643
}