fuzev2: prevent button light flickering when accessing µSD
[kugel-rb.git] / firmware / storage.c
blob1dd315948ce5cb537b80afd6f3acd3f617a3195f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Frank Gevaerts
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "storage.h"
22 #include "kernel.h"
24 #ifdef CONFIG_STORAGE_MULTI
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
32 static unsigned int storage_drivers[NUM_DRIVES];
33 static unsigned int num_drives;
34 #endif
37 #ifdef HAVE_IO_PRIORITY
39 /* Same for flash? */
40 #define STORAGE_MINIMUM_IDLE_TIME (HZ/10)
41 #define STORAGE_DELAY_UNIT (HZ/20)
43 unsigned int storage_last_thread[NUM_DRIVES];
44 unsigned int storage_last_activity[NUM_DRIVES];
46 static bool storage_should_wait(int drive, int prio)
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))
51 if(prio<=other_prio)
53 /* There is another active thread, but we have lower priority */
54 return false;
56 else
58 /* There is another active thread, but it has lower priority */
59 return true;
62 else
64 /* There's nothing going on anyway */
65 return false;
69 static void storage_wait_turn(IF_MD_NONVOID(int drive))
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)
78 sleep(STORAGE_DELAY_UNIT);
81 storage_last_thread[drive] = thread_get_current();
82 storage_last_activity[drive] = current_tick;
84 #endif
86 int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
87 void* buf)
89 #ifdef HAVE_IO_PRIORITY
90 storage_wait_turn(IF_MD(drive));
91 #endif
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;
97 switch (driver)
99 #if (CONFIG_STORAGE & STORAGE_ATA)
100 case STORAGE_ATA:
101 return ata_read_sectors(IF_MD2(ldrive,) start,count,buf);
102 #endif
104 #if (CONFIG_STORAGE & STORAGE_MMC)
105 case STORAGE_MMC:
106 return mmc_read_sectors(IF_MD2(ldrive,) start,count,buf);
107 #endif
109 #if (CONFIG_STORAGE & STORAGE_SD)
110 case STORAGE_SD:
111 return sd_read_sectors(IF_MD2(ldrive,) start,count,buf);
112 #endif
114 #if (CONFIG_STORAGE & STORAGE_NAND)
115 case STORAGE_NAND:
116 return nand_read_sectors(IF_MD2(ldrive,) start,count,buf);
117 #endif
119 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
120 case STORAGE_RAMDISK:
121 return ramdisk_read_sectors(IF_MD2(ldrive,) start,count,buf);
122 #endif
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 */
132 int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
133 const void* buf)
135 #ifdef HAVE_IO_PRIORITY
136 storage_wait_turn(IF_MD(drive));
137 #endif
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;
143 switch (driver)
145 #if (CONFIG_STORAGE & STORAGE_ATA)
146 case STORAGE_ATA:
147 return ata_write_sectors(IF_MD2(ldrive,)start,count,buf);
148 #endif
150 #if (CONFIG_STORAGE & STORAGE_MMC)
151 case STORAGE_MMC:
152 return mmc_write_sectors(IF_MD2(ldrive,)start,count,buf);
153 #endif
155 #if (CONFIG_STORAGE & STORAGE_SD)
156 case STORAGE_SD:
157 return sd_write_sectors(IF_MD2(ldrive,)start,count,buf);
158 #endif
160 #if (CONFIG_STORAGE & STORAGE_NAND)
161 case STORAGE_NAND:
162 return nand_write_sectors(IF_MD2(ldrive,)start,count,buf);
163 #endif
165 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
166 case STORAGE_RAMDISK:
167 return ramdisk_write_sectors(IF_MD2(ldrive,)start,count,buf);
168 #endif
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 */
177 #ifdef CONFIG_STORAGE_MULTI
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
185 static unsigned int storage_drivers[NUM_DRIVES];
186 static unsigned int num_drives;
188 int storage_num_drives(void)
190 return num_drives;
193 int storage_init(void)
195 int rc=0;
196 int i;
197 num_drives=0;
199 #if (CONFIG_STORAGE & STORAGE_ATA)
200 if ((rc=ata_init())) return rc;
202 int ata_drives = ata_num_drives(num_drives);
203 for (i=0; i<ata_drives; i++)
205 storage_drivers[num_drives++] =
206 (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
208 #endif
210 #if (CONFIG_STORAGE & STORAGE_MMC)
211 if ((rc=mmc_init())) return rc;
213 int mmc_drives = mmc_num_drives(num_drives);
214 for (i=0; i<mmc_drives ;i++)
216 storage_drivers[num_drives++] =
217 (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
219 #endif
221 #if (CONFIG_STORAGE & STORAGE_SD)
222 if ((rc=sd_init())) return rc;
224 int sd_drives = sd_num_drives(num_drives);
225 for (i=0; i<sd_drives; i++)
227 storage_drivers[num_drives++] =
228 (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
230 #endif
232 #if (CONFIG_STORAGE & STORAGE_NAND)
233 if ((rc=nand_init())) return rc;
235 int nand_drives = nand_num_drives(num_drives);
236 for (i=0; i<nand_drives; i++)
238 storage_drivers[num_drives++] =
239 (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
241 #endif
243 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
244 if ((rc=ramdisk_init())) return rc;
246 int ramdisk_drives = ramdisk_num_drives(num_drives);
247 for (i=0; i<ramdisk_drives; i++)
249 storage_drivers[num_drives++] =
250 (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
252 #endif
254 return 0;
258 void storage_enable(bool on)
260 #if (CONFIG_STORAGE & STORAGE_ATA)
261 ata_enable(on);
262 #endif
264 #if (CONFIG_STORAGE & STORAGE_MMC)
265 mmc_enable(on);
266 #endif
268 #if (CONFIG_STORAGE & STORAGE_SD)
269 sd_enable(on);
270 #endif
272 #if (CONFIG_STORAGE & STORAGE_NAND)
273 nand_enable(on);
274 #endif
276 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
277 ramdisk_enable(on);
278 #endif
281 void storage_sleep(void)
283 #if (CONFIG_STORAGE & STORAGE_ATA)
284 ata_sleep();
285 #endif
287 #if (CONFIG_STORAGE & STORAGE_MMC)
288 mmc_sleep();
289 #endif
291 #if (CONFIG_STORAGE & STORAGE_SD)
292 sd_sleep();
293 #endif
295 #if (CONFIG_STORAGE & STORAGE_NAND)
296 nand_sleep();
297 #endif
299 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
300 ramdisk_sleep();
301 #endif
304 void storage_sleepnow(void)
306 #if (CONFIG_STORAGE & STORAGE_ATA)
307 ata_sleepnow();
308 #endif
310 #if (CONFIG_STORAGE & STORAGE_MMC)
311 mmc_sleepnow();
312 #endif
314 #if (CONFIG_STORAGE & STORAGE_SD)
315 //sd_sleepnow();
316 #endif
318 #if (CONFIG_STORAGE & STORAGE_NAND)
319 nand_sleepnow();
320 #endif
322 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
323 ramdisk_sleepnow();
324 #endif
327 bool storage_disk_is_active(void)
329 #if (CONFIG_STORAGE & STORAGE_ATA)
330 if (ata_disk_is_active()) return true;
331 #endif
333 #if (CONFIG_STORAGE & STORAGE_MMC)
334 if (mmc_disk_is_active()) return true;
335 #endif
337 #if (CONFIG_STORAGE & STORAGE_SD)
338 //if (sd_disk_is_active()) return true;
339 #endif
341 #if (CONFIG_STORAGE & STORAGE_NAND)
342 //if (nand_disk_is_active()) return true;
343 #endif
345 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
346 if (ramdisk_disk_is_active()) return true;
347 #endif
349 return false;
352 int storage_soft_reset(void)
354 int rc=0;
356 #if (CONFIG_STORAGE & STORAGE_ATA)
357 if ((rc=ata_soft_reset())) return rc;
358 #endif
360 #if (CONFIG_STORAGE & STORAGE_MMC)
361 if ((rc=mmc_soft_reset())) return rc;
362 #endif
364 #if (CONFIG_STORAGE & STORAGE_SD)
365 //if ((rc=sd_soft_reset())) return rc;
366 #endif
368 #if (CONFIG_STORAGE & STORAGE_NAND)
369 //if ((rc=nand_soft_reset())) return rc;
370 #endif
372 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
373 if ((rc=ramdisk_soft_reset())) return rc;
374 #endif
376 return rc;
379 #ifdef HAVE_STORAGE_FLUSH
380 int storage_flush(void)
382 int rc=0;
384 #if (CONFIG_STORAGE & STORAGE_ATA)
385 //if ((rc=ata_flush())) return rc;
386 #endif
388 #if (CONFIG_STORAGE & STORAGE_MMC)
389 //if ((rc=mmc_flush())) return rc;
390 #endif
392 #if (CONFIG_STORAGE & STORAGE_SD)
393 //if ((rc=sd_flush())) return rc;
394 #endif
396 #if (CONFIG_STORAGE & STORAGE_NAND)
397 if ((rc=nand_flush())) return rc;
398 #endif
400 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
401 //if ((rc=ramdisk_flush())) return rc;
402 #endif
404 return rc;
406 #endif
408 void storage_spin(void)
410 #if (CONFIG_STORAGE & STORAGE_ATA)
411 ata_spin();
412 #endif
414 #if (CONFIG_STORAGE & STORAGE_MMC)
415 mmc_spin();
416 #endif
418 #if (CONFIG_STORAGE & STORAGE_SD)
419 sd_spin();
420 #endif
422 #if (CONFIG_STORAGE & STORAGE_NAND)
423 nand_spin();
424 #endif
426 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
427 ramdisk_spin();
428 #endif
431 void storage_spindown(int seconds)
433 #if (CONFIG_STORAGE & STORAGE_ATA)
434 ata_spindown(seconds);
435 #endif
437 #if (CONFIG_STORAGE & STORAGE_MMC)
438 mmc_spindown(seconds);
439 #endif
441 #if (CONFIG_STORAGE & STORAGE_SD)
442 sd_spindown(seconds);
443 #endif
445 #if (CONFIG_STORAGE & STORAGE_NAND)
446 nand_spindown(seconds);
447 #endif
449 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
450 ramdisk_spindown(seconds);
451 #endif
454 #if (CONFIG_LED == LED_REAL)
455 void storage_set_led_enabled(bool enabled)
457 #if (CONFIG_STORAGE & STORAGE_ATA)
458 ata_set_led_enabled(enabled);
459 #endif
461 #if (CONFIG_STORAGE & STORAGE_MMC)
462 mmc_set_led_enabled(enabled);
463 #endif
465 #if (CONFIG_STORAGE & STORAGE_SD)
466 sd_set_led_enabled(enabled);
467 #endif
469 #if (CONFIG_STORAGE & STORAGE_NAND)
470 nand_set_led_enabled(enabled);
471 #endif
473 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
474 ramdisk_set_led_enabled(enabled);
475 #endif
477 #endif /* CONFIG_LED == LED_REAL */
479 long storage_last_disk_activity(void)
481 long max=0;
482 long t;
484 #if (CONFIG_STORAGE & STORAGE_ATA)
485 t=ata_last_disk_activity();
486 if (t>max) max=t;
487 #endif
489 #if (CONFIG_STORAGE & STORAGE_MMC)
490 t=mmc_last_disk_activity();
491 if (t>max) max=t;
492 #endif
494 #if (CONFIG_STORAGE & STORAGE_SD)
495 t=sd_last_disk_activity();
496 if (t>max) max=t;
497 #endif
499 #if (CONFIG_STORAGE & STORAGE_NAND)
500 t=nand_last_disk_activity();
501 if (t>max) max=t;
502 #endif
504 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
505 t=ramdisk_last_disk_activity();
506 if (t>max) max=t;
507 #endif
509 return max;
512 int storage_spinup_time(void)
514 int max=0;
515 int t;
517 #if (CONFIG_STORAGE & STORAGE_ATA)
518 t=ata_spinup_time();
519 if (t>max) max=t;
520 #endif
522 #if (CONFIG_STORAGE & STORAGE_MMC)
523 t=mmc_spinup_time();
524 if (t>max) max=t;
525 #endif
527 #if (CONFIG_STORAGE & STORAGE_SD)
528 //t=sd_spinup_time();
529 //if (t>max) max=t;
530 #endif
532 #if (CONFIG_STORAGE & STORAGE_NAND)
533 t=nand_spinup_time();
534 if (t>max) max=t;
535 #endif
537 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
538 t=ramdisk_spinup_time();
539 if (t>max) max=t;
540 #endif
542 return max;
545 #ifdef STORAGE_GET_INFO
546 void storage_get_info(int drive, struct storage_info *info)
548 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
549 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
551 switch(driver)
553 #if (CONFIG_STORAGE & STORAGE_ATA)
554 case STORAGE_ATA:
555 return ata_get_info(ldrive,info);
556 #endif
558 #if (CONFIG_STORAGE & STORAGE_MMC)
559 case STORAGE_MMC:
560 return mmc_get_info(ldrive,info);
561 #endif
563 #if (CONFIG_STORAGE & STORAGE_SD)
564 case STORAGE_SD:
565 return sd_get_info(ldrive,info);
566 #endif
568 #if (CONFIG_STORAGE & STORAGE_NAND)
569 case STORAGE_NAND:
570 return nand_get_info(ldrive,info);
571 #endif
573 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
574 case STORAGE_RAMDISK:
575 return ramdisk_get_info(ldrive,info);
576 #endif
579 #endif /* STORAGE_GET_INFO */
581 #ifdef HAVE_HOTSWAP
582 bool storage_removable(int drive)
584 bool ret = false;
586 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
587 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
589 switch(driver)
591 #if (CONFIG_STORAGE & STORAGE_ATA)
592 case STORAGE_ATA:
593 ret = ata_removable(ldrive);
594 #endif
596 #if (CONFIG_STORAGE & STORAGE_MMC)
597 case STORAGE_MMC:
598 ret = mmc_removable(ldrive);
599 #endif
601 #if (CONFIG_STORAGE & STORAGE_SD)
602 case STORAGE_SD:
603 ret = sd_removable(ldrive);
604 #endif
606 #if (CONFIG_STORAGE & STORAGE_NAND)
607 case STORAGE_NAND:
608 ret = false;
609 #endif
611 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
612 case STORAGE_RAMDISK:
613 ret = false;
614 #endif
617 return ret;
620 bool storage_present(int drive)
622 bool ret = false;
624 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
625 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
627 switch(driver)
629 #if (CONFIG_STORAGE & STORAGE_ATA)
630 case STORAGE_ATA:
631 ret = ata_present(ldrive);
632 #endif
634 #if (CONFIG_STORAGE & STORAGE_MMC)
635 case STORAGE_MMC:
636 ret = mmc_present(ldrive);
637 #endif
639 #if (CONFIG_STORAGE & STORAGE_SD)
640 case STORAGE_SD:
641 ret = sd_present(ldrive);
642 #endif
644 #if (CONFIG_STORAGE & STORAGE_NAND)
645 case STORAGE_NAND:
646 ret = true;
647 #endif
649 #if (CONFIG_STORAGE & STORAGE_RAMDISK)
650 case STORAGE_RAMDISK:
651 ret = true;
652 #endif
655 return ret;
657 #endif
659 #endif /*CONFIG_STORAGE_MULTI*/