diff options
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu_init.c | 2 | ||||
| -rw-r--r-- | common/cmd_ubi.c | 15 | ||||
| -rw-r--r-- | common/cmd_ubifs.c | 47 | ||||
| -rw-r--r-- | fs/ubifs/super.c | 2 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.c | 71 | ||||
| -rw-r--r-- | include/configs/MPC8572DS.h | 1 | ||||
| -rw-r--r-- | include/post.h | 6 | 
7 files changed, 126 insertions, 18 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 27236a0ba..4b8faa5da 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -327,7 +327,7 @@ int cpu_init_r(void)  	if (l2cache->l2ctl & MPC85xx_L2CTL_L2E) {  		puts("already enabled");  		l2srbar = l2cache->l2srbar0; -#ifdef CONFIG_SYS_INIT_L2_ADDR +#if defined(CONFIG_SYS_INIT_L2_ADDR) && defined(CONFIG_SYS_FLASH_BASE)  		if (l2cache->l2ctl & MPC85xx_L2CTL_L2SRAM_ENTIRE  				&& l2srbar >= CONFIG_SYS_FLASH_BASE) {  			l2srbar = CONFIG_SYS_INIT_L2_ADDR; diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 7692ac771..b486ca8fe 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -42,6 +42,11 @@ struct selected_dev {  static struct selected_dev ubi_dev; +#ifdef CONFIG_CMD_UBIFS +int ubifs_is_mounted(void); +void cmd_ubifs_umount(void); +#endif +  static void ubi_dump_vol_info(const struct ubi_volume *vol)  {  	ubi_msg("volume information dump:"); @@ -472,6 +477,16 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  		if (argc < 3)  			return cmd_usage(cmdtp); +#ifdef CONFIG_CMD_UBIFS +		/* +		 * Automatically unmount UBIFS partition when user +		 * changes the UBI device. Otherwise the following +		 * UBIFS commands will crash. +		 */ +		if (ubifs_is_mounted()) +			cmd_ubifs_umount(); +#endif +  		/* todo: get dev number for NAND... */  		ubi_dev.nr = 0; diff --git a/common/cmd_ubifs.c b/common/cmd_ubifs.c index a0ec18448..3cd2d8fa8 100644 --- a/common/cmd_ubifs.c +++ b/common/cmd_ubifs.c @@ -33,12 +33,17 @@  #include <config.h>  #include <command.h> +#include "../fs/ubifs/ubifs.h" +  static int ubifs_initialized;  static int ubifs_mounted; +extern struct super_block *ubifs_sb; +  /* Prototypes */  int ubifs_init(void);  int ubifs_mount(char *vol_name); +void ubifs_umount(struct ubifs_info *c);  int ubifs_ls(char *dir_name);  int ubifs_load(char *filename, u32 addr, u32 size); @@ -67,13 +72,47 @@ int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	return 0;  } +int ubifs_is_mounted(void) +{ +	return ubifs_mounted; +} + +void cmd_ubifs_umount(void) +{ + +	if (ubifs_sb) { +		printf("Unmounting UBIFS volume %s!\n", +		       ((struct ubifs_info *)(ubifs_sb->s_fs_info))->vi.name); +		ubifs_umount(ubifs_sb->s_fs_info); +	} + +	ubifs_sb = NULL; +	ubifs_mounted = 0; +	ubifs_initialized = 0; +} + +int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	if (argc != 1) +		return cmd_usage(cmdtp); + +	if (ubifs_initialized == 0) { +		printf("No UBIFS volume mounted!\n"); +		return -1; +	} + +	cmd_ubifs_umount(); + +	return 0; +} +  int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	char *filename = "/";  	int ret;  	if (!ubifs_mounted) { -		printf("UBIFS not mounted, use ubifs mount to mount volume first!\n"); +		printf("UBIFS not mounted, use ubifsmount to mount volume first!\n");  		return -1;  	} @@ -132,6 +171,12 @@ U_BOOT_CMD(  );  U_BOOT_CMD( +	ubifsumount, 1, 0, do_ubifs_umount, +	"unmount UBIFS volume", +	"    - unmount current volume" +); + +U_BOOT_CMD(  	ubifsls, 2, 0, do_ubifs_ls,  	"list files in a directory",  	"[directory]\n" diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 39e3efec8..63b2164d3 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -824,7 +824,7 @@ out_free:   * through mounting (error path cleanup function). So it has to make sure the   * resource was actually allocated before freeing it.   */ -static void ubifs_umount(struct ubifs_info *c) +void ubifs_umount(struct ubifs_info *c)  {  	dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num,  		c->vi.vol_id); diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 1cc31a968..5a5c739b5 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -3,7 +3,7 @@   *   * Copyright (C) 2006-2008 Nokia Corporation.   * - * (C) Copyright 2008-2009 + * (C) Copyright 2008-2010   * Stefan Roese, DENX Software Engineering, sr@denx.de.   *   * This program is free software; you can redistribute it and/or modify it @@ -384,6 +384,7 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)  	unsigned long root_inum = 1;  	unsigned long inum;  	int symlink_count = 0; /* Don't allow symlink recursion */ +	char link_name[64];  	strcpy(fpath, filename); @@ -420,7 +421,6 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)  		ui = ubifs_inode(inode);  		if ((inode->i_mode & S_IFMT) == S_IFLNK) { -			char link_name[64];  			char buf[128];  			/* We have some sort of symlink recursion, bail out */ @@ -567,7 +567,8 @@ dump:  	return -EINVAL;  } -static int do_readpage(struct ubifs_info *c, struct inode *inode, struct page *page) +static int do_readpage(struct ubifs_info *c, struct inode *inode, +		       struct page *page, int last_block_size)  {  	void *addr;  	int err = 0, i; @@ -601,17 +602,54 @@ static int do_readpage(struct ubifs_info *c, struct inode *inode, struct page *p  			err = -ENOENT;  			memset(addr, 0, UBIFS_BLOCK_SIZE);  		} else { -			ret = read_block(inode, addr, block, dn); -			if (ret) { -				err = ret; -				if (err != -ENOENT) +			/* +			 * Reading last block? Make sure to not write beyond +			 * the requested size in the destination buffer. +			 */ +			if (((block + 1) == beyond) || last_block_size) { +				void *buff; +				int dlen; + +				/* +				 * We need to buffer the data locally for the +				 * last block. This is to not pad the +				 * destination area to a multiple of +				 * UBIFS_BLOCK_SIZE. +				 */ +				buff = malloc(UBIFS_BLOCK_SIZE); +				if (!buff) { +					printf("%s: Error, malloc fails!\n", +					       __func__); +					err = -ENOMEM;  					break; -			} else if (block + 1 == beyond) { -				int dlen = le32_to_cpu(dn->size); -				int ilen = i_size & (UBIFS_BLOCK_SIZE - 1); +				} + +				/* Read block-size into temp buffer */ +				ret = read_block(inode, buff, block, dn); +				if (ret) { +					err = ret; +					if (err != -ENOENT) { +						free(buff); +						break; +					} +				} + +				if (last_block_size) +					dlen = last_block_size; +				else +					dlen = le32_to_cpu(dn->size); + +				/* Now copy required size back to dest */ +				memcpy(addr, buff, dlen); -				if (ilen && ilen < dlen) -					memset(addr + ilen, 0, dlen - ilen); +				free(buff); +			} else { +				ret = read_block(inode, addr, block, dn); +				if (ret) { +					err = ret; +					if (err != -ENOENT) +						break; +				}  			}  		}  		if (++i >= UBIFS_BLOCKS_PER_PAGE) @@ -649,6 +687,7 @@ int ubifs_load(char *filename, u32 addr, u32 size)  	int err = 0;  	int i;  	int count; +	int last_block_size = 0;  	c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);  	/* ubifs_findfile will resolve symlinks, so we know that we get @@ -684,7 +723,13 @@ int ubifs_load(char *filename, u32 addr, u32 size)  	page.index = 0;  	page.inode = inode;  	for (i = 0; i < count; i++) { -		err = do_readpage(c, inode, &page); +		/* +		 * Make sure to not read beyond the requested size +		 */ +		if (((i + 1) == count) && (size < inode->i_size)) +			last_block_size = size - (i * PAGE_SIZE); + +		err = do_readpage(c, inode, &page, last_block_size);  		if (err)  			break; diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 692c8115e..1ee95aed2 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -202,6 +202,7 @@  #define CONFIG_BOARD_EARLY_INIT_R	/* call board_early_init_r function */ +#define CONFIG_HWCONFIG			/* enable hwconfig */  #define CONFIG_FSL_PIXIS	1	/* use common PIXIS code */  #define PIXIS_BASE	0xffdf0000	/* PIXIS registers */  #ifdef CONFIG_PHYS_64BIT diff --git a/include/post.h b/include/post.h index 957ce3b16..519cef161 100644 --- a/include/post.h +++ b/include/post.h @@ -58,11 +58,13 @@  #elif defined (CONFIG_MPC85xx)  #include <asm/immap_85xx.h> -#define _POST_WORD_ADDR	(CONFIG_SYS_IMMR + offsetof(ccsr_pic_t, tfrr)) +#define _POST_WORD_ADDR	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PIC_OFFSET + \ +				offsetof(ccsr_pic_t, tfrr))  #elif defined (CONFIG_MPC86xx)  #include <asm/immap_86xx.h> -#define _POST_WORD_ADDR	(CONFIG_SYS_IMMR + offsetof(ccsr_pic_t, tfrr)) +#define _POST_WORD_ADDR	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_PIC_OFFSET + \ +				offsetof(ccsr_pic_t, tfrr))  #elif defined (CONFIG_4xx)  #define _POST_WORD_ADDR \  |