imx233: fix partition window computation

The code was broken in two ways:
- it called storage_read_sectors with a wrong drive number
- calling storage_read_sectors too early at boot time will fail because
  we are in the init function, so the drive is not yet registered.
To fix this, use a user provided read callback instead of storage read
functions.

Change-Id: I5ab79d48391fae619d5f8ae09c3d499fc43854c8
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c
index ebc7b9a..508d6f0 100644
--- a/firmware/target/arm/imx233/partitions-imx233.c
+++ b/firmware/target/arm/imx233/partitions-imx233.c
@@ -71,11 +71,11 @@
     }
 }
 
-static int compute_window_creative(IF_MD(int drive,) enum imx233_part_t part,
-    unsigned *start, unsigned *end)
+static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
+    enum imx233_part_t part, unsigned *start, unsigned *end)
 {
     uint8_t mblk[512];
-    int ret = storage_read_sectors(IF_MD(drive,) MBLK_ADDR / 512, 1, mblk);
+    int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk);
     if(ret < 0)
         return ret;
     struct mblk_header_t *hdr = (void *)mblk;
@@ -99,11 +99,11 @@
 #endif /* #(IMX233_PARTITIONS & IMX233_CREATIVE) */
 
 #if (IMX233_PARTITIONS & IMX233_FREESCALE)
-static int compute_window_freescale(IF_MD(int drive,) enum imx233_part_t part,
-    unsigned *start, unsigned *end)
+static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn,
+    enum imx233_part_t part, unsigned *start, unsigned *end)
 {
     uint8_t mbr[512];
-    int ret = storage_read_sectors(IF_MD(drive,) 0, 1, mbr);
+    int ret = read_fn(user, 0, 1, mbr);
     if(ret < 0)
         return ret;
     /**
@@ -161,17 +161,17 @@
 }
 #endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */
 
-int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part,
-    unsigned *start, unsigned *end)
+int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
+    enum imx233_part_t part, unsigned *start, unsigned *end)
 {
     int ret = -1;
 #if (IMX233_PARTITIONS & IMX233_CREATIVE)
-    ret = compute_window_creative(IF_MD(drive,) part, start, end);
+    ret = compute_window_creative(user, read_fn, part, start, end);
     if(ret >= 0)
         return ret;
 #endif
 #if (IMX233_PARTITIONS & IMX233_FREESCALE)
-    ret = compute_window_freescale(IF_MD(drive,) part, start, end);
+    ret = compute_window_freescale(user, read_fn, part, start, end);
     if(ret >= 0)
         return ret;
 #endif
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h
index b7ed251..80936ad 100644
--- a/firmware/target/arm/imx233/partitions-imx233.h
+++ b/firmware/target/arm/imx233/partitions-imx233.h
@@ -40,11 +40,15 @@
 #endif
 };
 
+/** The computation function can be called very early in the boot, at which point
+ * usual storage read/write function may not be available. To workaround this
+ * issue, one must provide a read function. */
+typedef int (*part_read_fn_t)(intptr_t user, unsigned long start, int count, void* buf);
 /* Enable/Disable window computations for internal storage following the
  * Freescale convention */
 void imx233_partitions_enable_window(bool enable);
 bool imx233_partitions_is_window_enabled(void);
-int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part,
-    unsigned *start, unsigned *end);
+int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
+    enum imx233_part_t part, unsigned *start, unsigned *end);
 
 #endif /* __PARTITIONS_IMX233__ */
\ No newline at end of file
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index cff801f..24bf69e 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -672,6 +672,12 @@
     return ret;
 }
 
+// user specificies the sdmmc drive
+static int part_read_fn(intptr_t user, unsigned long start, int count, void* buf)
+{
+    return transfer_sectors(user, start, count, buf, true);
+}
+
 static int init_drive(int drive)
 {
     int ret;
@@ -693,8 +699,8 @@
     {
         /* NOTE: at this point the window shows the whole disk so raw disk
          * accesses can be made to lookup partitions */
-        ret = imx233_partitions_compute_window(IF_MD(drive,) IMX233_PART_USER,
-            &window_start[drive], &window_end[drive]);
+        ret = imx233_partitions_compute_window(IF_MD_DRV(drive), part_read_fn,
+            IMX233_PART_USER, &window_start[drive], &window_end[drive]);
         if(ret)
             panicf("cannot compute partitions window: %d", ret);
         SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive];