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