Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
54 theseven 1
/***************************************************************************
2
 *             __________               __   ___.
3
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7
 *                     \/            \/     \/    \/            \/
8
 * $Id$
9
 *
10
 * Copyright (C) 2008 by Frank Gevaerts
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 "storage.h"
23
 
24
#ifdef CONFIG_STORAGE_MULTI
25
 
26
#define DRIVER_MASK     0xff000000
27
#define DRIVER_OFFSET   24
28
#define DRIVE_MASK      0x00ff0000
29
#define DRIVE_OFFSET    16
30
#define PARTITION_MASK  0x0000ff00
31
 
32
static unsigned int storage_drivers[NUM_DRIVES];
33
static unsigned int num_drives;
34
#endif
35
 
36
 
37
#ifdef HAVE_IO_PRIORITY
38
 
39
/* Same for flash? */
40
#define STORAGE_MINIMUM_IDLE_TIME (HZ/10)
41
#define STORAGE_DELAY_UNIT  (HZ/20)
42
 
43
static unsigned int storage_last_thread[NUM_DRIVES];
44
static unsigned int storage_last_activity[NUM_DRIVES];
45
 
46
static bool storage_should_wait(int drive, int prio)
47
{
48
    int other_prio = thread_get_io_priority(storage_last_thread[drive]);
49
    if(TIME_BEFORE(current_tick,storage_last_activity[drive]+STORAGE_MINIMUM_IDLE_TIME))
50
    {
51
        if(prio<=other_prio)
52
        {
53
            /* There is another active thread, but we have lower priority */
54
            return false;
55
        }
56
        else
57
        {
58
            /* There is another active thread, but it has lower priority */
59
            return true;
60
        }
61
    }
62
    else
63
    {
64
        /* There's nothing going on anyway */
65
        return false;
66
    }
67
}
68
 
69
static void storage_wait_turn(IF_MD_NONVOID(int drive))
70
{
71
#ifndef HAVE_MULTIDRIVE
72
    int drive=0;
73
#endif
74
    int my_prio = thread_get_io_priority(THREAD_ID_CURRENT);
75
    int loops=my_prio;
76
    while(storage_should_wait(drive, my_prio) && (loops--)>=0)
77
    {
78
        sleep(STORAGE_DELAY_UNIT);
79
    }
80
 
81
    storage_last_thread[drive] = thread_get_current();
82
    storage_last_activity[drive] = current_tick;
83
}
84
#endif
85
 
86
int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
87
                         void* buf)
88
{
89
#ifdef HAVE_IO_PRIORITY
90
    storage_wait_turn(IF_MD(drive));
91
#endif
92
 
93
#ifdef CONFIG_STORAGE_MULTI
94
    int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
95
    int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
96
 
97
    switch (driver)
98
    {
99
#if (CONFIG_STORAGE & STORAGE_ATA)
100
    case STORAGE_ATA:
101
        return ata_read_sectors(IF_MD2(ldrive,) start,count,buf);
102
#endif
103
 
104
#if (CONFIG_STORAGE & STORAGE_MMC)
105
    case STORAGE_MMC:
106
        return mmc_read_sectors(IF_MD2(ldrive,) start,count,buf);
107
#endif
108
 
109
#if (CONFIG_STORAGE & STORAGE_SD)
110
    case STORAGE_SD:
111
        return sd_read_sectors(IF_MD2(ldrive,) start,count,buf);
112
#endif
113
 
114
#if (CONFIG_STORAGE & STORAGE_NAND)
115
    case STORAGE_NAND:
116
        return nand_read_sectors(IF_MD2(ldrive,) start,count,buf);
117
#endif
118
 
119
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
120
    case STORAGE_RAMDISK:
121
        return ramdisk_read_sectors(IF_MD2(ldrive,) start,count,buf);
122
#endif
123
    }
124
 
125
    return -1;
126
#else /* CONFIG_STORAGE_MULTI */
127
    return STORAGE_FUNCTION(read_sectors)(IF_MD2(drive,)start,count,buf);
128
#endif /* CONFIG_STORAGE_MULTI */
129
 
130
}
131
 
132
int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
133
                          const void* buf)
134
{
135
#ifdef HAVE_IO_PRIORITY
136
    storage_wait_turn(IF_MD(drive));
137
#endif
138
 
139
#ifdef CONFIG_STORAGE_MULTI
140
    int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
141
    int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
142
 
143
    switch (driver)
144
    {
145
#if (CONFIG_STORAGE & STORAGE_ATA)
146
    case STORAGE_ATA:
147
        return ata_write_sectors(IF_MD2(ldrive,)start,count,buf);
148
#endif
149
 
150
#if (CONFIG_STORAGE & STORAGE_MMC)
151
    case STORAGE_MMC:
152
        return mmc_write_sectors(IF_MD2(ldrive,)start,count,buf);
153
#endif
154
 
155
#if (CONFIG_STORAGE & STORAGE_SD)
156
    case STORAGE_SD:
157
        return sd_write_sectors(IF_MD2(ldrive,)start,count,buf);
158
#endif
159
 
160
#if (CONFIG_STORAGE & STORAGE_NAND)
161
    case STORAGE_NAND:
162
        return nand_write_sectors(IF_MD2(ldrive,)start,count,buf);
163
#endif
164
 
165
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
166
    case STORAGE_RAMDISK:
167
        return ramdisk_write_sectors(IF_MD2(ldrive,)start,count,buf);
168
#endif
169
    }
170
 
171
    return -1;
172
#else /* CONFIG_STORAGE_MULTI */
173
    return STORAGE_FUNCTION(write_sectors)(IF_MD2(drive,)start,count,buf);
174
#endif /* CONFIG_STORAGE_MULTI */
175
}
176
 
177
#ifdef CONFIG_STORAGE_MULTI
178
 
179
#define DRIVER_MASK     0xff000000
180
#define DRIVER_OFFSET   24
181
#define DRIVE_MASK      0x00ff0000
182
#define DRIVE_OFFSET    16
183
#define PARTITION_MASK  0x0000ff00
184
 
185
static unsigned int storage_drivers[NUM_DRIVES];
186
static unsigned int num_drives;
187
 
188
int storage_num_drives(void)
189
{
190
    return num_drives;
191
}
192
 
193
int storage_init(void)
194
{
195
    int rc=0;
196
    int i;
197
    num_drives=0;
198
 
199
#if (CONFIG_STORAGE & STORAGE_ATA)
200
    if ((rc=ata_init())) return rc;
201
 
202
    int ata_drives = ata_num_drives(num_drives);
203
    for (i=0; i<ata_drives; i++)
204
    {
205
        storage_drivers[num_drives++] = 
206
            (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
207
    }
208
#endif
209
 
210
#if (CONFIG_STORAGE & STORAGE_MMC)
211
    if ((rc=mmc_init())) return rc;
212
 
213
    int mmc_drives = mmc_num_drives(num_drives);
214
    for (i=0; i<mmc_drives ;i++)
215
    {
216
        storage_drivers[num_drives++] =
217
            (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
218
    }
219
#endif
220
 
221
#if (CONFIG_STORAGE & STORAGE_SD)
222
    if ((rc=sd_init())) return rc;
223
 
224
    int sd_drives = sd_num_drives(num_drives);
225
    for (i=0; i<sd_drives; i++)
226
    {
227
        storage_drivers[num_drives++] =
228
            (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
229
    }
230
#endif
231
 
232
#if (CONFIG_STORAGE & STORAGE_NAND)
233
    if ((rc=nand_init())) return rc;
234
 
235
    int nand_drives = nand_num_drives(num_drives);
236
    for (i=0; i<nand_drives; i++)
237
    {
238
        storage_drivers[num_drives++] =
239
            (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
240
    }
241
#endif
242
 
243
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
244
    if ((rc=ramdisk_init())) return rc;
245
 
246
    int ramdisk_drives = ramdisk_num_drives(num_drives);
247
    for (i=0; i<ramdisk_drives; i++)
248
    {
249
        storage_drivers[num_drives++] =
250
            (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
251
    }
252
#endif
253
 
254
    return 0;
255
}
256
 
257
 
258
void storage_enable(bool on)
259
{
260
#if (CONFIG_STORAGE & STORAGE_ATA)
261
    ata_enable(on);
262
#endif
263
 
264
#if (CONFIG_STORAGE & STORAGE_MMC)
265
    mmc_enable(on);
266
#endif
267
 
268
#if (CONFIG_STORAGE & STORAGE_SD)
269
    sd_enable(on);
270
#endif
271
 
272
#if (CONFIG_STORAGE & STORAGE_NAND)
273
    nand_enable(on);
274
#endif
275
 
276
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
277
    ramdisk_enable(on);
278
#endif
279
}
280
 
281
void storage_sleep(void)
282
{
283
#if (CONFIG_STORAGE & STORAGE_ATA)
284
    ata_sleep();
285
#endif
286
 
287
#if (CONFIG_STORAGE & STORAGE_MMC)
288
    mmc_sleep();
289
#endif
290
 
291
#if (CONFIG_STORAGE & STORAGE_SD)
292
    sd_sleep();
293
#endif
294
 
295
#if (CONFIG_STORAGE & STORAGE_NAND)
296
    nand_sleep();
297
#endif
298
 
299
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
300
    ramdisk_sleep();
301
#endif
302
}
303
 
304
void storage_sleepnow(void)
305
{
306
#if (CONFIG_STORAGE & STORAGE_ATA)
307
    ata_sleepnow();
308
#endif
309
 
310
#if (CONFIG_STORAGE & STORAGE_MMC)
311
    mmc_sleepnow();
312
#endif
313
 
314
#if (CONFIG_STORAGE & STORAGE_SD)
315
    //sd_sleepnow();
316
#endif
317
 
318
#if (CONFIG_STORAGE & STORAGE_NAND)
319
    nand_sleepnow();
320
#endif
321
 
322
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
323
    ramdisk_sleepnow();
324
#endif
325
}
326
 
327
bool storage_disk_is_active(void)
328
{
329
#if (CONFIG_STORAGE & STORAGE_ATA)
330
    if (ata_disk_is_active()) return true;
331
#endif
332
 
333
#if (CONFIG_STORAGE & STORAGE_MMC)
334
    if (mmc_disk_is_active()) return true;
335
#endif
336
 
337
#if (CONFIG_STORAGE & STORAGE_SD)
338
    //if (sd_disk_is_active()) return true;
339
#endif
340
 
341
#if (CONFIG_STORAGE & STORAGE_NAND)
342
    //if (nand_disk_is_active()) return true;
343
#endif
344
 
345
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
346
    if (ramdisk_disk_is_active()) return true;
347
#endif
348
 
349
    return false;
350
}
351
 
352
int storage_soft_reset(void)
353
{
354
    int rc=0;
355
 
356
#if (CONFIG_STORAGE & STORAGE_ATA)
357
    if ((rc=ata_soft_reset())) return rc;
358
#endif
359
 
360
#if (CONFIG_STORAGE & STORAGE_MMC)
361
    if ((rc=mmc_soft_reset())) return rc;
362
#endif
363
 
364
#if (CONFIG_STORAGE & STORAGE_SD)
365
    //if ((rc=sd_soft_reset())) return rc;
366
#endif
367
 
368
#if (CONFIG_STORAGE & STORAGE_NAND)
369
    //if ((rc=nand_soft_reset())) return rc;
370
#endif
371
 
372
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
373
    if ((rc=ramdisk_soft_reset())) return rc;
374
#endif
375
 
376
    return rc;
377
}
378
 
379
#ifdef HAVE_STORAGE_FLUSH
380
int storage_flush(void)
381
{
382
    int rc=0;
383
 
384
#if (CONFIG_STORAGE & STORAGE_ATA)
385
    //if ((rc=ata_flush())) return rc;
386
#endif
387
 
388
#if (CONFIG_STORAGE & STORAGE_MMC)
389
    //if ((rc=mmc_flush())) return rc;
390
#endif
391
 
392
#if (CONFIG_STORAGE & STORAGE_SD)
393
    //if ((rc=sd_flush())) return rc;
394
#endif
395
 
396
#if (CONFIG_STORAGE & STORAGE_NAND)
397
    if ((rc=nand_flush())) return rc;
398
#endif
399
 
400
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
401
    //if ((rc=ramdisk_flush())) return rc;
402
#endif
403
 
404
    return rc;
405
}
406
#endif
407
 
408
void storage_spin(void)
409
{
410
#if (CONFIG_STORAGE & STORAGE_ATA)
411
    ata_spin();
412
#endif
413
 
414
#if (CONFIG_STORAGE & STORAGE_MMC)
415
    mmc_spin();
416
#endif
417
 
418
#if (CONFIG_STORAGE & STORAGE_SD)
419
    sd_spin();
420
#endif
421
 
422
#if (CONFIG_STORAGE & STORAGE_NAND)
423
    nand_spin();
424
#endif
425
 
426
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
427
    ramdisk_spin();
428
#endif
429
}
430
 
431
void storage_spindown(int seconds)
432
{
433
#if (CONFIG_STORAGE & STORAGE_ATA)
434
    ata_spindown(seconds);
435
#endif
436
 
437
#if (CONFIG_STORAGE & STORAGE_MMC)
438
    mmc_spindown(seconds);
439
#endif
440
 
441
#if (CONFIG_STORAGE & STORAGE_SD)
442
    sd_spindown(seconds);
443
#endif
444
 
445
#if (CONFIG_STORAGE & STORAGE_NAND)
446
    nand_spindown(seconds);
447
#endif
448
 
449
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
450
    ramdisk_spindown(seconds);
451
#endif
452
}
453
 
454
#if (CONFIG_LED == LED_REAL)
455
void storage_set_led_enabled(bool enabled)
456
{
457
#if (CONFIG_STORAGE & STORAGE_ATA)
458
    ata_set_led_enabled(enabled);
459
#endif
460
 
461
#if (CONFIG_STORAGE & STORAGE_MMC)
462
    mmc_set_led_enabled(enabled);
463
#endif
464
 
465
#if (CONFIG_STORAGE & STORAGE_SD)
466
    sd_set_led_enabled(enabled);
467
#endif
468
 
469
#if (CONFIG_STORAGE & STORAGE_NAND)
470
    nand_set_led_enabled(enabled);
471
#endif
472
 
473
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
474
    ramdisk_set_led_enabled(enabled);
475
#endif
476
}
477
#endif /* CONFIG_LED == LED_REAL */
478
 
479
long storage_last_disk_activity(void)
480
{
481
    long max=0;
482
    long t;
483
 
484
#if (CONFIG_STORAGE & STORAGE_ATA)
485
    t=ata_last_disk_activity();
486
    if (t>max) max=t;
487
#endif
488
 
489
#if (CONFIG_STORAGE & STORAGE_MMC)
490
    t=mmc_last_disk_activity();
491
    if (t>max) max=t;
492
#endif
493
 
494
#if (CONFIG_STORAGE & STORAGE_SD)
495
    t=sd_last_disk_activity();
496
    if (t>max) max=t;
497
#endif
498
 
499
#if (CONFIG_STORAGE & STORAGE_NAND)
500
    t=nand_last_disk_activity();
501
    if (t>max) max=t;
502
#endif
503
 
504
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
505
    t=ramdisk_last_disk_activity();
506
    if (t>max) max=t;
507
#endif
508
 
509
    return max;
510
}
511
 
512
int storage_spinup_time(void)
513
{
514
    int max=0;
515
    int t;
516
 
517
#if (CONFIG_STORAGE & STORAGE_ATA)
518
    t=ata_spinup_time();
519
    if (t>max) max=t;
520
#endif
521
 
522
#if (CONFIG_STORAGE & STORAGE_MMC)
523
    t=mmc_spinup_time();
524
    if (t>max) max=t;
525
#endif
526
 
527
#if (CONFIG_STORAGE & STORAGE_SD)
528
    //t=sd_spinup_time();
529
    //if (t>max) max=t;
530
#endif
531
 
532
#if (CONFIG_STORAGE & STORAGE_NAND)
533
    t=nand_spinup_time();
534
    if (t>max) max=t;
535
#endif
536
 
537
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
538
    t=ramdisk_spinup_time();
539
    if (t>max) max=t;
540
#endif
541
 
542
    return max;
543
}
544
 
545
#ifdef STORAGE_GET_INFO
546
void storage_get_info(int drive, struct storage_info *info)
547
{
548
    int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
549
    int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
550
 
551
    switch(driver)
552
    {
553
#if (CONFIG_STORAGE & STORAGE_ATA)
554
    case STORAGE_ATA:
555
        return ata_get_info(ldrive,info);
556
#endif
557
 
558
#if (CONFIG_STORAGE & STORAGE_MMC)
559
    case STORAGE_MMC:
560
        return mmc_get_info(ldrive,info);
561
#endif
562
 
563
#if (CONFIG_STORAGE & STORAGE_SD)
564
    case STORAGE_SD:
565
        return sd_get_info(ldrive,info);
566
#endif
567
 
568
#if (CONFIG_STORAGE & STORAGE_NAND)
569
    case STORAGE_NAND:
570
        return nand_get_info(ldrive,info);
571
#endif
572
 
573
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
574
    case STORAGE_RAMDISK:
575
        return ramdisk_get_info(ldrive,info);
576
#endif
577
    }
578
}
579
#endif /* STORAGE_GET_INFO */
580
 
581
#ifdef HAVE_HOTSWAP
582
bool storage_removable(int drive)
583
{
584
    int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
585
    int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
586
 
587
    switch(driver)
588
    {
589
#if (CONFIG_STORAGE & STORAGE_ATA)
590
    case STORAGE_ATA:
591
        return ata_removable(ldrive);
592
#endif
593
 
594
#if (CONFIG_STORAGE & STORAGE_MMC)
595
    case STORAGE_MMC:
596
        return mmc_removable(ldrive);
597
#endif
598
 
599
#if (CONFIG_STORAGE & STORAGE_SD)
600
    case STORAGE_SD:
601
        return sd_removable(ldrive);
602
#endif
603
 
604
#if (CONFIG_STORAGE & STORAGE_NAND)
605
    case STORAGE_NAND:
606
        return false;
607
#endif
608
 
609
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
610
    case STORAGE_RAMDISK:
611
        return false;
612
#endif
613
 
614
    default:
615
        return false;
616
    }
617
}
618
 
619
bool storage_present(int drive)
620
{
621
    int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
622
    int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
623
 
624
    switch(driver)
625
    {
626
#if (CONFIG_STORAGE & STORAGE_ATA)
627
    case STORAGE_ATA:
628
        return ata_present(ldrive);
629
#endif
630
 
631
#if (CONFIG_STORAGE & STORAGE_MMC)
632
    case STORAGE_MMC:
633
        return mmc_present(ldrive);
634
#endif
635
 
636
#if (CONFIG_STORAGE & STORAGE_SD)
637
    case STORAGE_SD:
638
        return sd_present(ldrive);
639
#endif
640
 
641
#if (CONFIG_STORAGE & STORAGE_NAND)
642
    case STORAGE_NAND:
643
        return true;
644
#endif
645
 
646
#if (CONFIG_STORAGE & STORAGE_RAMDISK)
647
    case STORAGE_RAMDISK:
648
        return true;
649
#endif
650
 
651
    default:
652
        return false;
653
    }
654
}
655
#endif
656
 
657
#endif /*CONFIG_STORAGE_MULTI*/