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
 
29
/** static, private data **/ 
30
uint16_t ata_identify_data[0x100];
31
bool ata_lba48;
32
bool ata_dma;
33
uint64_t ata_total_sectors;
34
static struct mutex ata_mutex;
35
static struct wakeup ata_wakeup;
36
static uint32_t ata_dma_flags;
37
static long ata_last_activity_value = -1;
38
static long ata_sleep_timeout = 20000000;
39
static uint32_t ata_stack[0x80];
40
static bool ata_powered;
41
 
328 theseven 42
#ifdef ATA_HAVE_BBT
43
#include "panic.h"
44
uint16_t ata_bbt[ATA_BBT_PAGES][0x20];
339 theseven 45
uint64_t ata_virtual_sectors;
337 theseven 46
uint32_t ata_last_offset;
47
uint64_t ata_last_phys;
301 theseven 48
 
328 theseven 49
void ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
50
{
51
    int rc = ata_rw_sectors_internal(sector, count, buffer, false);
52
    if (IS_ERR(rc))
53
        panicf(PANIC_KILLTHREAD, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
54
               rc, sector, count);
55
}
56
#endif
57
 
58
 
301 theseven 59
static uint16_t ata_read_cbr(uint32_t volatile* reg)
60
{
317 theseven 61
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 62
    volatile uint32_t dummy = *reg;
317 theseven 63
    while (!(ATA_PIO_READY & 1)) yield();
301 theseven 64
    return ATA_PIO_RDATA;
65
}
66
 
67
static void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
68
{
317 theseven 69
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 70
    *reg = data;
71
}
72
 
73
static int ata_wait_for_not_bsy(long timeout)
74
{
75
    long startusec = USEC_TIMER;
76
    while (true)
77
    {
78
        uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
79
        if (!(csd & BIT(7))) return 0;
80
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0);
81
    }
82
}
83
 
84
static int ata_wait_for_rdy(long timeout)
85
{
86
    long startusec = USEC_TIMER;
87
    PASS_RC(ata_wait_for_not_bsy(timeout), 1, 0);
88
    while (true)
89
    {
90
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
91
        if (dad & BIT(6)) return 0;
92
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1);
93
    }
94
}
95
 
96
static int ata_wait_for_start_of_transfer(long timeout)
97
{
98
    long startusec = USEC_TIMER;
99
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
100
    while (true)
101
    {
102
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
103
        if (dad & BIT(0)) RET_ERR(1);
104
        if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0;
105
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2);
106
    }
107
}
108
 
109
static int ata_wait_for_end_of_transfer(long timeout)
110
{
111
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
112
    uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
113
    if (dad & BIT(0)) RET_ERR(1);
114
    if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0;
115
    RET_ERR(2);
116
}    
117
 
118
int ata_identify(uint16_t* buf)
119
{
120
    int i;
121
    PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
122
    ata_write_cbr(&ATA_PIO_DVR, 0);
123
    ata_write_cbr(&ATA_PIO_CSD, 0xec);
124
    PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
125
    for (i = 0; i < 0x100; i++)
126
    {
127
        uint16_t word = ata_read_cbr(&ATA_PIO_DTR);
128
        buf[i] = (word >> 8) | (word << 8);
129
    }
130
}
131
 
132
void ata_set_active(void)
133
{
134
    ata_last_activity_value = USEC_TIMER;
135
}
136
 
317 theseven 137
int ata_set_feature(uint32_t feature, uint32_t param)
138
{
139
    PASS_RC(ata_wait_for_rdy(500000), 1, 0);
140
    ata_write_cbr(&ATA_PIO_DVR, 0);
141
    ata_write_cbr(&ATA_PIO_FED, 3);
142
    ata_write_cbr(&ATA_PIO_SCR, param);
143
    ata_write_cbr(&ATA_PIO_CSD, feature);
144
    PASS_RC(ata_wait_for_rdy(500000), 1, 1);
145
    return 0;
146
}
147
 
301 theseven 148
int ata_power_up()
149
{
150
    ata_set_active();
357 theseven 151
    if (ata_powered) return 0;
301 theseven 152
    i2c_sendbyte(0, 0xe6, 0x1b, 1);
153
    clockgate_enable(5, true);
154
    ATA_CFG = BIT(0);
155
    sleep(1000);
156
    ATA_CFG = 0;
157
    sleep(6000);
158
    ATA_SWRST = BIT(0);
159
    sleep(500);
160
    ATA_SWRST = 0;
161
    sleep(90000);
162
    ATA_CONTROL = BIT(0);
163
    sleep(200000);
164
    ATA_PIO_TIME = 0x191f7;
165
    ATA_PIO_LHR = 0;
166
    while (!(ATA_PIO_READY & BIT(1))) sleep(100);
167
    PASS_RC(ata_identify(ata_identify_data), 2, 0);
168
    uint32_t piotime = 0x11f3;
169
    uint32_t mdmatime = 0x1c175;
170
    uint32_t udmatime = 0x5071152;
171
    uint32_t param = 0;
172
    ata_dma_flags = 0;
173
    ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
174
    if (ata_lba48)
175
        ata_total_sectors = ata_identify_data[100]
176
                          | (((uint64_t)ata_identify_data[101]) << 16)
177
                          | (((uint64_t)ata_identify_data[102]) << 32)
178
                          | (((uint64_t)ata_identify_data[103]) << 48);
179
    else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
328 theseven 180
    ata_total_sectors >>= 3;
301 theseven 181
    if (ata_identify_data[53] & BIT(1))
182
    {
183
        if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
184
        else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
185
    }
186
    if (ata_identify_data[63] & BIT(2))
187
    {
188
        mdmatime = 0x5072;
189
        param = 0x22;
190
    }
191
    else if (ata_identify_data[63] & BIT(1))
192
    {
193
        mdmatime = 0x7083;
194
        param = 0x21;
195
    }
196
    if (ata_identify_data[63] & BITRANGE(0, 2))
197
    {
198
        ata_dma_flags = BIT(3) | BIT(10);
199
        param |= 0x20;
200
    }
201
    if (ata_identify_data[53] & BIT(2))
202
    {
203
        if (ata_identify_data[88] & BIT(4))
204
        {
205
            udmatime = 0x2010a52;
206
            param = 0x44;
207
        }
208
        else if (ata_identify_data[88] & BIT(3))
209
        {
210
            udmatime = 0x2020a52;
211
            param = 0x43;
212
        }
213
        else if (ata_identify_data[88] & BIT(2))
214
        {
215
            udmatime = 0x3030a52;
216
            param = 0x42;
217
        }
218
        else if (ata_identify_data[88] & BIT(1))
219
        {
220
            udmatime = 0x3050a52;
221
            param = 0x41;
222
        }
223
        if (ata_identify_data[88] & BITRANGE(0, 4))
224
        {
225
            ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
226
            param |= 0x40;
227
        }
228
    }
229
    ata_dma = param ? true : false;
317 theseven 230
    PASS_RC(ata_set_feature(0xef, param), 2, 1);
337 theseven 231
    if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
232
    if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
301 theseven 233
    ATA_PIO_TIME = piotime;
234
    ATA_MDMA_TIME = mdmatime;
235
    ATA_UDMA_TIME = udmatime;
236
    ata_powered = true;
237
    ata_set_active();
238
    return 0;
239
}
240
 
241
void ata_power_down()
242
{
357 theseven 243
    if (!ata_powered) return;
301 theseven 244
    ata_powered = false;
245
    ata_wait_for_rdy(1000000);
246
    ata_write_cbr(&ATA_PIO_DVR, 0);
247
    ata_write_cbr(&ATA_PIO_CSD, 0xe0);
248
    ata_wait_for_rdy(1000000);
249
    sleep(30000);
250
    ATA_CONTROL = 0;
317 theseven 251
    while (!(ATA_CONTROL & BIT(1))) yield();
301 theseven 252
    clockgate_enable(5, false);
253
    i2c_sendbyte(0, 0xe6, 0x1b, 0);
254
}
255
 
337 theseven 256
int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
257
{
258
    PASS_RC(ata_wait_for_rdy(100000), 2, 0);
259
    ata_write_cbr(&ATA_PIO_DVR, 0);
260
    if (ata_lba48)
261
    {
262
        ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
263
        ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
264
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
265
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
266
        ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
267
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
268
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
269
        ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
270
        ata_write_cbr(&ATA_PIO_DVR, BIT(6));
271
        if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
272
        else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
273
    }
274
    else
275
    {
276
        ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
277
        ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
278
        ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
279
        ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
280
        ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
281
        if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
282
        else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
283
    }
284
    if (ata_dma)
285
    {
286
        PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
287
        if (write)
288
        {
289
            ATA_SBUF_START = buffer;
290
            ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
291
            ATA_CFG |= BIT(4);
292
        }
293
        else
294
        {
295
            ATA_TBUF_START = buffer;
296
            ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
297
            ATA_CFG &= ~BIT(4);
298
        }
299
        ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
300
        ATA_CFG |= ata_dma_flags;
301
        ATA_CFG &= ~(BIT(7) | BIT(8));
302
        wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
303
        ATA_IRQ = BITRANGE(0, 4);
304
        ATA_IRQ_MASK = BIT(0);
305
        ATA_COMMAND = BIT(0);
306
        if (wakeup_wait(&ata_wakeup, 500000) == THREAD_TIMEOUT)
307
        {
308
            ATA_COMMAND = BIT(1);
309
            ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
310
            RET_ERR(2);
311
        }
312
        ATA_COMMAND = BIT(1);
313
        ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
314
    }
315
    else
316
    {
317
        cnt *= SECTOR_SIZE / 512;
318
        while (cnt--)
319
        {
320
            int i;
321
            PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
322
            if (write)
323
                for (i = 0; i < 256; i++)
324
                    ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
325
            else
326
                for (i = 0; i < 256; i++)
327
                    ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
328
            buffer += 512;
329
        }
330
    }
331
    PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
332
    return 0;
333
}
334
 
301 theseven 335
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
336
{
328 theseven 337
#ifdef ATA_HAVE_BBT
338
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
339
    while (count)
340
    {
337 theseven 341
        uint32_t offset;
328 theseven 342
        uint32_t l0idx = sector >> 15;
343
        uint32_t l0offs = sector & 0x7fff;
344
        uint32_t cnt = MIN(count, 0x8000 - l0offs);
345
        uint32_t l0data = ata_bbt[0][l0idx << 1];
346
        uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
337 theseven 347
        if (l0data < 0x8000) offset = l0data + base;
328 theseven 348
        else
349
        {
350
            uint32_t l1idx = (sector >> 10) & 0x1f;
351
            uint32_t l1offs = sector & 0x3ff;
352
            cnt = MIN(count, 0x400 - l1offs);
353
            uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
337 theseven 354
            if (l1data < 0x8000) offset = l1data + base;
328 theseven 355
            else
356
            {
357
                uint32_t l2idx = (sector >> 5) & 0x1f;
358
                uint32_t l2offs = sector & 0x1f;
359
                cnt = MIN(count, 0x20 - l2offs);
360
                uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
337 theseven 361
                if (l2data < 0x8000) offset = l2data + base;
328 theseven 362
                else
363
                {
364
                    uint32_t l3idx = sector & 0x1f;
337 theseven 365
                    uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
328 theseven 366
                    for (cnt = 1; cnt < count && l3idx + cnt < 0x20; cnt++)
337 theseven 367
                        if (ata_bbt[l2data & 0x7fff][l3idx + cnt] != l3data)
328 theseven 368
                            break;
337 theseven 369
                    offset = l3data + base;
328 theseven 370
                }
371
            }
372
        }
337 theseven 373
        uint64_t phys = sector + offset;
374
        if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
375
        ata_last_offset = offset;
376
        ata_last_phys = phys + cnt;
328 theseven 377
        PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
378
        buffer += cnt * SECTOR_SIZE;
379
        sector += cnt;
380
        count -= cnt;
381
    }
382
    return 0;
383
}
384
 
385
int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write)
386
{
387
#endif
301 theseven 388
    if (sector + count > ata_total_sectors) RET_ERR(0);
389
    if (!ata_powered) ata_power_up();
390
    ata_set_active();
391
    if (ata_dma && write) clean_dcache();
392
    else if (ata_dma) invalidate_dcache();
393
    ATA_COMMAND = BIT(1);
394
    while (count)
395
    {
317 theseven 396
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
337 theseven 397
        int rc = -1;
398
        int tries = 3;
399
        while (tries-- && rc)
301 theseven 400
        {
337 theseven 401
            rc = ata_rw_chunk(sector, cnt, buffer, write);
402
            if (rc) ata_soft_reset();
301 theseven 403
        }
337 theseven 404
        if (rc)
301 theseven 405
        {
337 theseven 406
            void* buf = buffer;
405 theseven 407
            uint64_t sect;
337 theseven 408
            for (sect = sector; sect < sector + cnt; sect++)
409
            {
410
                rc = -1;
411
                tries = 3;
412
                while (tries-- && rc)
413
                {
414
                    rc = ata_rw_chunk(sect, 1, buf, write);
415
                    if (rc) ata_soft_reset();
416
                }
417
                if (rc) break;
418
                buf += SECTOR_SIZE;
419
            }
301 theseven 420
        }
337 theseven 421
        PASS_RC(rc, 1, 1);
422
        buffer += SECTOR_SIZE * cnt;
301 theseven 423
        sector += cnt;
424
        count -= cnt;
425
    }
426
    ata_set_active();
427
    return 0;
428
}
429
 
430
static void ata_thread(void)
431
{
432
    while (true)
433
    {
434
        mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
435
        if (TIME_AFTER(USEC_TIMER, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
436
            ata_power_down();
437
        mutex_unlock(&ata_mutex);
438
        sleep(1000000);
439
    }
440
}
441
 
442
/* API Functions */
443
int ata_soft_reset()
444
{
445
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
446
    if (!ata_powered) ata_power_up();
447
    ata_set_active();
448
    ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
449
    sleep(10);
450
    ata_write_cbr(&ATA_PIO_DAD, 0);
337 theseven 451
    PASS_RC_MTX(ata_wait_for_rdy(60000000), 0, 0, &ata_mutex);
301 theseven 452
    ata_set_active();
453
    mutex_unlock(&ata_mutex);
454
}
455
 
456
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
457
                     void* inbuf)
458
{
459
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 460
    int rc = ata_rw_sectors(start, incount, inbuf, false);
301 theseven 461
    mutex_unlock(&ata_mutex);
462
    return rc;
463
}
464
 
465
int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
466
                      const void* outbuf)
467
{
468
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 469
    int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
301 theseven 470
    mutex_unlock(&ata_mutex);
471
    return rc;
472
}
473
 
337 theseven 474
void ata_spindown(int seconds)
475
{
476
    ata_sleep_timeout = seconds * 1000000;
477
}
301 theseven 478
 
479
void ata_sleep(void)
480
{
481
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
482
    ata_power_down();
483
    mutex_unlock(&ata_mutex);
484
}
485
 
486
void ata_sleepnow(void)
487
{
488
    ata_sleep();
489
}
490
 
491
void ata_close(void)
492
{
493
    ata_sleep();
494
}
495
 
496
void ata_spin(void)
497
{
498
    ata_power_up();
499
}
500
 
501
void ata_get_info(IF_MD2(int drive,) struct storage_info *info)
502
{
503
    (*info).sector_size = SECTOR_SIZE;
328 theseven 504
#ifdef ATA_HAVE_BBT
505
    (*info).num_sectors = ata_virtual_sectors;
506
#else
301 theseven 507
    (*info).num_sectors = ata_total_sectors;
328 theseven 508
#endif
301 theseven 509
    (*info).vendor = "Apple";
510
    (*info).product = "iPod Classic";
511
    (*info).revision = "1.0";
512
}
513
 
514
long ata_last_disk_activity(void)
515
{
516
    return ata_last_activity_value;
517
}
518
 
519
int ata_init(void)
520
{
521
    mutex_init(&ata_mutex);
522
    wakeup_init(&ata_wakeup);
523
    PCON(7) = 0x44444444;
524
    PCON(8) = 0x44444444;
525
    PCON(9) = 0x44444444;
526
    PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
527
    ata_powered = false;
528
    ata_total_sectors = 0;
328 theseven 529
#ifdef ATA_HAVE_BBT
530
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
531
    memset(ata_bbt, 0, sizeof(ata_bbt));
532
    ata_power_up();
533
    uint32_t* buf = (uint32_t*)(ata_bbt[ARRAYLEN(ata_bbt) - 64]);
534
    ata_bbt_read_sectors(0, 1, buf);
535
    if (!memcmp(buf, "emBIbbth", 8))
536
    {
339 theseven 537
        ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
328 theseven 538
        uint32_t count = buf[0x1ff];
539
        if (count > (ATA_BBT_PAGES >> 6))
337 theseven 540
            panicf(PANIC_KILLTHREAD, "ATA: BBT too big! (%d pages, limit: %d)\n", count << 6, ATA_BBT_PAGES);
328 theseven 541
        uint32_t i;
542
        uint32_t cnt;
543
        for (i = 0; i < count; i += cnt)
544
        {
545
            uint32_t phys = buf[0x200 + i];
546
            for (cnt = 1; cnt < count; cnt++)
547
                if (buf[0x200 + i + cnt] != phys + cnt)
548
                    break;
549
            ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6]);
550
        }
551
    }
552
    else ata_virtual_sectors = ata_total_sectors;
553
    mutex_unlock(&ata_mutex);
554
#endif
301 theseven 555
    thread_create("ATA idle monitor", ata_thread, ata_stack,
556
                  sizeof(ata_stack), USER_THREAD, 1, true);
557
    return 0;
558
}
559
 
560
#ifdef CONFIG_STORAGE_MULTI
561
int ata_num_drives(int first_drive)
562
{
563
    /* We don't care which logical drive number(s) we have been assigned */
564
    (void)first_drive;
565
 
566
    return 1;
567
}
568
#endif
569
 
570
void INT_ATA()
571
{
572
    uint32_t ata_irq = ATA_IRQ;
573
    ATA_IRQ = ata_irq;
574
    if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
575
    ATA_IRQ_MASK = 0;
576
}