Apply FS#9500. This adds a storage_*() abstraction to replace ata_*(). To do that, it also introduces sd_*, nand_*, and mmc_*.
This should be a good first step to allow multi-driver targets, like the Elio (ATA/SD), or the D2 (NAND/SD).


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18960 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/buffering.c b/apps/buffering.c
index d963a98..534a82d 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -26,7 +26,7 @@
 #include <ctype.h>
 #include "buffering.h"
 
-#include "ata.h"
+#include "storage.h"
 #include "system.h"
 #include "thread.h"
 #include "file.h"
@@ -832,7 +832,7 @@
     {
         /* only spin the disk down if the filling wasn't interrupted by an
            event arriving in the queue. */
-        ata_sleep();
+        storage_sleep();
         return false;
     }
 }
@@ -1408,7 +1408,7 @@
          * for simplicity until its done right */
 #if MEM > 8
         /* If the disk is spinning, take advantage by filling the buffer */
-        else if (ata_disk_is_active() && queue_empty(&buffering_queue))
+        else if (storage_disk_is_active() && queue_empty(&buffering_queue))
         {
             if (num_handles > 0 && data_counters.useful <= high_watermark)
                 send_event(BUFFER_EVENT_BUFFER_LOW, 0);
diff --git a/apps/codecs.c b/apps/codecs.c
index 53fa675..8f5a0e3 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -43,7 +43,7 @@
 #include "buffering.h"
 #include "mp3_playback.h"
 #include "backlight.h"
-#include "ata.h"
+#include "storage.h"
 #include "talk.h"
 #include "mp3data.h"
 #include "powermgmt.h"
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 26534cc..b6038e7 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -59,13 +59,16 @@
 #include "power.h"
 #include "usb.h"
 #include "rtc.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "mas.h"
 #include "eeprom_24cxx.h"
 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
 #include "hotswap.h"
 #endif
+#if (CONFIG_STORAGE & STORAGE_ATA)
+#include "ata.h"
+#endif
 #if CONFIG_TUNER
 #include "tuner.h"
 #include "radio.h"
@@ -1731,11 +1734,13 @@
 
 #ifndef SIMULATOR
 #if (CONFIG_STORAGE & STORAGE_MMC) || (CONFIG_STORAGE & STORAGE_SD)
+
 #if (CONFIG_STORAGE & STORAGE_MMC)
 #define CARDTYPE "MMC"
-#else
+#elif (CONFIG_STORAGE & STORAGE_SD)
 #define CARDTYPE "microSD"
 #endif
+
 static int disk_callback(int btn, struct gui_synclist *lists)
 {
     tCardInfo *card;
@@ -1826,7 +1831,7 @@
     }
     return btn;
 }
-#else /* !(CONFIG_STORAGE & STORAGE_MMC) && !(CONFIG_STORAGE & STORAGE_SD) */
+#elif  (CONFIG_STORAGE & STORAGE_ATA) 
 static int disk_callback(int btn, struct gui_synclist *lists)
 {
     (void)lists;
@@ -1860,7 +1865,7 @@
     simplelist_addline(SIMPLELIST_ADD_LINE,
              "Free: %ld MB", free / 1024);
     simplelist_addline(SIMPLELIST_ADD_LINE,
-             "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
+             "Spinup time: %d ms", storage_spinup_time() * (1000/HZ));
     i = identify_info[83] & (1<<3);
     simplelist_addline(SIMPLELIST_ADD_LINE,
              "Power mgmt: %s", i ? "enabled" : "unsupported");
@@ -1945,7 +1950,29 @@
              "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
     return btn;
 }
+#else /* No SD, MMC or ATA */
+static int disk_callback(int btn, struct gui_synclist *lists)
+{
+    (void)btn;
+    (void)lists;
+    struct storage_info info;
+    storage_get_info(IF_MV2(0,)&info);
+    simplelist_addline(SIMPLELIST_ADD_LINE, "Vendor: %s", info.vendor);
+    simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", info.product);
+    simplelist_addline(SIMPLELIST_ADD_LINE, "Firmware: %s", info.revision);
+    simplelist_addline(SIMPLELIST_ADD_LINE,
+             "Size: %ld MB", info.num_sectors*(info.sector_size/512)/2024);
+    unsigned long free;
+    fat_size( IF_MV2(0,) NULL, &free );
+    simplelist_addline(SIMPLELIST_ADD_LINE,
+             "Free: %ld MB", free / 1024);
+    simplelist_addline(SIMPLELIST_ADD_LINE,
+             "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
+    return btn;
+}
+#endif
 
+#if  (CONFIG_STORAGE & STORAGE_ATA) 
 static bool dbg_identify_info(void)
 {
     int fd = creat("/identify_info.bin");
@@ -1960,7 +1987,7 @@
     }
     return false;
 }
-#endif /* !(CONFIG_STORAGE & STORAGE_MMC) && !(CONFIG_STORAGE & STORAGE_SD) */
+#endif
 
 static bool dbg_disk_info(void)
 {
@@ -2504,7 +2531,7 @@
 #endif
 #ifndef SIMULATOR
         { "View disk info", dbg_disk_info },
-#if !(CONFIG_STORAGE & STORAGE_MMC) && !(CONFIG_STORAGE & STORAGE_SD)
+#if (CONFIG_STORAGE & STORAGE_ATA)
         { "Dump ATA identify info", dbg_identify_info},
 #endif
 #endif
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 4d50740..9b6d6b5 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -39,7 +39,7 @@
 #include "audio.h"
 #include "usb.h"
 #include "status.h"
-#include "ata.h"
+#include "storage.h"
 #include "screens.h"
 #include "playlist.h"
 #ifdef HAVE_LCD_BITMAP
@@ -184,7 +184,7 @@
             if (wps_state.paused) {
                 settings_save();
 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
-                call_ata_idle_notifys(true);
+                call_storage_idle_notifys(true);
 #endif
             }
         }
@@ -322,7 +322,7 @@
                         audio_pause();
                     settings_save();
 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
-                    call_ata_idle_notifys(true);   /* make sure resume info is saved */
+                    call_storage_idle_notifys(true);   /* make sure resume info is saved */
 #endif
                 }
                 break;
@@ -701,7 +701,7 @@
         }
 
         if ( button )
-            ata_spin();
+            storage_spin();
     }
     return GO_TO_ROOT; /* unreachable - just to reduce compiler warnings */
 }
diff --git a/apps/main.c b/apps/main.c
index 5059769..111c5d1 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -20,7 +20,7 @@
  ****************************************************************************/
 #include "config.h"
 
-#include "ata.h"
+#include "storage.h"
 #include "disk.h"
 #include "fat.h"
 #include "lcd.h"
@@ -289,7 +289,7 @@
 #endif
     /* Must be done before any code uses the multi-screen APi */
     gui_syncstatusbar_init(&statusbars);
-    ata_init();
+    storage_init();
     settings_reset();
     settings_load(SETTINGS_ALL);
     gui_sync_wps_init();
@@ -427,7 +427,7 @@
     }
 #endif
 
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
 #ifdef HAVE_LCD_BITMAP
diff --git a/apps/misc.c b/apps/misc.c
index 7c8ff0f..02d8bed 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -46,7 +46,7 @@
 #include "audio.h"
 #include "mp3_playback.h"
 #include "settings.h"
-#include "ata.h"
+#include "storage.h"
 #include "ata_idle_notify.h"
 #include "kernel.h"
 #include "power.h"
@@ -621,7 +621,7 @@
 static void system_flush(void)
 {
     tree_flush();
-    call_ata_idle_notifys(true); /*doesnt work on usb and shutdown from ata thread */
+    call_storage_idle_notifys(true); /*doesnt work on usb and shutdown from ata thread */
 }
 
 static void system_restore(void)
@@ -635,7 +635,7 @@
     (void)callback;
     (void)parameter;
     bookmark_autobookmark();
-    call_ata_idle_notifys(true);
+    call_storage_idle_notifys(true);
     exit(0);
 #else
     long msg_id = -1;
diff --git a/apps/mpeg.c b/apps/mpeg.c
index 3c37a6b..f6d48bf 100644
--- a/apps/mpeg.c
+++ b/apps/mpeg.c
@@ -29,7 +29,7 @@
 #include "metadata.h"
 #include "mpeg.h"
 #include "audio.h"
-#include "ata.h"
+#include "storage.h"
 #include "string.h"
 #include <kernel.h>
 #include "thread.h"
@@ -509,7 +509,7 @@
 static void recalculate_watermark(int bitrate)
 {
     int bytes_per_sec;
-    int time = ata_spinup_time;
+    int time = storage_spinup_time();
 
     /* A bitrate of 0 probably means empty VBR header. We play safe
        and set a high threshold */
@@ -1589,7 +1589,7 @@
                     DEBUGF("0\n");
                     filling = false;
                     generate_postbuffer_events();
-                    ata_sleep();
+                    storage_sleep();
                     break;
                 }
 
@@ -1947,7 +1947,7 @@
                                 rc = fsync(mpeg_file);
                                 if (rc < 0)
                                     panicf("rec fls: %d", rc);
-                                ata_sleep();
+                                storage_sleep();
                                 break;
 
                             case NEW_FILE:
@@ -1957,7 +1957,7 @@
                                     panicf("rec cls: %d", rc);
                                 mpeg_file = -1;
                                 update_header();
-                                ata_sleep();
+                                storage_sleep();
 
                                 /* copy new filename */
                                 strcpy(delayed_filename, recording_filename);
diff --git a/apps/playback.c b/apps/playback.c
index b230594..ec4f419 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -49,7 +49,7 @@
 #include "mp3_playback.h"
 #include "usb.h"
 #include "status.h"
-#include "ata.h"
+#include "storage.h"
 #include "screens.h"
 #include "playlist.h"
 #include "playback.h"
diff --git a/apps/playlist.c b/apps/playlist.c
index cdcc059..95e1b82 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -1266,7 +1266,7 @@
                 if (playlist->control_fd >= 0)
                 {
                     if (playlist->num_cached > 0)
-                        register_ata_idle_func(playlist_flush_callback);
+                        register_storage_idle_func(playlist_flush_callback);
                 }
 
                 if (!dirty_pointers)
diff --git a/apps/plugin.c b/apps/plugin.c
index 86e5c51..e46e193 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -38,6 +38,7 @@
 #include "option_select.h"
 #include "talk.h"
 #include "version.h"
+#include "storage.h"
 
 #if CONFIG_CHARGING
 #include "power.h"
@@ -265,13 +266,13 @@
     fdprintf,
     read_line,
     settings_parseline,
-    ata_sleep,
-    ata_spin,
-    ata_spindown,
-#if USING_ATA_CALLBACK
-    register_ata_idle_func,
-    unregister_ata_idle_func,
-#endif /* USING_ATA_CALLBACK */
+    storage_sleep,
+    storage_spin,
+    storage_spindown,
+#if USING_STORAGE_CALLBACK
+    register_storage_idle_func,
+    unregister_storage_idle_func,
+#endif /* USING_STORAGE_CALLBACK */
     reload_directory,
     create_numbered_filename,
     file_exists,
diff --git a/apps/plugin.h b/apps/plugin.h
index 08d0b60..464614d 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -379,13 +379,13 @@
     int (*fdprintf)(int fd, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
     int (*read_line)(int fd, char* buffer, int buffer_size);
     bool (*settings_parseline)(char* line, char** name, char** value);
-    void (*ata_sleep)(void);
-    void (*ata_spin)(void);
-    void (*ata_spindown)(int seconds);
-#if USING_ATA_CALLBACK
-    void (*register_ata_idle_func)(ata_idle_notify function);
-    void (*unregister_ata_idle_func)(ata_idle_notify function, bool run);
-#endif /* USING_ATA_CALLBACK */
+    void (*storage_sleep)(void);
+    void (*storage_spin)(void);
+    void (*storage_spindown)(int seconds);
+#if USING_STORAGE_CALLBACK
+    void (*register_storage_idle_func)(storage_idle_notify function);
+    void (*unregister_storage_idle_func)(storage_idle_notify function, bool run);
+#endif /* USING_STORAGE_CALLBACK */
     void (*reload_directory)(void);
     char *(*create_numbered_filename)(char *buffer, const char *path,
                                       const char *prefix, const char *suffix,
diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c
index ef4795a..fff93b2 100644
--- a/apps/plugins/battery_bench.c
+++ b/apps/plugins/battery_bench.c
@@ -344,7 +344,7 @@
             bat[buf_idx].flags = charge_state();
 #endif
             buf_idx++;
-            rb->register_ata_idle_func(flush_buffer);
+            rb->register_storage_idle_func(flush_buffer);
         }
         
         /* What to do when the measurement buffer is full:
@@ -386,7 +386,7 @@
     }
 
     /* unregister flush callback and flush to disk */
-    rb->unregister_ata_idle_func(flush_buffer, true);
+    rb->unregister_storage_idle_func(flush_buffer, true);
     
     /* log end of bench and exit reason */
     fd = rb->open(BATTERY_LOG, O_RDWR | O_CREAT | O_APPEND);
diff --git a/apps/plugins/clock/clock_settings.c b/apps/plugins/clock/clock_settings.c
index 44a6f16..1147055 100644
--- a/apps/plugins/clock/clock_settings.c
+++ b/apps/plugins/clock/clock_settings.c
@@ -173,7 +173,7 @@
             draw_message(display, MESSAGE_ERRLOAD, 1);
         display->update();
     }
-    rb->ata_sleep();
+    rb->storage_sleep();
     rb->sleep(HZ);
 }
 
diff --git a/apps/plugins/jpeg/jpeg.c b/apps/plugins/jpeg/jpeg.c
index ed1b181..d8775dd 100644
--- a/apps/plugins/jpeg/jpeg.c
+++ b/apps/plugins/jpeg/jpeg.c
@@ -438,14 +438,14 @@
 #if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
     /* change ata spindown time based on slideshow time setting */
     immediate_ata_off = false;
-    rb->ata_spindown(rb->global_settings->disk_spindown);
+    rb->storage_spindown(rb->global_settings->disk_spindown);
 
     if (slideshow_enabled)
     {
         if(jpeg_settings.ss_timeout < 10)
         {
             /* slideshow times < 10s keep disk spinning */
-            rb->ata_spindown(0);
+            rb->storage_spindown(0);
         }
         else if (!rb->mp3_is_playing())
         {
@@ -1057,7 +1057,7 @@
     else if(immediate_ata_off)
     {
         /* running slideshow and time is long enough: power down disk */
-        rb->ata_sleep();
+        rb->storage_sleep();
     }
 #endif
 
@@ -1259,7 +1259,7 @@
 
 #if !defined(SIMULATOR) && defined(HAVE_DISK_STORAGE)
     /* set back ata spindown time in case we changed it */
-    rb->ata_spindown(rb->global_settings->disk_spindown);
+    rb->storage_spindown(rb->global_settings->disk_spindown);
 #endif
 
     /* Turn on backlight timeout (revert to settings) */
diff --git a/apps/plugins/mpegplayer/disk_buf.c b/apps/plugins/mpegplayer/disk_buf.c
index 7ba4025..df5e005 100644
--- a/apps/plugins/mpegplayer/disk_buf.c
+++ b/apps/plugins/mpegplayer/disk_buf.c
@@ -171,7 +171,7 @@
         if (!stream_get_window(&sw))
         {
             disk_buf.state = TSTATE_DATA;
-            rb->ata_sleep();
+            rb->storage_sleep();
             break;
         }
 
@@ -186,7 +186,7 @@
             /* Free space is less than one page */
             disk_buf.state = TSTATE_DATA;
             disk_buf.low_wm = DISK_BUF_LOW_WATERMARK;
-            rb->ata_sleep();
+            rb->storage_sleep();
             break;
         }
 
@@ -208,7 +208,7 @@
             {
                 /* Error or end of stream */
                 disk_buf.state = TSTATE_EOS;
-                rb->ata_sleep();
+                rb->storage_sleep();
                 break;
             }
 
diff --git a/apps/plugins/mpegplayer/stream_mgr.h b/apps/plugins/mpegplayer/stream_mgr.h
index c94fa84..e3ea920 100644
--- a/apps/plugins/mpegplayer/stream_mgr.h
+++ b/apps/plugins/mpegplayer/stream_mgr.h
@@ -153,7 +153,7 @@
 static inline void stream_keep_disk_active(void)
 {
 #ifdef HAVE_DISK_STORAGE
-    rb->ata_spin();
+    rb->storage_spin();
 #endif
     }
 
diff --git a/apps/plugins/video.c b/apps/plugins/video.c
index 6a380b8..1ba2b89 100644
--- a/apps/plugins/video.c
+++ b/apps/plugins/video.c
@@ -661,7 +661,7 @@
 #endif
             )
         {
-            rb->ata_sleep(); /* no point in leaving the disk run til timeout */
+            rb->storage_sleep(); /* no point in leaving the disk run til timeout */
             gPlay.bDiskSleep = true;
         }
 
diff --git a/apps/plugins/wavplay.c b/apps/plugins/wavplay.c
index c37b656..dc0992a 100644
--- a/apps/plugins/wavplay.c
+++ b/apps/plugins/wavplay.c
@@ -3598,7 +3598,7 @@
             if (free_space <= 0)
             {
                 filling = false;
-                rb->ata_sleep();
+                rb->storage_sleep();
             }
             else
             {
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c
index da4e9b7..dbbc690 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -24,7 +24,7 @@
 #include "logf.h"
 #include "thread.h"
 #include <string.h>
-#include "ata.h"
+#include "storage.h"
 #include "usb.h"
 #include "buffer.h"
 #include "general.h"
@@ -162,7 +162,7 @@
 static int            low_watermark;   /* Low watermark to stop flush      */
 static int            high_watermark;  /* max chunk limit for data flush   */
 static unsigned long  spinup_time = 35*HZ/10;  /* Fudged spinup time       */
-static int            last_ata_spinup_time = -1;/* previous spin time used */
+static int            last_storage_spinup_time = -1;/* previous spin time used */
 #ifdef HAVE_PRIORITY_SCHEDULING
 static int            flood_watermark; /* boost thread priority when here  */
 #endif
@@ -731,7 +731,7 @@
  */
 static void pcmrec_refresh_watermarks(void)
 {
-    logf("ata spinup: %d", ata_spinup_time);
+    logf("ata spinup: %d", storage_spinup_time());
 
     /* set the low mark for when flushing stops if automatic */
     low_watermark = (LOW_SECONDS*4*sample_rate + (enc_chunk_size-1))
@@ -755,7 +755,7 @@
 
     logf("flood at: %d", flood_watermark);
 #endif
-    spinup_time = last_ata_spinup_time = ata_spinup_time;
+    spinup_time = last_storage_spinup_time = storage_spinup_time();
 
     /* write at 8s + st remaining in enc_buffer - range 12s to
        20s total - default to 3.5s spinup. */
@@ -816,7 +816,7 @@
         if (!is_recording)
             return;
 
-        if (ata_spinup_time != last_ata_spinup_time)
+        if (storage_spinup_time() != last_storage_spinup_time)
             pcmrec_refresh_watermarks();
 
         /* enough available? no? then leave */
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c
index ce0974a..422b138 100644
--- a/apps/recorder/peakmeter.c
+++ b/apps/recorder/peakmeter.c
@@ -26,7 +26,7 @@
 #include "thread.h"
 #include "kernel.h"
 #include "settings.h"
-#include "ata.h"
+#include "storage.h"
 #include "lcd.h"
 #include "scrollbar.h"
 #include "gwps.h"
@@ -1343,7 +1343,7 @@
      * is active, it must not draw too much CPU power or a buffer overrun can
      * happen when saving a recording. As a compromise, poll only once per tick
      * when the disk is active, otherwise spin around as fast as possible. */
-    bool highperf = !ata_disk_is_active();
+    bool highperf = !storage_disk_is_active();
 #endif
     bool dopeek = true;
 
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index d29db39..5a2aa09 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -65,7 +65,7 @@
 #include "errno.h"
 #include "talk.h"
 #include "sound.h"
-#include "ata.h"
+#include "storage.h"
 #include "splash.h"
 #include "screen_access.h"
 #include "action.h"
@@ -298,7 +298,7 @@
     peak_valid_mem[peak_time % 3] = *peak_l;
     if (((peak_valid_mem[0] == peak_valid_mem[1]) &&
          (peak_valid_mem[1] == peak_valid_mem[2])) &&
-        ((*peak_l < 32767) || ata_disk_is_active()))
+        ((*peak_l < 32767) || storage_disk_is_active()))
             return false;
 
     if (*peak_r > *peak_l)
@@ -1034,7 +1034,7 @@
     rec_status = RCSTAT_IN_RECSCREEN;
 
 #if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
-    ata_set_led_enabled(false);
+    storage_set_led_enabled(false);
 #endif
 
 #if CONFIG_CODEC == SWCODEC
@@ -1905,7 +1905,7 @@
         reload_directory();
 
 #if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
-    ata_set_led_enabled(true);
+    storage_set_led_enabled(true);
 #endif
 
 #if CONFIG_TUNER
diff --git a/apps/scrobbler.c b/apps/scrobbler.c
index acf1e9e..b0f6515 100644
--- a/apps/scrobbler.c
+++ b/apps/scrobbler.c
@@ -180,7 +180,7 @@
         logf("SCROBBLER: %s", scrobbler_entry.path);
     } else {
         cache_pos++;
-        register_ata_idle_func(scrobbler_flush_callback);
+        register_storage_idle_func(scrobbler_flush_callback);
     }
 
 }
diff --git a/apps/settings.c b/apps/settings.c
index 709e05e..e15bfc8 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -38,6 +38,7 @@
 #include "rtc.h"
 #include "power.h"
 #include "ata_idle_notify.h"
+#include "storage.h"
 #include "screens.h"
 #include "ctype.h"
 #include "file.h"
@@ -582,11 +583,11 @@
 {
     update_runtime();
 #ifdef HAVE_RTC_RAM
-    /* this will be done in the ata_callback if
+    /* this will be done in the storage_callback if
        target doesnt have rtc ram */
     write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
 #else
-    register_ata_idle_func(flush_global_status_callback);
+    register_storage_idle_func(flush_global_status_callback);
 #endif
 }
 
@@ -594,11 +595,11 @@
 {
     update_runtime();
 #ifdef HAVE_RTC_RAM
-    /* this will be done in the ata_callback if
+    /* this will be done in the storage_callback if
        target doesnt have rtc ram */
     write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
 #endif
-    register_ata_idle_func(flush_config_block_callback);
+    register_storage_idle_func(flush_config_block_callback);
     return 0;
 }
 
@@ -768,7 +769,7 @@
     buttonlight_set_timeout(global_settings.buttonlight_timeout);
 #endif
 #ifdef HAVE_DISK_STORAGE
-    ata_spindown(global_settings.disk_spindown);
+    storage_spindown(global_settings.disk_spindown);
 #endif
 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
     dac_line_in(global_settings.line_in);
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 7f870b4..3eeeffd 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -23,7 +23,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include "system.h"
-#include "ata.h"
+#include "storage.h"
 #include "lang.h"
 #include "talk.h"
 #include "lcd.h"
@@ -714,7 +714,7 @@
     /* disk */
 #ifdef HAVE_DISK_STORAGE
     INT_SETTING(0, disk_spindown, LANG_SPINDOWN, 5, "disk spindown",
-                    UNIT_SEC, 3, 254, 1, NULL, NULL, ata_spindown),
+                    UNIT_SEC, 3, 254, 1, NULL, NULL, storage_spindown),
 #endif /* HAVE_DISK_STORAGE */
     /* browser */
     CHOICE_SETTING(0, dirfilter, LANG_FILTER, SHOW_SUPPORTED, "show files",
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 19469cd..b6cfcd5 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -3094,7 +3094,7 @@
     if (force || command_queue_is_full())
         command_queue_sync_callback();
     else
-        register_ata_idle_func(command_queue_sync_callback);
+        register_storage_idle_func(command_queue_sync_callback);
 }
 
 static void queue_command(int cmd, long idx_id, int tag, long data)
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 7b05391..7777a9f 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -48,6 +48,7 @@
 #include "filetypes.h"
 #include "audio.h"
 #include "appevents.h"
+#include "storage.h"
 
 #define FILE_SEARCH_INSTRUCTIONS ROCKBOX_DIR "/tagnavi.config"
 
@@ -1057,7 +1058,7 @@
            otherwise show it after the normal 1/2 second delay */
         show_search_progress(
 #ifdef HAVE_DISK_STORAGE
-            ata_disk_is_active()
+            storage_disk_is_active()
 #else
             true
 #endif
diff --git a/apps/tree.c b/apps/tree.c
index 768223e..dbc47e3 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -41,7 +41,7 @@
 #include "settings.h"
 #include "status.h"
 #include "debug.h"
-#include "ata.h"
+#include "storage.h"
 #include "rolo.h"
 #include "icons.h"
 #include "lang.h"
@@ -828,7 +828,7 @@
             return GO_TO_WPS;
         if (button)
         {
-            ata_spin();
+            storage_spin();
         }
 
 
diff --git a/bootloader/creativezvm.c b/bootloader/creativezvm.c
index bd8050b..403a8bb 100644
--- a/bootloader/creativezvm.c
+++ b/bootloader/creativezvm.c
@@ -21,7 +21,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "ata-target.h"
 #include "disk.h"
 #include "font.h"
@@ -64,7 +64,7 @@
     printf("Rockbox boot loader");
     printf("Version %s", APPSVERSION);
     
-    ret = ata_init();
+    ret = storage_init();
     if(ret)
         printf("ATA error: %d", ret);
     
diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c
index 089d0f7..e1e293f 100644
--- a/bootloader/gigabeat-s.c
+++ b/bootloader/gigabeat-s.c
@@ -25,7 +25,7 @@
 #include "string.h"
 #include "adc.h"
 #include "powermgmt.h"
-#include "ata.h"
+#include "storage.h"
 #include "dir.h"
 #include "disk.h"
 #include "common.h"
@@ -81,7 +81,7 @@
         sleep(HZ/5);
 
         /* If the disk powers off, the firmware will lock at startup */
-        ata_spin();
+        storage_spin();
     }
 }
 
@@ -310,7 +310,7 @@
 
     /* Put drivers into a known state */
     button_close_device();
-    ata_close();
+    storage_close();
     system_prepare_fw_start();
 
     if (rc == EOK)
@@ -353,7 +353,7 @@
 
     check_battery();
 
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         reset_screen();
diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c
index 117dacc..6b3a68b 100644
--- a/bootloader/gigabeat.c
+++ b/bootloader/gigabeat.c
@@ -29,7 +29,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
@@ -75,7 +75,7 @@
                     (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
         lcd_update();
 
-        ata_enable(false);
+        storage_enable(false);
         sleep(HZ/20);
         usb_enable(true);
 
@@ -101,7 +101,7 @@
 
     sleep(50); /* ATA seems to error without this pause */
 
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         reset_screen();
diff --git a/bootloader/iaudio_coldfire.c b/bootloader/iaudio_coldfire.c
index 8e85dc9..0af2f25 100644
--- a/bootloader/iaudio_coldfire.c
+++ b/bootloader/iaudio_coldfire.c
@@ -30,7 +30,7 @@
 #include "lcd-remote.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "usb.h"
 #include "disk.h"
 #include "font.h"
@@ -87,10 +87,10 @@
     if (ide_powered())
     {
         /* Make sure ATA has been initialized. */
-        ata_init();
+        storage_init();
         
         /* And put the disk into sleep immediately. */
-        ata_sleepnow();
+        storage_sleepnow();
     }
 
     sleep(HZ*2);
@@ -192,7 +192,7 @@
     
     check_battery();
     
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         printf("ATA error: %d", rc);
diff --git a/bootloader/iriver_h1x0.c b/bootloader/iriver_h1x0.c
index 7f051bc..83e5455 100644
--- a/bootloader/iriver_h1x0.c
+++ b/bootloader/iriver_h1x0.c
@@ -31,7 +31,7 @@
 #include "scroll_engine.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "usb.h"
 #include "disk.h"
 #include "font.h"
@@ -148,10 +148,10 @@
     if (ide_powered())
     {
         /* Make sure ATA has been initialized. */
-        ata_init();
+        storage_init();
         
         /* And put the disk into sleep immediately. */
-        ata_sleepnow();
+        storage_sleepnow();
     }
 
     sleep(HZ*2);
@@ -560,7 +560,7 @@
         }
 #endif
         ide_power_enable(true);
-        ata_enable(false);
+        storage_enable(false);
         sleep(HZ/20);
         usb_enable(true);
         cpu_idle_mode(true);
@@ -571,7 +571,7 @@
             remote_line = 0;
             check_battery();
             
-            ata_spin(); /* Prevent the drive from spinning down */
+            storage_spin(); /* Prevent the drive from spinning down */
             sleep(HZ);
 
             /* Backlight OFF */
@@ -585,7 +585,7 @@
         lcd_update();
     }
 
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         reset_screen();
diff --git a/bootloader/iriver_h300.c b/bootloader/iriver_h300.c
index 9d839ae..d15efb9 100644
--- a/bootloader/iriver_h300.c
+++ b/bootloader/iriver_h300.c
@@ -31,7 +31,7 @@
 #include "scroll_engine.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "usb.h"
 #include "disk.h"
 #include "font.h"
@@ -93,10 +93,10 @@
     if (ide_powered())
     {
         /* Make sure ATA has been initialized. */
-        ata_init();
+        storage_init();
         
         /* And put the disk into sleep immediately. */
-        ata_sleepnow();
+        storage_sleepnow();
     }
 
     sleep(HZ*2);
@@ -317,7 +317,7 @@
         lcd_remote_update();
 
         ide_power_enable(true);
-        ata_enable(false);
+        storage_enable(false);
         sleep(HZ/20);
         usb_enable(true);
         cpu_idle_mode(true);
@@ -328,7 +328,7 @@
             remote_line = 0;
             check_battery();
             
-            ata_spin(); /* Prevent the drive from spinning down */
+            storage_spin(); /* Prevent the drive from spinning down */
             sleep(HZ);
         }
 
@@ -339,7 +339,7 @@
         lcd_update();
     }
 
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         reset_screen();
diff --git a/bootloader/main-c240wipe.c b/bootloader/main-c240wipe.c
index 1bf3ac2..952382e 100644
--- a/bootloader/main-c240wipe.c
+++ b/bootloader/main-c240wipe.c
@@ -29,7 +29,7 @@
 #include "kernel.h"
 #include "lcd.h"
 #include "font.h"
-#include "ata.h"
+#include "storage.h"
 #include "button.h"
 #include "disk.h"
 #include "crc32-mi4.h"
@@ -185,14 +185,14 @@
     printf("");
 
 
-    i=ata_init();
+    i=storage_init();
     disk_init(IF_MV(0));
 
     memset(zero,0,16*1024);
     printf("Zeroing flash");
     for(i=0;i<250816;i++)
     {
-       ata_write_sectors(IF_MV2(0,) i*32,32,zero);
+       storage_write_sectors(IF_MV2(0,) i*32,32,zero);
        if(i%64 == 0)
        {
            printf("%d kB left",(250816-i)/2);
@@ -200,13 +200,13 @@
     }
 
     printf("Writing MBR");
-    ata_write_sectors(IF_MV2(0,) 0,1,mbr);
+    storage_write_sectors(IF_MV2(0,) 0,1,mbr);
     printf("Writing FAT bootsector");
-    ata_write_sectors(IF_MV2(0,) 1023,1,fat);
+    storage_write_sectors(IF_MV2(0,) 1023,1,fat);
     printf("Writing more FAT");
-    ata_write_sectors(IF_MV2(0,) 1024,1,backupfat);
+    storage_write_sectors(IF_MV2(0,) 1024,1,backupfat);
     printf("Writing more FAT");
-    ata_write_sectors(IF_MV2(0,) 1264,1,backupfat);
+    storage_write_sectors(IF_MV2(0,) 1264,1,backupfat);
     if (button_hold())
         printf("Release Hold and");
 
diff --git a/bootloader/main-c250wipe.c b/bootloader/main-c250wipe.c
index fedabb7..06a0a5b 100644
--- a/bootloader/main-c250wipe.c
+++ b/bootloader/main-c250wipe.c
@@ -29,7 +29,7 @@
 #include "kernel.h"
 #include "lcd.h"
 #include "font.h"
-#include "ata.h"
+#include "storage.h"
 #include "button.h"
 #include "disk.h"
 #include "crc32-mi4.h"
@@ -250,14 +250,14 @@
     printf("");
 
 
-    i=ata_init();
+    i=storage_init();
     disk_init(IF_MV(0));
 
     memset(zero,0,16*1024);
     printf("Zeroing flash");
     for(i=0;i<250816;i++)
     {
-       ata_write_sectors(IF_MV2(0,) i*32,32,zero);
+       storage_write_sectors(IF_MV2(0,) i*32,32,zero);
        if(i%64 == 0)
        {
            printf("%d kB left",(250816-i)/2);
@@ -265,15 +265,15 @@
     }
 
     printf("Writing MBR");
-    ata_write_sectors(IF_MV2(0,) 0,1,mbr);
+    storage_write_sectors(IF_MV2(0,) 0,1,mbr);
     printf("Writing FAT bootsector");
-    ata_write_sectors(IF_MV2(0,) 1017,2,bootsector);
+    storage_write_sectors(IF_MV2(0,) 1017,2,bootsector);
     printf("Writing more FAT");
-    ata_write_sectors(IF_MV2(0,) 1023,1,fat);
+    storage_write_sectors(IF_MV2(0,) 1023,1,fat);
     printf("Writing more FAT");
-    ata_write_sectors(IF_MV2(0,) 1049,1,backupfat);
+    storage_write_sectors(IF_MV2(0,) 1049,1,backupfat);
     printf("Writing more FAT");
-    ata_write_sectors(IF_MV2(0,) 4920,1,backupfat);
+    storage_write_sectors(IF_MV2(0,) 4920,1,backupfat);
     if (button_hold())
         printf("Release Hold and");
 
diff --git a/bootloader/main-e200r-installer.c b/bootloader/main-e200r-installer.c
index b1209e1..3ac5743 100644
--- a/bootloader/main-e200r-installer.c
+++ b/bootloader/main-e200r-installer.c
@@ -31,7 +31,7 @@
 #include "kernel.h"
 #include "lcd.h"
 #include "font.h"
-#include "ata.h"
+#include "storage.h"
 #include "button.h"
 #include "disk.h"
 #include "crc32-mi4.h"
@@ -120,7 +120,7 @@
     printf(MODEL_NAME);
     printf("");
 
-    i=ata_init();
+    i=storage_init();
     disk_init(IF_MV(0));
     num_partitions = disk_mount_all();
 
@@ -139,7 +139,7 @@
     printf("reading: %x", (START_SECTOR_OF_ROM + ROMSECTOR_TO_HACK)*512);
 #endif
 
-    ata_read_sectors(IF_MV2(0,) 
+    storage_read_sectors(IF_MV2(0,) 
                         pinfo->start + START_SECTOR_OF_ROM + ROMSECTOR_TO_HACK,
                         1 , sector);
     crc32 = chksum_crc32 (sector, 512);
@@ -161,7 +161,7 @@
         /* E200R bootloader detected - patch it */
         memcpy(&sector[HACK_OFFSET], changedBytes,
                 sizeof(changedBytes)/sizeof(*changedBytes));
-        ata_write_sectors(IF_MV2(0,) 
+        storage_write_sectors(IF_MV2(0,) 
                         pinfo->start + START_SECTOR_OF_ROM + ROMSECTOR_TO_HACK,
                         1 , sector);
         printf("Firmware unlocked");
diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c
index c1aad5c..09e1c23 100644
--- a/bootloader/main-pp.c
+++ b/bootloader/main-pp.c
@@ -30,7 +30,7 @@
 #include "kernel.h"
 #include "lcd.h"
 #include "font.h"
-#include "ata.h"
+#include "storage.h"
 #include "adc.h"
 #include "button.h"
 #include "disk.h"
@@ -371,7 +371,7 @@
     unsigned long sum;
     
     /* Read header to find out how long the mi4 file is. */
-    ata_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET,
+    storage_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET,
                             PPMI_SECTORS, &ppmi_header);
     
     /* The first four characters at 0x80000 (sector 1024) should be PPMI*/
@@ -381,7 +381,7 @@
     printf("BL mi4 size: %x", ppmi_header.length);
     
     /* Read mi4 header of the OF */
-    ata_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS 
+    storage_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS 
                        + (ppmi_header.length/512), MI4_HEADER_SECTORS, &mi4header);
     
     /* We don't support encrypted mi4 files yet */
@@ -404,7 +404,7 @@
     printf("Binary type: %.4s", mi4header.type);
 
     /* Load firmware */
-    ata_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS
+    storage_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS
                         + (ppmi_header.length/512) + MI4_HEADER_SECTORS,
                         (mi4header.mi4size-MI4_HEADER_SIZE)/512, buf);
 
@@ -423,9 +423,9 @@
         
         printf("Disabling database rebuild");
         
-        ata_read_sectors(IF_MV2(0,) pinfo->start + 0x3c08, 1, block);
+        storage_read_sectors(IF_MV2(0,) pinfo->start + 0x3c08, 1, block);
         block[0xe1] = 0;
-        ata_write_sectors(IF_MV2(0,) pinfo->start + 0x3c08, 1, block);
+        storage_write_sectors(IF_MV2(0,) pinfo->start + 0x3c08, 1, block);
     }
 #else
     (void) disable_rebuild;
@@ -505,7 +505,7 @@
     printf("Version: %s", version);
     printf(MODEL_NAME);
 
-    i=ata_init();
+    i=storage_init();
 #if !(CONFIG_STORAGE & STORAGE_SD)
     if (i==0) {
         identify_info=ata_get_identify();
@@ -601,7 +601,7 @@
                 {
                     printf("dumping sector %d", i);
                 }
-                ata_read_sectors(IF_MV2(0,) pinfo->start + i, 1, sector);
+                storage_read_sectors(IF_MV2(0,) pinfo->start + i, 1, sector);
                 write(fd,sector,512);
             }
             close(fd);
diff --git a/bootloader/meizu_m3.c b/bootloader/meizu_m3.c
index acd07d7..940e7ea 100644
--- a/bootloader/meizu_m3.c
+++ b/bootloader/meizu_m3.c
@@ -29,7 +29,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
diff --git a/bootloader/meizu_m6sl.c b/bootloader/meizu_m6sl.c
index 86c4c57..0b335be 100644
--- a/bootloader/meizu_m6sl.c
+++ b/bootloader/meizu_m6sl.c
@@ -29,7 +29,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
diff --git a/bootloader/meizu_m6sp.c b/bootloader/meizu_m6sp.c
index 7608c9b..63ade2d 100644
--- a/bootloader/meizu_m6sp.c
+++ b/bootloader/meizu_m6sp.c
@@ -29,7 +29,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
diff --git a/bootloader/mrobe500.c b/bootloader/mrobe500.c
index 8389d11..f92ff4b 100644
--- a/bootloader/mrobe500.c
+++ b/bootloader/mrobe500.c
@@ -26,7 +26,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
@@ -229,13 +229,13 @@
         lcd_update();
 
         ide_power_enable(true);
-        ata_enable(false);
+        storage_enable(false);
         sleep(HZ/20);
         usb_enable(true);
 
         while (usb_detect() == USB_INSERTED)
         {
-            ata_spin(); /* Prevent the drive from spinning down */
+            storage_spin(); /* Prevent the drive from spinning down */
             sleep(HZ);
         }
 
@@ -248,7 +248,7 @@
     mrdebug();
 #endif
     printf("ATA");
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         reset_screen();
diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c
index d8fefd4..13c537b 100644
--- a/bootloader/ondavx747.c
+++ b/bootloader/ondavx747.c
@@ -54,7 +54,7 @@
     
     backlight_init();
     
-    ata_init();
+    storage_init();
 
     int touch, btn;
     char datetime[30];
diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c
index df6f789..aa4d6a9 100644
--- a/bootloader/sansa_as3525.c
+++ b/bootloader/sansa_as3525.c
@@ -30,7 +30,7 @@
 #include "backlight-target.h"
 #include "as3525-codec.h"
 #include "common.h"
-#include "ata.h"
+#include "storage.h"
 
 int show_logo(void);
 void main(void)
@@ -54,7 +54,7 @@
     }
     printf("ID: %02X%02X%02X%02X%02X%02X%02X%02X", buf[7], buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
 
-    ata_init();
+    storage_init();
 
 #ifdef SANSA_CLIP
     /* Use hardware scrolling */
diff --git a/bootloader/telechips.c b/bootloader/telechips.c
index 7e00e52..4d64532 100644
--- a/bootloader/telechips.c
+++ b/bootloader/telechips.c
@@ -30,7 +30,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
@@ -206,7 +206,7 @@
     printf("Version %s", version);
 
     printf("ATA");
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
         reset_screen();
diff --git a/bootloader/tpj1022.c b/bootloader/tpj1022.c
index 62929cf..aaf6e9f 100644
--- a/bootloader/tpj1022.c
+++ b/bootloader/tpj1022.c
@@ -30,7 +30,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "font.h"
@@ -58,7 +58,7 @@
     printf("Hello World!");
 #endif
 
-    i=ata_init();
+    i=storage_init();
 
     disk_init();
     rc = disk_mount_all();
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 724f092..3bdf089 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -108,6 +108,7 @@
 
 
 /* Storage */
+storage.c
 #ifndef SIMULATOR
 #if (CONFIG_STORAGE & STORAGE_MMC)
 drivers/ata_mmc.c
diff --git a/firmware/ata_idle_notify.c b/firmware/ata_idle_notify.c
index 3dde52f..99b1d4d 100644
--- a/firmware/ata_idle_notify.c
+++ b/firmware/ata_idle_notify.c
@@ -25,9 +25,9 @@
 #include "kernel.h"
 #include "string.h"
 
-void register_ata_idle_func(ata_idle_notify function)
+void register_storage_idle_func(storage_idle_notify function)
 {
-#if USING_ATA_CALLBACK
+#if USING_STORAGE_CALLBACK
     add_event(DISK_EVENT_SPINUP, true, function);
 #else
     function(); /* just call the function now */
@@ -37,8 +37,8 @@
 #endif
 }
 
-#if USING_ATA_CALLBACK
-void unregister_ata_idle_func(ata_idle_notify func, bool run)
+#if USING_STORAGE_CALLBACK
+void unregister_storage_idle_func(storage_idle_notify func, bool run)
 {
     remove_event(DISK_EVENT_SPINUP, func);
     
@@ -46,7 +46,7 @@
         func();
 }
 
-bool call_ata_idle_notifys(bool force)
+bool call_storage_idle_notifys(bool force)
 {
     static int lock_until = 0;
 
diff --git a/firmware/common/disk.c b/firmware/common/disk.c
index 4add5b9..32b15b8 100644
--- a/firmware/common/disk.c
+++ b/firmware/common/disk.c
@@ -19,7 +19,7 @@
  *
  ****************************************************************************/
 #include <stdio.h>
-#include "ata.h"
+#include "storage.h"
 #include "debug.h"
 #include "fat.h"
 #ifdef HAVE_HOTSWAP
@@ -80,7 +80,7 @@
     struct partinfo* pinfo = part;
 #endif
 
-    ata_read_sectors(IF_MV2(drive,) 0,1, &sector);
+    storage_read_sectors(IF_MV2(drive,) 0,1, &sector);
     /* check that the boot sector is initialized */
     if ( (sector[510] != 0x55) ||
          (sector[511] != 0xaa)) {
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index b80f615..c2882a5 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -32,6 +32,7 @@
 #include "string.h"
 #include "ata_idle_notify.h"
 #include "ata-target.h"
+#include "storage.h"
 
 #define SECTOR_SIZE     (512)
 
@@ -148,7 +149,7 @@
 static struct mutex ata_mtx SHAREDBSS_ATTR;
 static int ata_device; /* device 0 (master) or 1 (slave) */
 
-int ata_spinup_time = 0;
+static int spinup_time = 0;
 #if (CONFIG_LED == LED_REAL)
 static bool ata_led_enabled = true;
 static bool ata_led_on = false;
@@ -166,7 +167,7 @@
 static bool initialized = false;
 
 static long last_user_activity = -1;
-long last_disk_activity = -1;
+static long last_disk_activity = -1;
 
 static unsigned long total_sectors;
 static int multisectors; /* number of supported multisectors */
@@ -407,7 +408,7 @@
             }
 
             if (spinup) {
-                ata_spinup_time = current_tick - spinup_start;
+                spinup_time = current_tick - spinup_start;
                 spinup = false;
                 sleeping = false;
                 poweroff = false;
@@ -584,7 +585,7 @@
         }
 
         if (spinup) {
-            ata_spinup_time = current_tick - spinup_start;
+            spinup_time = current_tick - spinup_start;
             spinup = false;
             sleeping = false;
             poweroff = false;
@@ -873,7 +874,7 @@
 {
     if (!spinup && !sleeping && !ata_mtx.locked && initialized)
     {
-        call_ata_idle_notifys(false);
+        call_storage_idle_notifys(false);
         ata_perform_sleep();
     }
 }
@@ -908,7 +909,7 @@
 #ifdef ALLOW_USB_SPINDOWN
                             if(!usb_mode)
 #endif
-                                call_ata_idle_notifys(false);
+                                call_storage_idle_notifys(false);
                             last_seen_mtx_unlock = 0;
                         }
                     }
@@ -921,7 +922,7 @@
 #ifdef ALLOW_USB_SPINDOWN
                         if(!usb_mode)
 #endif
-                            call_ata_idle_notifys(true);
+                            call_storage_idle_notifys(true);
                         ata_perform_sleep();
                         last_sleep = current_tick;
                     }
@@ -974,7 +975,7 @@
 #ifdef ALLOW_USB_SPINDOWN
                 if(!usb_mode)
 #endif
-                    call_ata_idle_notifys(false);
+                    call_storage_idle_notifys(false);
                 last_disk_activity = current_tick - sleep_timeout + (HZ/2);
                 break;
 
@@ -1391,3 +1392,43 @@
         led(false);
 }
 #endif
+
+long ata_last_disk_activity(void)
+{
+    return last_disk_activity;
+}
+
+int ata_spinup_time(void)
+{
+    return spinup_time;
+}
+
+void ata_get_info(struct storage_info *info)
+{
+    unsigned short *src,*dest;
+    static char vendor[8];
+    static char product[16];
+    static char revision[4];
+    int i;
+    info->sector_size = SECTOR_SIZE;
+    info->num_sectors= ((unsigned long)identify_info[61] << 16 | \
+                 (unsigned long)identify_info[60]);
+
+    src = (unsigned short*)&identify_info[27];
+    dest = (unsigned short*)vendor;
+    for (i=0;i<4;i++)
+        dest[i] = htobe16(src[i]);
+    info->vendor=vendor;
+
+    src = (unsigned short*)&identify_info[31];
+    dest = (unsigned short*)product;
+    for (i=0;i<8;i++)
+        dest[i] = htobe16(src[i]);
+    info->product=product;
+
+    src = (unsigned short*)&identify_info[23];
+    dest = (unsigned short*)revision;
+    for (i=0;i<2;i++)
+        dest[i] = htobe16(src[i]);
+    info->revision=revision;
+}
diff --git a/firmware/drivers/ata_flash.c b/firmware/drivers/ata_flash.c
index d77e056..9b1b641 100644
--- a/firmware/drivers/ata_flash.c
+++ b/firmware/drivers/ata_flash.c
@@ -19,7 +19,7 @@
  *
  ****************************************************************************/
 
-#include "ata.h"
+#include "storage.h"
 #include <stdbool.h>
 #include <string.h>
 
@@ -42,8 +42,6 @@
 
 #define SECTOR_SIZE     (512)
 
-static unsigned short identify_info[SECTOR_SIZE];
-int ata_spinup_time = 0;
 long last_disk_activity = -1;
 
 #if CONFIG_FLASH == FLASH_IFP7XX
@@ -386,7 +384,7 @@
     return done;
 }
 
-int ata_read_sectors(IF_MV2(int drive,)
+int nand_read_sectors(IF_MV2(int drive,)
                      unsigned long start,
                      int incount,
                      void* inbuf)
@@ -403,7 +401,7 @@
     return 0;
 }
 
-int ata_write_sectors(IF_MV2(int drive,)
+int nand_write_sectors(IF_MV2(int drive,)
                       unsigned long start,
                       int count,
                       const void* buf)
@@ -414,60 +412,7 @@
     return -1;
 }
 
-/* schedule a single sector write, executed with the the next spinup 
-   (volume 0 only, used for config sector) */
-extern void ata_delayed_write(unsigned long sector, const void* buf)
-{
-    (void)sector;
-    (void)buf;
-}
-
-/* write the delayed sector to volume 0 */
-extern void ata_flush(void)
-{
-
-}
-
-void ata_spindown(int seconds)
-{
-    (void)seconds;
-}
-
-bool ata_disk_is_active(void)
-{
-  return 0;
-}
-
-void ata_sleep(void)
-{
-}
-
-void ata_spin(void)
-{
-}
-
-/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
-int ata_hard_reset(void)
-{
-  return 0;
-}
-
-int ata_soft_reset(void)
-{
-  return 0;
-}
-
-void ata_enable(bool on)
-{
-    (void)on;
-}
-
-unsigned short* ata_get_identify(void)
-{
-    return identify_info;
-}
-
-int ata_init(void)
+int nand_init(void)
 {
     int i, id, id2;
 
@@ -499,3 +444,29 @@
 
     return 0;
 }
+
+long nand_last_disk_activity(void)
+{
+    return last_disk_activity;
+}
+
+void nand_get_info(struct storage_info *info)
+{
+    unsigned long blocks;
+    int i;
+
+    /* firmware version */
+    info->revision="0.00";
+
+    /* vendor field, need better name? */
+    info->vendor="Rockbox";
+    /* model field, need better name? */
+    info->product="TNFL";
+
+    /* blocks count */
+    info->num_sectors = 0;
+    info->sector_size=SECTOR_SIZE;
+
+    info->serial=0;
+}
+
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index 1040ab0..953bb90 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -19,7 +19,7 @@
  *
  ****************************************************************************/
 #include <stdbool.h>
-#include "ata.h"
+#include "mmc.h"
 #include "ata_mmc.h"
 #include "ata_idle_notify.h"
 #include "kernel.h"
@@ -36,6 +36,7 @@
 #include "adc.h"
 #include "bitswap.h"
 #include "disk.h" /* for mount/unmount */
+#include "storage.h"
 
 #define BLOCK_SIZE  512   /* fixed */
 
@@ -84,8 +85,7 @@
 #define DT_STOP_TRAN                 0xfd
 
 /* for compatibility */
-int ata_spinup_time = 0;
-long last_disk_activity = -1;
+static long last_disk_activity = -1;
 
 /* private variables */
 
@@ -601,7 +601,7 @@
     return rc;
 }
 
-int ata_read_sectors(IF_MV2(int drive,)
+int mmc_read_sectors(IF_MV2(int drive,)
                      unsigned long start,
                      int incount,
                      void* inbuf)
@@ -687,7 +687,7 @@
     return rc;
 }
 
-int ata_write_sectors(IF_MV2(int drive,)
+int mmc_write_sectors(IF_MV2(int drive,)
                       unsigned long start,
                       int count,
                       const void* buf)
@@ -755,25 +755,12 @@
     return rc;
 }
 
-void ata_spindown(int seconds)
-{
-    (void)seconds;
-}
-
-bool ata_disk_is_active(void)
+bool mmc_disk_is_active(void)
 {
     /* this is correct unless early return from write gets implemented */
     return mmc_mutex.locked;
 }
 
-void ata_sleep(void)
-{
-}
-
-void ata_spin(void)
-{
-}
-
 static void mmc_thread(void)
 {
     struct queue_event ev;
@@ -810,7 +797,7 @@
                 {
                     if (!idle_notified)
                     {
-                        call_ata_idle_notifys(false);
+                        call_storage_idle_notifys(false);
                         idle_notified = true;
                     }
                 }
@@ -904,12 +891,7 @@
     }
 }
 
-int ata_soft_reset(void)
-{
-    return 0;
-}
-
-void ata_enable(bool on)
+void mmc_enable(bool on)
 {
     PBCR1 &= ~0x0CF0;      /* PB13, PB11 and PB10 become GPIO,
                             * if not modified below */
@@ -924,7 +906,7 @@
     card_info[1].initialized = false;
 }
 
-int ata_init(void)
+int mmc_init(void)
 {
     int rc = 0;
 
@@ -970,9 +952,51 @@
         tick_add_task(mmc_tick);
         initialized = true;
     }
-    ata_enable(true);
+    mmc_enable(true);
 
     mutex_unlock(&mmc_mutex);
     return rc;
 }
 
+long mmc_last_disk_activity(void)
+{
+    return last_disk_activity;
+}
+
+void mmc_get_info(IF_MV2(int drive,) struct storage_info *info)
+{
+#ifndef HAVE_MULTIVOLUME
+    const int drive=0;
+#endif
+    info->sector_size=card_info[drive].blocksize;
+    info->num_sectors=card_info[drive].numblocks;
+    info->vendor="Rockbox";
+    if(drive==0)
+    {
+        info->product="Internal Storage";
+    }
+    else
+    {
+        info->product="MMC Card Slot";
+    }
+    info->revision="0.00";
+}
+
+#ifdef HAVE_HOTSWAP
+bool mmc_removable(IF_MV_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIVOLUME
+    const int drive=0;
+#endif
+    return (drive==1);
+}
+
+bool mmc_present(IF_MV_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIVOLUME
+    const int drive=0;
+#endif
+    return (card_info[drive].initialized && card_info[drive].numblocks > 0);
+}
+#endif
+
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 90be93f..4317b70 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -24,7 +24,7 @@
 #include <ctype.h>
 #include <stdbool.h>
 #include "fat.h"
-#include "ata.h"
+#include "storage.h"
 #include "debug.h"
 #include "panic.h"
 #include "system.h"
@@ -300,7 +300,7 @@
 #endif
 
     /* Read the sector */
-    rc = ata_read_sectors(IF_MV2(drive,) startsector,1,buf);
+    rc = storage_read_sectors(IF_MV2(drive,) startsector,1,buf);
     if(rc)
     {
         DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc);
@@ -422,7 +422,7 @@
 #endif /* #ifdef HAVE_FAT16SUPPORT */
     {
         /* Read the fsinfo sector */
-        rc = ata_read_sectors(IF_MV2(drive,) 
+        rc = storage_read_sectors(IF_MV2(drive,) 
             startsector + fat_bpb->bpb_fsinfo, 1, buf);
         if (rc < 0)
         {
@@ -597,7 +597,7 @@
 #endif
 
     /* Write to the first FAT */
-    rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,)
+    rc = storage_write_sectors(IF_MV2(fce->fat_vol->drive,)
                            secnum, 1,
                            sectorbuf);
     if(rc < 0)
@@ -618,7 +618,7 @@
 #else
         secnum += fat_bpbs[0].fatsize;
 #endif
-        rc = ata_write_sectors(IF_MV2(fce->fat_vol->drive,)
+        rc = storage_write_sectors(IF_MV2(fce->fat_vol->drive,)
                                secnum, 1, sectorbuf);
         if(rc < 0)
         {
@@ -664,7 +664,7 @@
     /* Load the sector if it is not cached */
     if(!fce->inuse)
     {
-        rc = ata_read_sectors(IF_MV2(fat_bpb->drive,)
+        rc = storage_read_sectors(IF_MV2(fat_bpb->drive,)
                               secnum + fat_bpb->startsector,1,
                               sectorbuf);
         if(rc < 0)
@@ -923,7 +923,7 @@
 #endif /* #ifdef HAVE_FAT16SUPPORT */
 
     /* update fsinfo */
-    rc = ata_read_sectors(IF_MV2(fat_bpb->drive,) 
+    rc = storage_read_sectors(IF_MV2(fat_bpb->drive,) 
                           fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo);
     if (rc < 0)
     {
@@ -936,7 +936,7 @@
     intptr = (long*)&(fsinfo[FSINFO_NEXTFREE]);
     *intptr = htole32(fat_bpb->fsinfo.nextfree);
 
-    rc = ata_write_sectors(IF_MV2(fat_bpb->drive,)
+    rc = storage_write_sectors(IF_MV2(fat_bpb->drive,)
                            fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo);
     if (rc < 0)
     {
@@ -2077,11 +2077,11 @@
         if (start + count > fat_bpb->totalsectors)
             panicf("Write %ld after data\n",
                 start + count - fat_bpb->totalsectors);
-        rc = ata_write_sectors(IF_MV2(fat_bpb->drive,)
+        rc = storage_write_sectors(IF_MV2(fat_bpb->drive,)
                                start + fat_bpb->startsector, count, buf);
     }
     else
-        rc = ata_read_sectors(IF_MV2(fat_bpb->drive,)
+        rc = storage_read_sectors(IF_MV2(fat_bpb->drive,)
                               start + fat_bpb->startsector, count, buf);
     if (rc < 0) {
         DEBUGF( "transfer() - Couldn't %s sector %lx"
diff --git a/firmware/export/ata.h b/firmware/export/ata.h
index 164261a..f09a463 100644
--- a/firmware/export/ata.h
+++ b/firmware/export/ata.h
@@ -23,43 +23,40 @@
 
 #include <stdbool.h>
 #include "config.h" /* for HAVE_MULTIVOLUME or not */
+#include "mv.h" /* for IF_MV() and friends */
 
-/* FixMe: These macros are a bit nasty and perhaps misplaced here.
-   We'll get rid of them once decided on how to proceed with multivolume. */
-#ifdef HAVE_MULTIVOLUME
-#define IF_MV(x) x /* optional volume/drive parameter */
-#define IF_MV2(x,y) x,y /* same, for a list of arguments */
-#define IF_MV_NONVOID(x) x /* for prototype with sole volume parameter */
-#define NUM_VOLUMES 2
-#else /* empty definitions if no multi-volume */
-#define IF_MV(x)
-#define IF_MV2(x,y)
-#define IF_MV_NONVOID(x) void
-#define NUM_VOLUMES 1
-#endif
+struct storage_info;
 
-extern void ata_enable(bool on);
-extern void ata_spindown(int seconds);
-extern void ata_sleep(void);
-extern void ata_sleepnow(void);
+void ata_enable(bool on);
+void ata_spindown(int seconds);
+void ata_sleep(void);
+void ata_sleepnow(void);
 /* NOTE: DO NOT use this to poll for disk activity.
          If you are waiting for the disk to become active before
          doing something use ata_idle_notify.h
  */
-extern bool ata_disk_is_active(void);
-extern int ata_hard_reset(void);
-extern int ata_soft_reset(void);
-extern int ata_init(void);
-extern void ata_close(void);
-extern int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf);
-extern int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf);
-extern void ata_spin(void);
+bool ata_disk_is_active(void);
+int ata_hard_reset(void);
+int ata_soft_reset(void);
+int ata_init(void);
+void ata_close(void);
+int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf);
+int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf);
+void ata_spin(void);
 #if (CONFIG_LED == LED_REAL)
-extern void ata_set_led_enabled(bool enabled);
+void ata_set_led_enabled(bool enabled);
 #endif
-extern unsigned short* ata_get_identify(void);
+unsigned short* ata_get_identify(void);
+void ata_get_info(IF_MV2(int drive,) struct storage_info *info);
+#ifdef HAVE_HOTSWAP
+bool ata_removable(IF_MV_NONVOID(int drive));
+bool ata_present(IF_MV_NONVOID(int drive));
+#endif
 
-extern long last_disk_activity;
-extern int ata_spinup_time; /* ticks */
+
+
+long ata_last_disk_activity(void);
+int ata_spinup_time(void); /* ticks */
+
 
 #endif
diff --git a/firmware/export/ata_idle_notify.h b/firmware/export/ata_idle_notify.h
index aea2c92..ceba2ee 100644
--- a/firmware/export/ata_idle_notify.h
+++ b/firmware/export/ata_idle_notify.h
@@ -26,15 +26,15 @@
 #include "events.h"
 
 /*
-        NOTE: ata_idle_notify usage notes..
+        NOTE: storage_idle_notify usage notes..
         
 1) The callbacks are called in the ata thread, not main/your thread.
 2) Asynchronous callbacks (like the buffer refill) should be avoided.
-    If you must use an async callback, remember to check ata_is_active() before
+    If you must use an async callback, remember to check storage_is_active() before
     accessing the disk, and do not call any functions between that check and the
     disk access which may cause a yield (lcd_update() does this!).
 3) Do not call any yielding functions in the callback.
-4) Do not call ata_sleep in the callbacks.
+4) Do not call storage_sleep in the callbacks.
 5) Don't Panic!
 
 */
@@ -43,21 +43,21 @@
     DISK_EVENT_SPINUP = (EVENT_CLASS_DISK|1),
 };
 
-#define USING_ATA_CALLBACK  !defined(SIMULATOR)             \
+#define USING_STORAGE_CALLBACK  !defined(SIMULATOR)             \
                             && ! ((CONFIG_STORAGE & STORAGE_NAND) \
                                && (CONFIG_NAND & NAND_IFP7XX)) \
                             && !defined(BOOTLOADER)
 
-typedef bool (*ata_idle_notify)(void);
+typedef bool (*storage_idle_notify)(void);
 
-extern void register_ata_idle_func(ata_idle_notify function);
-#if USING_ATA_CALLBACK
-extern void unregister_ata_idle_func(ata_idle_notify function, bool run);
-extern bool call_ata_idle_notifys(bool force);
+extern void register_storage_idle_func(storage_idle_notify function);
+#if USING_STORAGE_CALLBACK
+extern void unregister_storage_idle_func(storage_idle_notify function, bool run);
+extern bool call_storage_idle_notifys(bool force);
 #else
-#define unregister_ata_idle_func(f,r)
-#define call_ata_idle_notifys(f)
-#define ata_idle_notify_init(s)
+#define unregister_storage_idle_func(f,r)
+#define call_storage_idle_notifys(f)
+#define storage_idle_notify_init(s)
 #endif
 
 #endif /* __ATACALLBACK_H__ */
diff --git a/firmware/export/disk.h b/firmware/export/disk.h
index 8d440be..cec9bfa 100644
--- a/firmware/export/disk.h
+++ b/firmware/export/disk.h
@@ -21,7 +21,7 @@
 #ifndef _DISK_H_
 #define _DISK_H_
 
-#include "ata.h" /* for volume definitions */
+#include "mv.h" /* for volume definitions */
 
 struct partinfo {
     unsigned long start; /* first sector (LBA) */
diff --git a/firmware/export/fat.h b/firmware/export/fat.h
index 0e83ca8..c99a1a7 100644
--- a/firmware/export/fat.h
+++ b/firmware/export/fat.h
@@ -23,7 +23,7 @@
 #define FAT_H
 
 #include <stdbool.h>
-#include "ata.h" /* for volume definitions */
+#include "mv.h" /* for volume definitions */
 #include "config.h"
 
 #define SECTOR_SIZE 512
diff --git a/firmware/export/nand_id.h b/firmware/export/nand_id.h
index a47a38e..188b6c1 100644
--- a/firmware/export/nand_id.h
+++ b/firmware/export/nand_id.h
@@ -5,7 +5,7 @@
  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  *                     \/            \/     \/    \/            \/
- * $Id: ata.h 17847 2008-06-28 18:10:04Z bagder $
+ * $Id: $
  *
  * Copyright (C) 2002 by Alan Korr
  *
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 6e0c03c..6f0c37b 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -29,7 +29,7 @@
 #include "adc.h"
 #include "string.h"
 #include "sprintf.h"
-#include "ata.h"
+#include "storage.h"
 #include "power.h"
 #include "button.h"
 #include "audio.h"
@@ -451,7 +451,7 @@
          !sleeptimer_active)))
     {
         if(TIME_AFTER(current_tick, last_event_tick    + timeout) &&
-           TIME_AFTER(current_tick, last_disk_activity + timeout))
+           TIME_AFTER(current_tick, storage_last_disk_activity() + timeout))
         {
             sys_poweroff();
         }
@@ -579,7 +579,7 @@
 
 static inline void charging_algorithm_small_step(void)
 {
-    if (ata_disk_is_active()) {
+    if (storage_disk_is_active()) {
         /* flag hdd use for charging calculation */
         disk_activity_last_cycle = true;
     }
@@ -589,7 +589,7 @@
      * If we have a lot of pending writes or if the disk is spining,
      * fsync the debug log file.
      */
-    if((wrcount > 10) || ((wrcount > 0) && ata_disk_is_active())) {
+    if((wrcount > 10) || ((wrcount > 0) && storage_disk_is_active())) {
         fsync(fd);
         wrcount = 0;
     }
@@ -1014,7 +1014,7 @@
          * the disk is spinning unless we are in USB mode (the disk will most
          * likely always be spinning in USB mode).
          */
-        if (!ata_disk_is_active() || usb_inserted()) {
+        if (!storage_disk_is_active() || usb_inserted()) {
             avgbat += battery_adc_voltage() - (avgbat / BATT_AVE_SAMPLES);
             /*
              * battery_millivolts is the millivolt-scaled filtered battery value.
@@ -1152,10 +1152,10 @@
 #ifdef HAVE_LCD_BITMAP
         glyph_cache_save();
 #endif
-        if(ata_disk_is_active())
-            ata_spindown(1);
+        if(storage_disk_is_active())
+            storage_spindown(1);
     }
-    while(ata_disk_is_active())
+    while(storage_disk_is_active())
         sleep(HZ/10);
 
 #if CONFIG_CODEC != SWCODEC
@@ -1166,7 +1166,7 @@
 
     /* If HD is still active we try to wait for spindown, otherwise the
        shutdown_timeout in power_thread_sleep will force a power off */
-    while(ata_disk_is_active())
+    while(storage_disk_is_active())
         sleep(HZ/10);
 #ifndef IAUDIO_X5
     lcd_set_contrast(0);
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index 1c13565..4276c10 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -18,7 +18,7 @@
  * KIND, either express or implied.
  *
  ****************************************************************************/
-#include "ata.h"
+#include "nand.h"
 #include "ata-nand-target.h"
 #include "system.h"
 #include <string.h>
@@ -31,6 +31,7 @@
 #include "lcd.h"
 #include "font.h"
 #include "button.h"
+#include "storage.h"
 #include <sprintf.h>
 
 #define SECTOR_SIZE 512
@@ -43,9 +44,6 @@
 
 long last_disk_activity = -1;
 
-/* as we aren't actually ata manually fill some fields */
-static unsigned short ata_identify[SECTOR_SIZE/2];
-
 /** static, private data **/
 static bool initialized = false;
 
@@ -662,7 +660,7 @@
 }
 
 
-int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
+int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
                      void* inbuf)
 {
 #ifdef HAVE_MULTIVOLUME
@@ -702,7 +700,7 @@
     return 0;
 }
 
-int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
+int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
                       const void* outbuf)
 {
 #ifdef HAVE_MULTIVOLUME
@@ -716,83 +714,21 @@
     return -1;
 }
 
-void ata_spindown(int seconds)
+void nand_get_info(struct storage_info *info)
 {
-    /* null */
-    (void)seconds;
-}
-
-bool ata_disk_is_active(void)
-{
-    /* null */
-    return 0;
-}
-
-void ata_sleep(void)
-{
-    /* null */
-}
-
-void ata_spin(void)
-{
-    /* null */
-}
-
-/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
-int ata_hard_reset(void)
-{
-    /* null */
-    return 0;
-}
-
-int ata_soft_reset(void)
-{
-    /* null */
-    return 0;
-}
-
-void ata_enable(bool on)
-{
-    /* null - flash controller is enabled/disabled as needed. */
-    (void)on;
-}
-
-static void fill_identify(void)
-{
-    char buf[80];
-    unsigned short *wbuf = (unsigned short *) buf;
-    unsigned long blocks;
-    int i;
-
-    memset(ata_identify, 0, sizeof(ata_identify));
-
     /* firmware version */
-    memset(buf, ' ', 8);
-    memcpy(buf, "0.00", 4);
+    info->revision="0.00";
 
-    for (i = 0; i < 4; i++)
-        ata_identify[23 + i] = betoh16(wbuf[i]);
-
-    /* model field, need better name? */
-    memset(buf, ' ', 80);
-    memcpy(buf, "TNFL", 4);
-
-    for (i = 0; i < 40; i++)
-        ata_identify[27 + i] = betoh16(wbuf[i]);
+    info->vendor="Rockbox";
+    info->product="Internal Storage";
 
     /* blocks count */
-    blocks = (pages_per_block * blocks_per_bank / SECTOR_SIZE)
-                 * page_size * total_banks;
-    ata_identify[60] = blocks & 0xffff;
-    ata_identify[61] = blocks >> 16;
-
-    /* TODO: discover where is s/n in TNFL */
-    for (i = 10; i < 20; i++) {
-        ata_identify[i] = 0;
-    }
+    info->num_sectors = (pages_per_block * blocks_per_bank / SECTOR_SIZE)
+                        * page_size * total_banks;
+    info->sector_size=SECTOR_SIZE;
 }
 
-int ata_init(void)
+int nand_init(void)
 {
     int i, bank, phys_segment;
     unsigned char spare_buf[16];
@@ -909,13 +845,12 @@
     }
 #endif
     
-    fill_identify();
     initialized = true;
 
     return 0;
 }
 
-unsigned short* ata_get_identify(void)
+long nand_last_disk_activity(void)
 {
-    return ata_identify;
+    return last_disk_activity;
 }
diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c
index b15b363..a12aafc 100644
--- a/firmware/target/arm/ata-sd-pp.c
+++ b/firmware/target/arm/ata-sd-pp.c
@@ -30,6 +30,8 @@
 #include "cpu.h"
 #include "panic.h"
 #include "usb.h"
+#include "sd.h"
+#include "storage.h"
 
 #define BLOCK_SIZE      512
 #define SECTOR_SIZE     512
@@ -128,15 +130,13 @@
 
 /** global, exported variables **/
 #ifdef HAVE_MULTIVOLUME
-#define NUM_VOLUMES 2
+#define NUM_DRIVES 2
 #else
-#define NUM_VOLUMES 1
+#define NUM_DRIVES 1
 #endif
 
 /* for compatibility */
-int ata_spinup_time = 0;
-
-long last_disk_activity = -1;
+static long last_disk_activity = -1;
 
 /** static, private data **/ 
 static bool initialized = false;
@@ -153,7 +153,7 @@
     int retry_max;
 };
 
-static struct sd_card_status sd_status[NUM_VOLUMES] =
+static struct sd_card_status sd_status[NUM_DRIVES] =
 {
     { 0, 1  },
 #ifdef HAVE_MULTIVOLUME
@@ -786,12 +786,12 @@
 
 /* API Functions */
 
-static void ata_led(bool onoff)
+static void sd_led(bool onoff)
 {
     led(onoff);
 }
 
-int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
+int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
                      void* inbuf)
 {
 #ifndef HAVE_MULTIVOLUME
@@ -805,14 +805,14 @@
 
     mutex_lock(&sd_mtx);
 
-    ata_led(true);
+    sd_led(true);
 
-ata_read_retry:
+sd_read_retry:
     if (drive != 0 && !card_detect_target())
     {
         /* no external sd-card inserted */
         ret = -EC_NOCARD;
-        goto ata_read_error;
+        goto sd_read_error;
     }
 
     sd_select_device(drive);
@@ -820,7 +820,7 @@
     if (currcard->initialized < 0)
     {
         ret = currcard->initialized;
-        goto ata_read_error;
+        goto sd_read_error;
     }
 
     last_disk_activity = current_tick;
@@ -834,7 +834,7 @@
         {
             ret = sd_select_bank(bank);
             if (ret < 0)
-                goto ata_read_error;
+                goto sd_read_error;
         }
     
         start -= bank * BLOCKS_PER_BANK;
@@ -842,7 +842,7 @@
 
     ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY);
     if (ret < 0)
-        goto ata_read_error;
+        goto sd_read_error;
 
     BLOCK_COUNT_REG = incount;
 
@@ -858,7 +858,7 @@
         ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25);
     }
     if (ret < 0)
-        goto ata_read_error;
+        goto sd_read_error;
 
     /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */
 
@@ -874,38 +874,38 @@
         }
 
         ret = -EC_FIFO_READ_FULL;
-        goto ata_read_error;
+        goto sd_read_error;
     }
 
     last_disk_activity = current_tick;
 
     ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1);
     if (ret < 0)
-        goto ata_read_error;
+        goto sd_read_error;
 
     ret = sd_wait_for_state(TRAN, EC_TRAN_READ_EXIT);
     if (ret < 0)
-        goto ata_read_error;
+        goto sd_read_error;
 
     while (1)
     {
-        ata_led(false);
+        sd_led(false);
         mutex_unlock(&sd_mtx);
 
         return ret;
 
-ata_read_error:
+sd_read_error:
         if (sd_status[drive].retry < sd_status[drive].retry_max
             && ret != -EC_NOCARD)
         {
             sd_status[drive].retry++;
             currcard->initialized = 0;
-            goto ata_read_retry;
+            goto sd_read_retry;
         }
     }
 }
 
-int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
+int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
                       const void* outbuf)
 {
 /* Write support is not finished yet */
@@ -920,14 +920,14 @@
 
     mutex_lock(&sd_mtx);
 
-    ata_led(true);
+    sd_led(true);
 
-ata_write_retry:
+sd_write_retry:
     if (drive != 0 && !card_detect_target())
     {
         /* no external sd-card inserted */
         ret = -EC_NOCARD;
-        goto ata_write_error;
+        goto sd_write_error;
     }
 
     sd_select_device(drive);
@@ -935,7 +935,7 @@
     if (currcard->initialized < 0)
     {
         ret = currcard->initialized;
-        goto ata_write_error;
+        goto sd_write_error;
     }
 
     /* Only switch banks with non-SDHC cards */
@@ -947,7 +947,7 @@
         {
             ret = sd_select_bank(bank);
             if (ret < 0)
-                goto ata_write_error;
+                goto sd_write_error;
         }
     
         start -= bank * BLOCKS_PER_BANK;
@@ -957,7 +957,7 @@
 
     ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_ENTRY);
     if (ret < 0)
-        goto ata_write_error;
+        goto sd_write_error;
 
     BLOCK_COUNT_REG = count;
 
@@ -973,7 +973,7 @@
         ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d);
     }
     if (ret < 0)
-        goto ata_write_error;
+        goto sd_write_error;
 
     buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN;
 
@@ -996,7 +996,7 @@
         }
 
         ret = -EC_FIFO_WR_EMPTY;
-        goto ata_write_error;
+        goto sd_write_error;
     }
 
     last_disk_activity = current_tick;
@@ -1004,31 +1004,31 @@
     if (!sd_poll_status(DATA_DONE, 0x80000))
     {
         ret = -EC_FIFO_WR_DONE;
-        goto ata_write_error;
+        goto sd_write_error;
     }
 
     ret = sd_command(STOP_TRANSMISSION, 0, NULL, 1);
     if (ret < 0)
-        goto ata_write_error;
+        goto sd_write_error;
 
     ret = sd_wait_for_state(TRAN, EC_TRAN_WRITE_EXIT);
     if (ret < 0)
-        goto ata_write_error;
+        goto sd_write_error;
 
     while (1)
     {
-        ata_led(false);
+        sd_led(false);
         mutex_unlock(&sd_mtx);
 
         return ret;
 
-ata_write_error:
+sd_write_error:
         if (sd_status[drive].retry < sd_status[drive].retry_max
             && ret != -EC_NOCARD)
         {
             sd_status[drive].retry++;
             currcard->initialized = 0;
-            goto ata_write_retry;
+            goto sd_write_retry;
         }
     }
 }
@@ -1088,7 +1088,7 @@
 
                 if (!idle_notified)
                 {
-                    call_ata_idle_notifys(false);
+                    call_storage_idle_notifys(false);
                     idle_notified = true;
                 }
             }
@@ -1106,37 +1106,7 @@
     }
 }
 
-
-void ata_spindown(int seconds)
-{
-    (void)seconds;
-}
-
-bool ata_disk_is_active(void)
-{
-    return 0;
-}
-
-void ata_sleep(void)
-{
-}
-
-void ata_spin(void)
-{
-}
-
-/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
-int ata_hard_reset(void)
-{
-    return 0;
-}
-
-int ata_soft_reset(void)
-{
-    return 0;
-}
-
-void ata_enable(bool on)
+void sd_enable(bool on)
 {
     if(on)
     {
@@ -1170,7 +1140,7 @@
 }
 #endif
 
-int ata_init(void)
+int sd_init(void)
 {
     int ret = 0;
 
@@ -1179,7 +1149,7 @@
 
     mutex_lock(&sd_mtx);
 
-    ata_led(false);
+    sd_led(false);
 
     if (!initialized)
     {
@@ -1324,3 +1294,46 @@
 
 }
 #endif /* HAVE_HOTSWAP */
+
+long sd_last_disk_activity(void)
+{
+    return last_disk_activity;
+}
+
+void sd_get_info(IF_MV2(int drive,) struct storage_info *info)
+{
+#ifndef HAVE_MULTIVOLUME
+    const int drive=0;
+#endif
+    info->sector_size=card_info[drive].block_size;
+    info->num_sectors=card_info[drive].numblocks;
+    info->vendor="Rockbox";
+    if(drive==0)
+    {
+        info->product="Internal Storage";
+    }
+    else
+    {
+        info->product="SD Card Slot";
+    }
+    info->revision="0.00";
+}
+
+#ifdef HAVE_HOTSWAP
+bool sd_removable(IF_MV_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIVOLUME
+    const int drive=0;
+#endif
+    return (drive==1);
+}
+
+bool sd_present(IF_MV_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIVOLUME
+    const int drive=0;
+#endif
+    return (card_info[drive].initialized && card_info[drive].numblocks > 0);
+}
+#endif
+
diff --git a/firmware/usb.c b/firmware/usb.c
index 9064987..bfb99e0 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -29,7 +29,7 @@
 #include "thread.h"
 #include "system.h"
 #include "debug.h"
-#include "ata.h"
+#include "storage.h"
 #include "fat.h"
 #include "disk.h"
 #include "panic.h"
@@ -86,7 +86,7 @@
 static int last_usb_status;
 static bool usb_monitor_enabled;
 #ifdef HAVE_USBSTACK
-static bool exclusive_ata_access;
+static bool exclusive_storage_access;
 #endif
 
 
@@ -105,9 +105,9 @@
     if(on)
     {
         DEBUGF("Entering USB slave mode\n");
-        ata_soft_reset();
-        ata_init();
-        ata_enable(false);
+        storage_soft_reset();
+        storage_init();
+        storage_enable(false);
         usb_enable(true);
     }
     else
@@ -119,9 +119,9 @@
         
         usb_enable(false);
 
-        rc = ata_init();
+        rc = storage_init();
         if(rc)
-            panicf("ata: %d",rc);
+            panicf("storage: %d",rc);
     
         rc = disk_mount_all();
         if (rc <= 0) /* no partition */
@@ -134,7 +134,7 @@
 static void try_reboot(void)
 {
 #ifdef HAVE_DISK_STORAGE
-    ata_sleepnow(); /* Immediately spindown the disk. */
+    storage_sleepnow(); /* Immediately spindown the disk. */
     sleep(HZ*2);
 #endif
 
@@ -262,7 +262,7 @@
 #ifdef HAVE_PRIORITY_SCHEDULING
                         thread_set_priority(usb_thread_entry,PRIORITY_REALTIME);
 #endif
-                        exclusive_ata_access = true;
+                        exclusive_storage_access = true;
 
 #else
                         usb_slave_mode(true);
@@ -310,12 +310,12 @@
 
                 usb_state = USB_EXTRACTED;
 #ifdef HAVE_USBSTACK
-                if(exclusive_ata_access)
+                if(exclusive_storage_access)
                 {
                     int rc = disk_mount_all();
                     if (rc <= 0) /* no partition */
                         panicf("mount: %d",rc);
-                    exclusive_ata_access = false;
+                    exclusive_storage_access = false;
 #endif
                     /* Tell all threads that we are back in business */
                     num_acks_to_expect =
@@ -455,7 +455,7 @@
 {
     usb_state = USB_EXTRACTED;
 #ifdef HAVE_USBSTACK
-    exclusive_ata_access = false;
+    exclusive_storage_access = false;
 #endif
     usb_monitor_enabled = false;
     countdown = -1;
@@ -561,7 +561,7 @@
      * currently the best one. We want to get rid of having to boost the cpu
      * for usb anyway */
     trigger_cpu_boost();
-    if(!exclusive_ata_access) {
+    if(!exclusive_storage_access) {
         queue_post(&usb_queue, USB_REQUEST_DISK, 0);
     }
 }
@@ -569,15 +569,15 @@
 void usb_release_exclusive_ata(void)
 {
     cancel_cpu_boost();
-    if(exclusive_ata_access) {
+    if(exclusive_storage_access) {
         queue_post(&usb_queue, USB_RELEASE_DISK, 0);
-        exclusive_ata_access = false;
+        exclusive_storage_access = false;
     }
 }
 
 bool usb_exclusive_ata(void)
 {
-    return exclusive_ata_access;
+    return exclusive_storage_access;
 }
 #endif
 
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index fa0ff5e..7724049 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -50,7 +50,7 @@
 #include "as3514.h"
 #endif
 
-#if !defined(HAVE_AS3514) && !defined(IPOD_ARCH)
+#if !defined(HAVE_AS3514) && !defined(IPOD_ARCH) && (CONFIG_STORAGE & STORAGE_ATA)
 #include "ata.h"
 #endif
 
@@ -281,7 +281,7 @@
     }
     usb_string_iSerial.bLength=68;
 }
-#else 
+#elif (CONFIG_STORAGE & STORAGE_ATA)
 /* If we don't know the device serial number, use the one
  * from the disk */
 static void set_serial_descriptor(void)
@@ -300,6 +300,8 @@
     }
     usb_string_iSerial.bLength=84;
 }
+#else
+#error No set_serial_descriptor() implementation for this target
 #endif
 
 void usb_core_init(void)
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 198ff46..24ac001 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -24,7 +24,7 @@
 #include "usb_drv.h"
 //#define LOGF_ENABLE
 #include "logf.h"
-#include "ata.h"
+#include "storage.h"
 #include "hotswap.h"
 #include "disk.h"
 /* Needed to get at the audio buffer */
@@ -36,7 +36,7 @@
 
 /* The SD card driver on Sansa c200 and e200 can cause write corruption,
  * often triggered by simultaneous USB activity. This can be largely avoided
- * by not overlapping ata_write_sector() with USB transfers. This does reduce
+ * by not overlapping storage_write_sector() with USB transfers. This does reduce
  * write performance, so we only do it for the affected DAPs
  */
 #if (CONFIG_STORAGE & STORAGE_SD)
@@ -147,10 +147,8 @@
 struct report_lun_data {
     unsigned int lun_list_length;
     unsigned int reserved1;
-    unsigned char lun0[8];
-#ifdef HAVE_HOTSWAP
-    unsigned char lun1[8];
-#endif
+    // TODO this should be cleaned up with the VOLUMES vs DRIVES mess
+    unsigned char luns[NUM_VOLUMES][8];
 } __attribute__ ((packed));
 
 struct sense_data {
@@ -263,7 +261,7 @@
 static void send_command_failed_result(void);
 static void send_block_data(void *data,int size);
 static void receive_block_data(void *data,int size);
-static void identify2inquiry(int lun);
+static void fill_inquiry(IF_MV_NONVOID(int lun));
 static void send_and_read_next(void);
 static bool ejected[NUM_VOLUMES];
 
@@ -289,7 +287,7 @@
     return true;
 #else
     unsigned char sector[512];
-    return ata_read_sectors(IF_MV2(volume,)0,1,sector) == 0;
+    return storage_read_sectors(IF_MV2(volume,)0,1,sector) == 0;
 #endif
 }
 
@@ -460,7 +458,7 @@
                        cur_cmd.data[cur_cmd.data_select],
                        MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
 #else
-                int result = ata_write_sectors(IF_MV2(cur_cmd.lun,)
+                int result = storage_write_sectors(IF_MV2(cur_cmd.lun,)
                                          cur_cmd.sector,
                                          MIN(BUFFER_SIZE/SECTOR_SIZE,
                                              cur_cmd.count),
@@ -639,7 +637,7 @@
                ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
                MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
 #else
-        cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,)
+        cur_cmd.last_result = storage_read_sectors(IF_MV2(cur_cmd.lun,)
                                            cur_cmd.sector,
                                            MIN(BUFFER_SIZE/SECTOR_SIZE,
                                                cur_cmd.count),
@@ -654,6 +652,7 @@
     /* USB Mass Storage assumes LBA capability.
        TODO: support 48-bit LBA */
 
+    struct storage_info info;
     unsigned int length = cbw->data_transfer_length;
     unsigned int block_size = 0;
     unsigned int block_count = 0;
@@ -664,25 +663,20 @@
     unsigned char lun = cbw->lun;
 #endif
     unsigned int block_size_mult = 1;
+    storage_get_info(IF_MV2(lun,)&info);
 #ifdef USB_USE_RAMDISK
     block_size = SECTOR_SIZE;
     block_count = RAMDISK_SIZE;
 #else
-#if (CONFIG_STORAGE & STORAGE_SD) || defined(HAVE_HOTSWAP)
-    tCardInfo* cinfo = card_get_info(lun);
-    if(cinfo->initialized && cinfo->numblocks > 0) {
-        block_size = cinfo->blocksize;
-        block_count = cinfo->numblocks;
-    }
-    else {
+    block_size=info.sector_size;
+    block_count=info.num_sectors;
+#endif
+
+#ifdef HAVE_HOTSWAP
+    if(storage_removable(IF_MV(lun)) && !storage_present(IF_MV(lun))) {
         ejected[lun] = true;
         try_release_ata();
     }
-#else
-    unsigned short* identify = ata_get_identify();
-    block_size = SECTOR_SIZE;
-    block_count = (identify[61] << 16 | identify[60]);
-#endif
 #endif
 
     if(ejected[lun])
@@ -719,19 +713,22 @@
         case SCSI_REPORT_LUNS: {
             logf("scsi inquiry %d",lun);
             int allocation_length=0;
+            int i;
             allocation_length|=(cbw->command_block[6]<<24);
             allocation_length|=(cbw->command_block[7]<<16);
             allocation_length|=(cbw->command_block[8]<<8);
             allocation_length|=(cbw->command_block[9]);
             memset(tb.lun_data,0,sizeof(struct report_lun_data));
+            tb.lun_data->lun_list_length=htobe32(8*NUM_VOLUMES);
+            for(i=0;i<NUM_VOLUMES;i++)
+            {
 #ifdef HAVE_HOTSWAP
-            tb.lun_data->lun_list_length=htobe32(16);
-            tb.lun_data->lun1[1]=1;
-#else
-            tb.lun_data->lun_list_length=htobe32(8);
+                if(storage_removable(IF_MV(i)))
+                    tb.lun_data->luns[i][1]=1;
+                else
 #endif
-            tb.lun_data->lun0[1]=0;
-            
+                    tb.lun_data->luns[i][1]=0;
+            }
             send_command_result(tb.lun_data,
                                 MIN(sizeof(struct report_lun_data), length));
             break;
@@ -739,7 +736,7 @@
 
         case SCSI_INQUIRY:
             logf("scsi inquiry %d",lun);
-            identify2inquiry(lun);
+            fill_inquiry(IF_MV(lun));
             length = MIN(length, cbw->command_block[4]);
             send_command_result(tb.inquiry,
                                 MIN(sizeof(struct inquiry_data), length));
@@ -975,7 +972,7 @@
                        ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
                        MIN(BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
 #else
-                cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,)
+                cur_cmd.last_result = storage_read_sectors(IF_MV2(cur_cmd.lun,)
                                              cur_cmd.sector,
                                              MIN(BUFFER_SIZE/SECTOR_SIZE,
                                                  cur_cmd.count),
@@ -1072,46 +1069,30 @@
     }
 }
 
-/* convert ATA IDENTIFY to SCSI INQUIRY */
-static void identify2inquiry(int lun)
+static void copy_padded(char *dest, char *src, int len)
 {
-#ifdef HAVE_FLASH_STORAGE
-    if(lun==0) {
-        memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
-        memcpy(&tb.inquiry->ProductId,"Internal Storage",16);
-        memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
-    }
-    else {
-        memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
-        memcpy(&tb.inquiry->ProductId,"SD Card Slot    ",16);
-        memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
-    }
-#else
-    unsigned int i;
-    unsigned short* dest;
-    unsigned short* src;
-    unsigned short* identify = ata_get_identify();
-    (void)lun;
-    memset(tb.inquiry, 0, sizeof(struct inquiry_data));
-    
-#if 0
-    if (identify[82] & 4)
-        tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
-#endif
+   int i=0;
+   while(src[i]!=0 && i<len)
+   {
+      dest[i]=src[i];
+      i++;
+   }
+   while(i<len)
+   {
+      dest[i]=' ';
+      i++;
+   }
+}
 
-    /* ATA only has a 'model' field, so we copy the 
-       first 8 bytes to 'vendor' and the rest to 'product' (they are
-       consecutive in the inquiry struct) */
-    src = (unsigned short*)&identify[27];
-    dest = (unsigned short*)&tb.inquiry->VendorId;
-    for (i=0;i<12;i++)
-        dest[i] = htobe16(src[i]);
-    
-    src = (unsigned short*)&identify[23];
-    dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel;
-    for (i=0;i<2;i++)
-        dest[i] = htobe16(src[i]);
-#endif
+/* build SCSI INQUIRY */
+static void fill_inquiry(IF_MV_NONVOID(int lun))
+{
+    memset(tb.inquiry, 0, sizeof(struct inquiry_data));
+    struct storage_info info;
+    storage_get_info(IF_MV2(lun,)&info);
+    copy_padded(tb.inquiry->VendorId,info.vendor,sizeof(tb.inquiry->VendorId));
+    copy_padded(tb.inquiry->ProductId,info.product,sizeof(tb.inquiry->ProductId));
+    copy_padded(tb.inquiry->ProductRevisionLevel,info.revision,sizeof(tb.inquiry->ProductRevisionLevel));
 
     tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
     tb.inquiry->AdditionalLength = 0x1f;
@@ -1119,14 +1100,6 @@
     tb.inquiry->Versions = 4; /* SPC-2 */
     tb.inquiry->Format   = 2; /* SPC-2/3 inquiry format */
 
-#if 0
-#ifdef HAVE_HOTSWAP
-    if(lun>0)
-        tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
-#endif
-#endif
-    /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set.
-       TODO : this can probably be solved by providing caching mode page */
 #ifdef TOSHIBA_GIGABEAT_S
     tb.inquiry->DeviceTypeModifier = 0;
 #else
diff --git a/flash/bootbox/main.c b/flash/bootbox/main.c
index 2bd3fea..f53a5ed 100644
--- a/flash/bootbox/main.c
+++ b/flash/bootbox/main.c
@@ -31,7 +31,7 @@
 #include "lcd.h"
 #include "kernel.h"
 #include "thread.h"
-#include "ata.h"
+#include "storage.h"
 #include "disk.h"
 #include "font.h"
 #include "adc.h"
@@ -168,7 +168,7 @@
     }
 #endif
 
-    rc = ata_init();
+    rc = storage_init();
     if(rc)
     {
 #ifdef HAVE_LCD_BITMAP
@@ -179,7 +179,7 @@
         lcd_update();
         while(!(button_get(true) & BUTTON_REL));
 #endif
-        panicf("ata: %d", rc);
+        panicf("storage: %d", rc);
     }
 
     usb_start_monitoring();