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
This commit is contained in:
Amaury Pouly 2013-10-22 15:55:28 +02:00
parent 51ed6da0b1
commit 4aa32fb8f4
3 changed files with 24 additions and 14 deletions

View file

@ -71,11 +71,11 @@ static const char *creative_part_name(enum imx233_part_t part)
} }
} }
static int compute_window_creative(IF_MD(int drive,) enum imx233_part_t part, static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
unsigned *start, unsigned *end) enum imx233_part_t part, unsigned *start, unsigned *end)
{ {
uint8_t mblk[512]; 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) if(ret < 0)
return ret; return ret;
struct mblk_header_t *hdr = (void *)mblk; struct mblk_header_t *hdr = (void *)mblk;
@ -99,11 +99,11 @@ static int compute_window_creative(IF_MD(int drive,) enum imx233_part_t part,
#endif /* #(IMX233_PARTITIONS & IMX233_CREATIVE) */ #endif /* #(IMX233_PARTITIONS & IMX233_CREATIVE) */
#if (IMX233_PARTITIONS & IMX233_FREESCALE) #if (IMX233_PARTITIONS & IMX233_FREESCALE)
static int compute_window_freescale(IF_MD(int drive,) enum imx233_part_t part, static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn,
unsigned *start, unsigned *end) enum imx233_part_t part, unsigned *start, unsigned *end)
{ {
uint8_t mbr[512]; 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) if(ret < 0)
return ret; return ret;
/** /**
@ -161,17 +161,17 @@ static int compute_window_freescale(IF_MD(int drive,) enum imx233_part_t part,
} }
#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */ #endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */
int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part, int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
unsigned *start, unsigned *end) enum imx233_part_t part, unsigned *start, unsigned *end)
{ {
int ret = -1; int ret = -1;
#if (IMX233_PARTITIONS & IMX233_CREATIVE) #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) if(ret >= 0)
return ret; return ret;
#endif #endif
#if (IMX233_PARTITIONS & IMX233_FREESCALE) #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) if(ret >= 0)
return ret; return ret;
#endif #endif

View file

@ -40,11 +40,15 @@ enum imx233_part_t
#endif #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 /* Enable/Disable window computations for internal storage following the
* Freescale convention */ * Freescale convention */
void imx233_partitions_enable_window(bool enable); void imx233_partitions_enable_window(bool enable);
bool imx233_partitions_is_window_enabled(void); bool imx233_partitions_is_window_enabled(void);
int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part, int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
unsigned *start, unsigned *end); enum imx233_part_t part, unsigned *start, unsigned *end);
#endif /* __PARTITIONS_IMX233__ */ #endif /* __PARTITIONS_IMX233__ */

View file

@ -672,6 +672,12 @@ static int transfer_sectors(int drive, unsigned long start, int count, void *buf
return ret; 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) static int init_drive(int drive)
{ {
int ret; int ret;
@ -693,8 +699,8 @@ static int init_drive(int drive)
{ {
/* NOTE: at this point the window shows the whole disk so raw disk /* NOTE: at this point the window shows the whole disk so raw disk
* accesses can be made to lookup partitions */ * accesses can be made to lookup partitions */
ret = imx233_partitions_compute_window(IF_MD(drive,) IMX233_PART_USER, ret = imx233_partitions_compute_window(IF_MD_DRV(drive), part_read_fn,
&window_start[drive], &window_end[drive]); IMX233_PART_USER, &window_start[drive], &window_end[drive]);
if(ret) if(ret)
panicf("cannot compute partitions window: %d", ret); panicf("cannot compute partitions window: %d", ret);
SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive]; SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive];