A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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 "storage.h"
22#include "kernel.h"
23#include "ata_idle_notify.h"
24#include "usb.h"
25#include "disk.h"
26#include "pathfuncs.h"
27
28#ifdef CONFIG_STORAGE_MULTI
29
30#define DRIVER_MASK 0xff000000
31#define DRIVER_OFFSET 24
32#define DRIVE_MASK 0x00ff0000
33#define DRIVE_OFFSET 16
34#define PARTITION_MASK 0x0000ff00
35
36static unsigned int storage_drivers[NUM_DRIVES];
37static unsigned int num_drives;
38#endif /* CONFIG_STORAGE_MULTI */
39
40/* defaults: override elsewhere target-wise if they must be different */
41#if (CONFIG_STORAGE & STORAGE_ATA)
42 #ifndef ATA_THREAD_STACK_SIZE
43 #define ATA_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
44 #endif
45#endif
46#if (CONFIG_STORAGE & STORAGE_MMC)
47 #ifndef MMC_THREAD_STACK_SIZE
48 #define MMC_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
49 #endif
50#endif
51#if (CONFIG_STORAGE & STORAGE_SD)
52 #ifndef SD_THREAD_STACK_SIZE
53 #define SD_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
54 #endif
55#endif
56#if (CONFIG_STORAGE & STORAGE_NAND)
57 #ifndef NAND_THREAD_STACK_SIZE
58 #define NAND_THREAD_STACK_SIZE (DEFAULT_STACK_SIZE*2)
59 #endif
60#endif
61#if (CONFIG_STORAGE & STORAGE_RAMDISK)
62 #ifndef RAMDISK_THREAD_STACK_SIZE
63 #define RAMDISK_THREAD_STACK_SIZE (0) /* not used on its own */
64 #endif
65#endif
66
67static struct event_queue storage_queue SHAREDBSS_ATTR;
68static unsigned int storage_thread_id = 0;
69
70static union {
71#if (CONFIG_STORAGE & STORAGE_ATA)
72 long stk_ata[ATA_THREAD_STACK_SIZE / sizeof (long)];
73#endif
74#if (CONFIG_STORAGE & STORAGE_MMC)
75 long stk_mmc[MMC_THREAD_STACK_SIZE / sizeof (long)];
76#endif
77#if (CONFIG_STORAGE & STORAGE_SD)
78 long stk_sd[SD_THREAD_STACK_SIZE / sizeof (long)];
79#endif
80#if (CONFIG_STORAGE & STORAGE_NAND)
81 long stk_nand[NAND_THREAD_STACK_SIZE / sizeof (long)];
82#endif
83#if (CONFIG_STORAGE & STORAGE_RAMDISK)
84 long stk_ramdisk[RAMDISK_THREAD_STACK_SIZE / sizeof (long)];
85#endif
86} storage_thread_stack;
87
88static const char storage_thread_name[] =
89#if (CONFIG_STORAGE & STORAGE_ATA)
90 "/ata"
91#endif
92#if (CONFIG_STORAGE & STORAGE_MMC)
93 "/mmc"
94#endif
95#if (CONFIG_STORAGE & STORAGE_SD)
96 "/sd"
97#endif
98#if (CONFIG_STORAGE & STORAGE_NAND)
99 "/nand"
100#endif
101#if (CONFIG_STORAGE & STORAGE_RAMDISK)
102 "/ramdisk"
103#endif
104 ;
105
106/* event is targeted to a specific drive */
107#define DRIVE_EVT (1 << STORAGE_NUM_TYPES)
108
109#ifdef CONFIG_STORAGE_MULTI
110static int storage_event_send(unsigned int route, long id, intptr_t data)
111{
112 /* most events go to everyone */
113 if (UNLIKELY(route == DRIVE_EVT)) {
114 route = (storage_drivers[data] & DRIVER_MASK) >> DRIVER_OFFSET;
115 data = (storage_drivers[data] & DRIVE_MASK) >> DRIVE_OFFSET;
116 }
117
118 int rc = 0;
119
120#if (CONFIG_STORAGE & STORAGE_ATA)
121 if (route & STORAGE_ATA) {
122 rc = ata_event(id, data);
123 }
124#endif
125#if (CONFIG_STORAGE & STORAGE_MMC)
126 if (route & STORAGE_MMC) {
127 rc = mmc_event(id, data);
128 }
129#endif
130#if (CONFIG_STORAGE & STORAGE_SD)
131 if (route & STORAGE_SD) {
132 rc = sd_event(id, data);
133 }
134#endif
135#if (CONFIG_STORAGE & STORAGE_NAND)
136 if (route & STORAGE_NAND) {
137 rc = nand_event(id, data);
138 }
139#endif
140#if (CONFIG_STORAGE & STORAGE_RAMDISK)
141 if (route & STORAGE_RAMDISK) {
142 rc = ramdisk_event(id, data);
143 }
144#endif
145
146 return rc;
147}
148#endif /* CONFIG_STORAGE_MULTI */
149
150#ifndef CONFIG_STORAGE_MULTI
151static FORCE_INLINE int storage_event_send(unsigned int route, long id,
152 intptr_t data)
153{
154 return route ? STORAGE_FUNCTION(event)(id, data) : 0;
155}
156#endif /* ndef CONFIG_STORAGE_MULTI */
157
158static void NORETURN_ATTR storage_thread(void)
159{
160 unsigned int bdcast = CONFIG_STORAGE;
161 bool usb_mode = false;
162 struct queue_event ev;
163
164 while (1)
165 {
166 queue_wait_w_tmo(&storage_queue, &ev, HZ/2);
167
168 switch (ev.id)
169 {
170 case SYS_TIMEOUT:;
171 /* drivers hold their bit low when they want to
172 sleep and keep it high otherwise */
173 unsigned int trig = 0;
174 storage_event_send(bdcast, Q_STORAGE_TICK, (intptr_t)&trig);
175 trig = bdcast & ~trig;
176 if (trig) {
177 if (!usb_mode) {
178 call_storage_idle_notifys(false);
179 }
180 storage_event_send(trig, Q_STORAGE_SLEEPNOW, 0);
181 }
182 break;
183
184#if (CONFIG_STORAGE & STORAGE_ATA)
185 case Q_STORAGE_SLEEP:
186 storage_event_send(bdcast, ev.id, 0);
187 break;
188#endif
189
190#ifdef STORAGE_CLOSE
191 case Q_STORAGE_CLOSE:
192 storage_event_send(CONFIG_STORAGE, ev.id, 0);
193 thread_exit();
194#endif /* STORAGE_CLOSE */
195
196#ifdef HAVE_HOTSWAP
197 case SYS_HOTSWAP_INSERTED:
198 case SYS_HOTSWAP_EXTRACTED:
199 if (!usb_mode) {
200 int drive = IF_MD_DRV(ev.data);
201 if (!CHECK_DRV(drive)) {
202 break;
203 }
204
205 int umnt = disk_unmount(drive);
206 int mnt = 0;
207 int rci = storage_event_send(DRIVE_EVT, ev.id, drive);
208
209 if (ev.id == SYS_HOTSWAP_INSERTED && !rci) {
210 mnt = disk_mount(drive);
211 }
212
213 if (umnt > 0 || mnt > 0) {
214 /* something was unmounted and/or mounted */
215 queue_broadcast(SYS_FS_CHANGED, drive);
216 }
217 }
218 break;
219#endif /* HAVE_HOTSWAP */
220
221#ifndef USB_NONE
222 case SYS_USB_CONNECTED:
223 case SYS_USB_DISCONNECTED:
224 bdcast = 0;
225 storage_event_send(CONFIG_STORAGE, ev.id, (intptr_t)&bdcast);
226 usb_mode = ev.id == SYS_USB_CONNECTED;
227 if (usb_mode) {
228 usb_acknowledge(SYS_USB_CONNECTED_ACK);
229 }
230 else {
231 bdcast = CONFIG_STORAGE;
232 }
233 break;
234#endif /* ndef USB_NONE */
235 }
236 }
237}
238
239#if (CONFIG_STORAGE & STORAGE_ATA)
240void storage_sleep(void)
241{
242 if (storage_thread_id) {
243 queue_post(&storage_queue, Q_STORAGE_SLEEP, 0);
244 }
245}
246#endif /* (CONFIG_STORAGE & STORAGE_ATA) */
247
248#ifdef STORAGE_CLOSE
249void storage_close(void)
250{
251 if (storage_thread_id) {
252 queue_post(&storage_queue, Q_STORAGE_CLOSE, 0);
253 thread_wait(storage_thread_id);
254 }
255}
256#endif /* STORAGE_CLOSE */
257
258static inline void storage_thread_init(void)
259{
260 if (storage_thread_id) {
261 return;
262 }
263
264 queue_init(&storage_queue, true);
265 storage_thread_id = create_thread(storage_thread, &storage_thread_stack,
266 sizeof (storage_thread_stack),
267 0, &storage_thread_name[1]
268 IF_PRIO(, PRIORITY_USER_INTERFACE)
269 IF_COP(, CPU));
270}
271
272int storage_init(void)
273{
274 int rc=0;
275
276#ifdef CONFIG_STORAGE_MULTI
277 int i;
278 num_drives=0;
279
280#if (CONFIG_STORAGE & STORAGE_ATA)
281 if ((rc=ata_init())) return rc;
282
283 int ata_drives = ata_num_drives(num_drives);
284 for (i=0; i<ata_drives; i++)
285 {
286 storage_drivers[num_drives++] =
287 (STORAGE_ATA<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
288 }
289#endif
290
291#if (CONFIG_STORAGE & STORAGE_MMC)
292 if ((rc=mmc_init())) return rc;
293
294 int mmc_drives = mmc_num_drives(num_drives);
295 for (i=0; i<mmc_drives ;i++)
296 {
297 storage_drivers[num_drives++] =
298 (STORAGE_MMC<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
299 }
300#endif
301
302#if (CONFIG_STORAGE & STORAGE_SD)
303 if ((rc=sd_init())) return rc;
304
305 int sd_drives = sd_num_drives(num_drives);
306 for (i=0; i<sd_drives; i++)
307 {
308 storage_drivers[num_drives++] =
309 (STORAGE_SD<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
310 }
311#endif
312
313#if (CONFIG_STORAGE & STORAGE_NAND)
314 if ((rc=nand_init())) return rc;
315
316 int nand_drives = nand_num_drives(num_drives);
317 for (i=0; i<nand_drives; i++)
318 {
319 storage_drivers[num_drives++] =
320 (STORAGE_NAND<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
321 }
322#endif
323
324#if (CONFIG_STORAGE & STORAGE_RAMDISK)
325 if ((rc=ramdisk_init())) return rc;
326
327 int ramdisk_drives = ramdisk_num_drives(num_drives);
328 for (i=0; i<ramdisk_drives; i++)
329 {
330 storage_drivers[num_drives++] =
331 (STORAGE_RAMDISK<<DRIVER_OFFSET) | (i << DRIVE_OFFSET);
332 }
333#endif
334#else /* ndef CONFIG_STORAGE_MULTI */
335 rc = STORAGE_FUNCTION(init)();
336#endif /* CONFIG_STORAGE_MULTI */
337
338#ifdef HAVE_MULTIVOLUME
339 init_volume_names();
340#endif
341
342 storage_thread_init();
343 return rc;
344}
345
346int storage_read_sectors(IF_MD(int drive,) sector_t start, int count,
347 void* buf)
348{
349#ifdef CONFIG_STORAGE_MULTI
350 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
351 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
352
353 switch (driver)
354 {
355#if (CONFIG_STORAGE & STORAGE_ATA)
356 case STORAGE_ATA:
357 return ata_read_sectors(IF_MD(ldrive,) start,count,buf);
358#endif
359
360#if (CONFIG_STORAGE & STORAGE_MMC)
361 case STORAGE_MMC:
362 return mmc_read_sectors(IF_MD(ldrive,) start,count,buf);
363#endif
364
365#if (CONFIG_STORAGE & STORAGE_SD)
366 case STORAGE_SD:
367 return sd_read_sectors(IF_MD(ldrive,) start,count,buf);
368#endif
369
370#if (CONFIG_STORAGE & STORAGE_NAND)
371 case STORAGE_NAND:
372 return nand_read_sectors(IF_MD(ldrive,) start,count,buf);
373#endif
374
375#if (CONFIG_STORAGE & STORAGE_RAMDISK)
376 case STORAGE_RAMDISK:
377 return ramdisk_read_sectors(IF_MD(ldrive,) start,count,buf);
378#endif
379 }
380
381 return -1;
382#else /* CONFIG_STORAGE_MULTI */
383 return STORAGE_FUNCTION(read_sectors)(IF_MD(drive,)start,count,buf);
384#endif /* CONFIG_STORAGE_MULTI */
385
386}
387
388int storage_write_sectors(IF_MD(int drive,) sector_t start, int count,
389 const void* buf)
390{
391#ifdef CONFIG_STORAGE_MULTI
392 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
393 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
394
395 switch (driver)
396 {
397#if (CONFIG_STORAGE & STORAGE_ATA)
398 case STORAGE_ATA:
399 return ata_write_sectors(IF_MD(ldrive,)start,count,buf);
400#endif
401
402#if (CONFIG_STORAGE & STORAGE_MMC)
403 case STORAGE_MMC:
404 return mmc_write_sectors(IF_MD(ldrive,)start,count,buf);
405#endif
406
407#if (CONFIG_STORAGE & STORAGE_SD)
408 case STORAGE_SD:
409 return sd_write_sectors(IF_MD(ldrive,)start,count,buf);
410#endif
411
412#if (CONFIG_STORAGE & STORAGE_NAND)
413 case STORAGE_NAND:
414 return nand_write_sectors(IF_MD(ldrive,)start,count,buf);
415#endif
416
417#if (CONFIG_STORAGE & STORAGE_RAMDISK)
418 case STORAGE_RAMDISK:
419 return ramdisk_write_sectors(IF_MD(ldrive,)start,count,buf);
420#endif
421 }
422
423 return -1;
424#else /* CONFIG_STORAGE_MULTI */
425 return STORAGE_FUNCTION(write_sectors)(IF_MD(drive,)start,count,buf);
426#endif /* CONFIG_STORAGE_MULTI */
427}
428
429#ifdef CONFIG_STORAGE_MULTI
430
431#define DRIVER_MASK 0xff000000
432#define DRIVER_OFFSET 24
433#define DRIVE_MASK 0x00ff0000
434#define DRIVE_OFFSET 16
435#define PARTITION_MASK 0x0000ff00
436
437static unsigned int storage_drivers[NUM_DRIVES];
438static unsigned int num_drives;
439
440int storage_num_drives(void)
441{
442 return num_drives;
443}
444
445int storage_driver_type(int drive)
446{
447 if ((unsigned int)drive >= num_drives)
448 return -1;
449
450 unsigned int bit = (storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
451 return bit ? find_first_set_bit(bit) : -1;
452}
453
454void storage_enable(bool on)
455{
456#if (CONFIG_STORAGE & STORAGE_ATA)
457 ata_enable(on);
458#endif
459
460#if (CONFIG_STORAGE & STORAGE_MMC)
461 mmc_enable(on);
462#endif
463
464#if (CONFIG_STORAGE & STORAGE_SD)
465 sd_enable(on);
466#endif
467
468#if (CONFIG_STORAGE & STORAGE_NAND)
469 nand_enable(on);
470#endif
471
472#if (CONFIG_STORAGE & STORAGE_RAMDISK)
473 ramdisk_enable(on);
474#endif
475}
476
477void storage_sleepnow(void)
478{
479#if (CONFIG_STORAGE & STORAGE_ATA)
480 ata_sleepnow();
481#endif
482
483#if (CONFIG_STORAGE & STORAGE_MMC)
484 mmc_sleepnow();
485#endif
486
487#if (CONFIG_STORAGE & STORAGE_SD)
488 //sd_sleepnow();
489#endif
490
491#if (CONFIG_STORAGE & STORAGE_NAND)
492 nand_sleepnow();
493#endif
494
495#if (CONFIG_STORAGE & STORAGE_RAMDISK)
496 ramdisk_sleepnow();
497#endif
498}
499
500bool storage_disk_is_active(void)
501{
502#if (CONFIG_STORAGE & STORAGE_ATA)
503 if (ata_disk_is_active()) return true;
504#endif
505
506#if (CONFIG_STORAGE & STORAGE_MMC)
507 if (mmc_disk_is_active()) return true;
508#endif
509
510#if (CONFIG_STORAGE & STORAGE_SD)
511 //if (sd_disk_is_active()) return true;
512#endif
513
514#if (CONFIG_STORAGE & STORAGE_NAND)
515 //if (nand_disk_is_active()) return true;
516#endif
517
518#if (CONFIG_STORAGE & STORAGE_RAMDISK)
519 if (ramdisk_disk_is_active()) return true;
520#endif
521
522 return false;
523}
524
525int storage_soft_reset(void)
526{
527 int rc=0;
528
529#if (CONFIG_STORAGE & STORAGE_ATA)
530 if ((rc=ata_soft_reset())) return rc;
531#endif
532
533#if (CONFIG_STORAGE & STORAGE_MMC)
534 if ((rc=mmc_soft_reset())) return rc;
535#endif
536
537#if (CONFIG_STORAGE & STORAGE_SD)
538 //if ((rc=sd_soft_reset())) return rc;
539#endif
540
541#if (CONFIG_STORAGE & STORAGE_NAND)
542 //if ((rc=nand_soft_reset())) return rc;
543#endif
544
545#if (CONFIG_STORAGE & STORAGE_RAMDISK)
546 if ((rc=ramdisk_soft_reset())) return rc;
547#endif
548
549 return rc;
550}
551
552#ifdef HAVE_STORAGE_FLUSH
553int storage_flush(void)
554{
555 int rc=0;
556
557#if (CONFIG_STORAGE & STORAGE_ATA)
558 if ((rc=ata_flush())) return rc;
559#endif
560
561#if (CONFIG_STORAGE & STORAGE_MMC)
562 //if ((rc=mmc_flush())) return rc;
563#endif
564
565#if (CONFIG_STORAGE & STORAGE_SD)
566 //if ((rc=sd_flush())) return rc;
567#endif
568
569#if (CONFIG_STORAGE & STORAGE_NAND)
570 if ((rc=nand_flush())) return rc;
571#endif
572
573#if (CONFIG_STORAGE & STORAGE_RAMDISK)
574 //if ((rc=ramdisk_flush())) return rc;
575#endif
576
577 return rc;
578}
579#endif
580
581void storage_spin(void)
582{
583#if (CONFIG_STORAGE & STORAGE_ATA)
584 ata_spin();
585#endif
586
587#if (CONFIG_STORAGE & STORAGE_MMC)
588 mmc_spin();
589#endif
590
591#if (CONFIG_STORAGE & STORAGE_SD)
592 sd_spin();
593#endif
594
595#if (CONFIG_STORAGE & STORAGE_NAND)
596 nand_spin();
597#endif
598
599#if (CONFIG_STORAGE & STORAGE_RAMDISK)
600 ramdisk_spin();
601#endif
602}
603
604void storage_spindown(int seconds)
605{
606#if (CONFIG_STORAGE & STORAGE_ATA)
607 ata_spindown(seconds);
608#endif
609
610#if (CONFIG_STORAGE & STORAGE_MMC)
611 mmc_spindown(seconds);
612#endif
613
614#if (CONFIG_STORAGE & STORAGE_SD)
615 sd_spindown(seconds);
616#endif
617
618#if (CONFIG_STORAGE & STORAGE_NAND)
619 nand_spindown(seconds);
620#endif
621
622#if (CONFIG_STORAGE & STORAGE_RAMDISK)
623 ramdisk_spindown(seconds);
624#endif
625}
626
627#if (CONFIG_LED == LED_REAL)
628void storage_set_led_enabled(bool enabled)
629{
630#if (CONFIG_STORAGE & STORAGE_ATA)
631 ata_set_led_enabled(enabled);
632#endif
633
634#if (CONFIG_STORAGE & STORAGE_MMC)
635 mmc_set_led_enabled(enabled);
636#endif
637
638#if (CONFIG_STORAGE & STORAGE_SD)
639 sd_set_led_enabled(enabled);
640#endif
641
642#if (CONFIG_STORAGE & STORAGE_NAND)
643 nand_set_led_enabled(enabled);
644#endif
645
646#if (CONFIG_STORAGE & STORAGE_RAMDISK)
647 ramdisk_set_led_enabled(enabled);
648#endif
649}
650#endif /* CONFIG_LED == LED_REAL */
651
652long storage_last_disk_activity(void)
653{
654 long max=0;
655 long t;
656
657#if (CONFIG_STORAGE & STORAGE_ATA)
658 t=ata_last_disk_activity();
659 if (t>max) max=t;
660#endif
661
662#if (CONFIG_STORAGE & STORAGE_MMC)
663 t=mmc_last_disk_activity();
664 if (t>max) max=t;
665#endif
666
667#if (CONFIG_STORAGE & STORAGE_SD)
668 t=sd_last_disk_activity();
669 if (t>max) max=t;
670#endif
671
672#if (CONFIG_STORAGE & STORAGE_NAND)
673 t=nand_last_disk_activity();
674 if (t>max) max=t;
675#endif
676
677#if (CONFIG_STORAGE & STORAGE_RAMDISK)
678 t=ramdisk_last_disk_activity();
679 if (t>max) max=t;
680#endif
681
682 return max;
683}
684
685int storage_spinup_time(void)
686{
687 int max=0;
688 int t;
689
690#if (CONFIG_STORAGE & STORAGE_ATA)
691 t=ata_spinup_time();
692 if (t>max) max=t;
693#endif
694
695#if (CONFIG_STORAGE & STORAGE_MMC)
696 t=mmc_spinup_time();
697 if (t>max) max=t;
698#endif
699
700#if (CONFIG_STORAGE & STORAGE_SD)
701 //t=sd_spinup_time();
702 //if (t>max) max=t;
703 (void)t;
704#endif
705
706#if (CONFIG_STORAGE & STORAGE_NAND)
707 t=nand_spinup_time();
708 if (t>max) max=t;
709#endif
710
711#if (CONFIG_STORAGE & STORAGE_RAMDISK)
712 t=ramdisk_spinup_time();
713 if (t>max) max=t;
714#endif
715
716 return max;
717}
718
719#ifdef STORAGE_GET_INFO
720void storage_get_info(int drive, struct storage_info *info)
721{
722 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
723 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
724
725 switch(driver)
726 {
727#if (CONFIG_STORAGE & STORAGE_ATA)
728 case STORAGE_ATA:
729 return ata_get_info(ldrive,info);
730#endif
731
732#if (CONFIG_STORAGE & STORAGE_MMC)
733 case STORAGE_MMC:
734 return mmc_get_info(ldrive,info);
735#endif
736
737#if (CONFIG_STORAGE & STORAGE_SD)
738 case STORAGE_SD:
739 return sd_get_info(ldrive,info);
740#endif
741
742#if (CONFIG_STORAGE & STORAGE_NAND)
743 case STORAGE_NAND:
744 return nand_get_info(ldrive,info);
745#endif
746
747#if (CONFIG_STORAGE & STORAGE_RAMDISK)
748 case STORAGE_RAMDISK:
749 return ramdisk_get_info(ldrive,info);
750#endif
751 }
752}
753#endif /* STORAGE_GET_INFO */
754
755#ifdef HAVE_HOTSWAP
756bool storage_removable(int drive)
757{
758 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
759 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
760
761 switch(driver)
762 {
763#if (CONFIG_STORAGE & STORAGE_ATA)
764 case STORAGE_ATA:
765 return false;
766#endif
767
768#if (CONFIG_STORAGE & STORAGE_MMC)
769 case STORAGE_MMC:
770 return mmc_removable(ldrive);
771#endif
772
773#if (CONFIG_STORAGE & STORAGE_SD)
774 case STORAGE_SD:
775 return sd_removable(ldrive);
776#endif
777
778#if (CONFIG_STORAGE & STORAGE_NAND)
779 case STORAGE_NAND:
780 return false;
781#endif
782
783#if (CONFIG_STORAGE & STORAGE_RAMDISK)
784 case STORAGE_RAMDISK:
785 return false;
786#endif
787
788 default:
789 return false;
790 }
791}
792
793bool storage_present(int drive)
794{
795 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
796 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
797
798 switch(driver)
799 {
800#if (CONFIG_STORAGE & STORAGE_ATA)
801 case STORAGE_ATA:
802 return true;
803#endif
804
805#if (CONFIG_STORAGE & STORAGE_MMC)
806 case STORAGE_MMC:
807 return mmc_present(ldrive);
808#endif
809
810#if (CONFIG_STORAGE & STORAGE_SD)
811 case STORAGE_SD:
812 return sd_present(ldrive);
813#endif
814
815#if (CONFIG_STORAGE & STORAGE_NAND)
816 case STORAGE_NAND:
817 return true;
818#endif
819
820#if (CONFIG_STORAGE & STORAGE_RAMDISK)
821 case STORAGE_RAMDISK:
822 return true;
823#endif
824
825 default:
826 return false;
827 }
828}
829#endif /* HAVE_HOTSWAP */
830#endif /*CONFIG_STORAGE_MULTI*/