#define BLOCK_LEN_MIN 0x10000
-static struct mtd_info *trx_mtd_master = NULL;
-static struct mtd_info *trx_mtds[TRX_MAX_OFFSET];
+static struct mtd_info *trx_mtd = NULL;
+static unsigned long trx_offset = 0;
+static int trx_nr_parts = 0;
static struct mtd_partition trx_parts[TRX_MAX_OFFSET];
static struct trx_header trx_hdr;
-static int trx_nr_parts = 0;
-static int trx_rootfs_part = -1;
static int __init trxsplit_checktrx(struct mtd_info *mtd, unsigned long offset)
{
int err;
err = mtd->read(mtd, offset, sizeof(trx_hdr), &retlen, (void *)&trx_hdr);
- if (err)
+ if (err) {
+ printk(KERN_ALERT PFX "unable to read from '%s'\n", mtd->name);
goto err_out;
+ }
- if (retlen != sizeof(trx_hdr))
+ if (retlen != sizeof(trx_hdr)) {
+ printk(KERN_ALERT PFX "reading failed on '%s'\n", mtd->name);
goto err_out;
+ }
trx_hdr.magic = le32_to_cpu(trx_hdr.magic);
trx_hdr.len = le32_to_cpu(trx_hdr.len);
/* TODO: add crc32 checking too? */
- return 1;
+ return 0;
err_out:
- return 0;
+ return -1;
}
-static void __init trxsplit_create_partitions(struct mtd_info *mtd,
- unsigned long offset)
+static int __init trxsplit_create_partitions(void)
{
struct mtd_partition *part = trx_parts;
+ int ret = 0;
int i;
- for (i=0;i<TRX_MAX_OFFSET;i++) {
+ if (trx_mtd == NULL)
+ goto out;
+
+ printk(KERN_INFO PFX "creating TRX partitions in '%s' (%d,%d)\n",
+ trx_mtd->name, MTD_BLOCK_MAJOR, trx_mtd->index);
+
+ for (i=0; i<TRX_MAX_OFFSET;i++) {
part = &trx_parts[i];
if (trx_hdr.offsets[i] == 0)
continue;
- part->offset = offset + trx_hdr.offsets[i];
- part->mtdp = &trx_mtds[trx_nr_parts];
+ part->offset = trx_offset + trx_hdr.offsets[i];
trx_nr_parts++;
}
for (i=0; i<trx_nr_parts-1; i++) {
trx_parts[i].size = trx_parts[i+1].offset - trx_parts[i].offset;
}
- trx_parts[i].size = mtd->size - trx_parts[i].offset;
+ trx_parts[i].size = trx_mtd->size - trx_parts[i].offset;
i=0;
part = &trx_parts[i];
if (part->size < TRX_MIN_KERNEL_SIZE) {
- part->name = "trx_loader";
+ part->name = "loader";
i++;
}
part = &trx_parts[i];
- part->name = "trx_kernel";
+ part->name = "kernel";
i++;
part = &trx_parts[i];
- part->name = "trx_rootfs";
- trx_rootfs_part = i;
+ part->name = "rootfs";
+
+ ret = add_mtd_partitions(trx_mtd, trx_parts, trx_nr_parts);
+ if (ret) {
+ printk(KERN_ALERT PFX "creating TRX partitions failed\n");
+ }
+
+out:
+ return ret;
}
static void __init trxsplit_add_mtd(struct mtd_info *mtd)
{
unsigned long offset;
unsigned long blocklen;
- int found;
+ int err;
- if (trx_mtd_master)
+ if (trx_mtd)
return;
blocklen = mtd->erasesize;
printk(KERN_INFO PFX "searching TRX header in '%s'\n", mtd->name);
- found = 0;
+ err = 0;
for (offset=0; offset < mtd->size; offset+=blocklen) {
- found = trxsplit_checktrx(mtd, offset);
- if (found)
+ err = trxsplit_checktrx(mtd, offset);
+ if (err == 0)
break;
}
- if (found == 0) {
+ if (err) {
printk(KERN_ALERT PFX "no TRX header found\n");
return;
}
printk(KERN_INFO PFX "TRX header found at 0x%lX\n", offset);
- trxsplit_create_partitions(mtd, offset);
-
- trx_mtd_master = mtd;
+ trx_mtd = mtd;
+ trx_offset = offset;
}
-static void trxsplit_remove_mtd(struct mtd_info *mtd)
+static void __init trxsplit_remove_mtd(struct mtd_info *mtd)
{
+ /* nothing to do */
}
static struct mtd_notifier trxsplit_notifier __initdata = {
static int __init trxsplit_init(void)
{
- int err;
- int i;
+ int ret;
trxsplit_find_trx();
- if (trx_mtd_master == NULL)
- goto err;
-
- printk(KERN_INFO PFX "creating TRX partitions in '%s'\n",
- trx_mtd_master->name);
-
- err = add_mtd_partitions(trx_mtd_master, trx_parts, trx_nr_parts);
- if (err) {
- printk(KERN_ALERT PFX "creating TRX partitions failed\n");
- goto err;
- }
-
- for (i=0; i<trx_nr_parts; i++) {
- /* TODO: add error checking */
- add_mtd_device(trx_mtds[i]);
- }
-
- if (ROOT_DEV == 0 && trx_rootfs_part >= 0) {
- printk(KERN_INFO PFX "set '%s' to be root filesystem\n",
- trx_mtds[trx_rootfs_part]->name);
- ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, trx_mtds[trx_rootfs_part]->index);
- }
-
- return 0;
-
-err:
- return -1;
+ ret = trxsplit_create_partitions();
+ return ret;
}
late_initcall(trxsplit_init);