| From: Daniel Golle <daniel@makrotopia.org> | 
 | Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot | 
 |  | 
 | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | 
 | --- | 
 |  drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ | 
 |  1 file changed, 36 insertions(+) | 
 |  | 
 | --- a/drivers/mtd/ubi/build.c | 
 | +++ b/drivers/mtd/ubi/build.c | 
 | @@ -1177,6 +1177,73 @@ static struct mtd_info * __init open_mtd | 
 |  	return mtd; | 
 |  } | 
 |   | 
 | +/* | 
 | + * This function tries attaching mtd partitions named either "ubi" or "data" | 
 | + * during boot. | 
 | + */ | 
 | +static void __init ubi_auto_attach(void) | 
 | +{ | 
 | +	int err; | 
 | +	struct mtd_info *mtd; | 
 | +	loff_t offset = 0; | 
 | +	size_t len; | 
 | +	char magic[4]; | 
 | + | 
 | +	/* try attaching mtd device named "ubi" or "data" */ | 
 | +	mtd = open_mtd_device("ubi"); | 
 | +	if (IS_ERR(mtd)) | 
 | +		mtd = open_mtd_device("data"); | 
 | + | 
 | +	if (IS_ERR(mtd)) | 
 | +		return; | 
 | + | 
 | +	/* get the first not bad block */ | 
 | +	if (mtd_can_have_bb(mtd)) | 
 | +		while (mtd_block_isbad(mtd, offset)) { | 
 | +			offset += mtd->erasesize; | 
 | + | 
 | +			if (offset > mtd->size) { | 
 | +				pr_err("UBI error: Failed to find a non-bad " | 
 | +				       "block on mtd%d\n", mtd->index); | 
 | +				goto cleanup; | 
 | +			} | 
 | +		} | 
 | + | 
 | +	/* check if the read from flash was successful */ | 
 | +	err = mtd_read(mtd, offset, 4, &len, (void *) magic); | 
 | +	if ((err && !mtd_is_bitflip(err)) || len != 4) { | 
 | +		pr_err("UBI error: unable to read from mtd%d\n", mtd->index); | 
 | +		goto cleanup; | 
 | +	} | 
 | + | 
 | +	/* check for a valid ubi magic */ | 
 | +	if (strncmp(magic, "UBI#", 4)) { | 
 | +		pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); | 
 | +		goto cleanup; | 
 | +	} | 
 | + | 
 | +	/* don't auto-add media types where UBI doesn't makes sense */ | 
 | +	if (mtd->type != MTD_NANDFLASH && | 
 | +	    mtd->type != MTD_NORFLASH && | 
 | +	    mtd->type != MTD_DATAFLASH && | 
 | +	    mtd->type != MTD_MLCNANDFLASH) | 
 | +		goto cleanup; | 
 | + | 
 | +	mutex_lock(&ubi_devices_mutex); | 
 | +	pr_notice("UBI: auto-attach mtd%d\n", mtd->index); | 
 | +	err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); | 
 | +	mutex_unlock(&ubi_devices_mutex); | 
 | +	if (err < 0) { | 
 | +		pr_err("UBI error: cannot attach mtd%d\n", mtd->index); | 
 | +		goto cleanup; | 
 | +	} | 
 | + | 
 | +	return; | 
 | + | 
 | +cleanup: | 
 | +	put_mtd_device(mtd); | 
 | +} | 
 | + | 
 |  static int __init ubi_init(void) | 
 |  { | 
 |  	int err, i, k; | 
 | @@ -1260,6 +1327,12 @@ static int __init ubi_init(void) | 
 |  		} | 
 |  	} | 
 |   | 
 | +	/* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd | 
 | +	 * parameter was given */ | 
 | +	if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && | 
 | +	    !ubi_is_module() && !mtd_devs) | 
 | +		ubi_auto_attach(); | 
 | + | 
 |  	err = ubiblock_init(); | 
 |  	if (err) { | 
 |  		pr_err("UBI error: block: cannot initialize, error %d\n", err); |