linux/2.6.32: R.I.P.
SVN-Revision: 31597
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,244 +0,0 @@ | |||||||
| From 6c4419d997d4431bb62e73475cd6b084e83efbd1 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Tue, 22 Sep 2009 19:25:24 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: move zlib decompression wrapper code into a separate file |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/Makefile       |    2 +- |  | ||||||
|  fs/squashfs/block.c        |   74 ++---------------------------- |  | ||||||
|  fs/squashfs/squashfs.h     |    4 ++ |  | ||||||
|  fs/squashfs/zlib_wrapper.c |  109 ++++++++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  4 files changed, 118 insertions(+), 71 deletions(-) |  | ||||||
|  create mode 100644 fs/squashfs/zlib_wrapper.c |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/Makefile |  | ||||||
| +++ b/fs/squashfs/Makefile |  | ||||||
| @@ -4,4 +4,4 @@ |  | ||||||
|   |  | ||||||
|  obj-$(CONFIG_SQUASHFS) += squashfs.o |  | ||||||
|  squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o |  | ||||||
| -squashfs-y += namei.o super.o symlink.o |  | ||||||
| +squashfs-y += namei.o super.o symlink.o zlib_wrapper.o |  | ||||||
| --- a/fs/squashfs/block.c |  | ||||||
| +++ b/fs/squashfs/block.c |  | ||||||
| @@ -29,7 +29,6 @@ |  | ||||||
|  #include <linux/fs.h> |  | ||||||
|  #include <linux/vfs.h> |  | ||||||
|  #include <linux/slab.h> |  | ||||||
| -#include <linux/mutex.h> |  | ||||||
|  #include <linux/string.h> |  | ||||||
|  #include <linux/buffer_head.h> |  | ||||||
|  #include <linux/zlib.h> |  | ||||||
| @@ -153,72 +152,10 @@ int squashfs_read_data(struct super_bloc |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (compressed) { |  | ||||||
| -		int zlib_err = 0, zlib_init = 0; |  | ||||||
| - |  | ||||||
| -		/* |  | ||||||
| -		 * Uncompress block. |  | ||||||
| -		 */ |  | ||||||
| - |  | ||||||
| -		mutex_lock(&msblk->read_data_mutex); |  | ||||||
| - |  | ||||||
| -		msblk->stream.avail_out = 0; |  | ||||||
| -		msblk->stream.avail_in = 0; |  | ||||||
| - |  | ||||||
| -		bytes = length; |  | ||||||
| -		do { |  | ||||||
| -			if (msblk->stream.avail_in == 0 && k < b) { |  | ||||||
| -				avail = min(bytes, msblk->devblksize - offset); |  | ||||||
| -				bytes -= avail; |  | ||||||
| -				wait_on_buffer(bh[k]); |  | ||||||
| -				if (!buffer_uptodate(bh[k])) |  | ||||||
| -					goto release_mutex; |  | ||||||
| - |  | ||||||
| -				if (avail == 0) { |  | ||||||
| -					offset = 0; |  | ||||||
| -					put_bh(bh[k++]); |  | ||||||
| -					continue; |  | ||||||
| -				} |  | ||||||
| - |  | ||||||
| -				msblk->stream.next_in = bh[k]->b_data + offset; |  | ||||||
| -				msblk->stream.avail_in = avail; |  | ||||||
| -				offset = 0; |  | ||||||
| -			} |  | ||||||
| - |  | ||||||
| -			if (msblk->stream.avail_out == 0 && page < pages) { |  | ||||||
| -				msblk->stream.next_out = buffer[page++]; |  | ||||||
| -				msblk->stream.avail_out = PAGE_CACHE_SIZE; |  | ||||||
| -			} |  | ||||||
| - |  | ||||||
| -			if (!zlib_init) { |  | ||||||
| -				zlib_err = zlib_inflateInit(&msblk->stream); |  | ||||||
| -				if (zlib_err != Z_OK) { |  | ||||||
| -					ERROR("zlib_inflateInit returned" |  | ||||||
| -						" unexpected result 0x%x," |  | ||||||
| -						" srclength %d\n", zlib_err, |  | ||||||
| -						srclength); |  | ||||||
| -					goto release_mutex; |  | ||||||
| -				} |  | ||||||
| -				zlib_init = 1; |  | ||||||
| -			} |  | ||||||
| - |  | ||||||
| -			zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); |  | ||||||
| - |  | ||||||
| -			if (msblk->stream.avail_in == 0 && k < b) |  | ||||||
| -				put_bh(bh[k++]); |  | ||||||
| -		} while (zlib_err == Z_OK); |  | ||||||
| - |  | ||||||
| -		if (zlib_err != Z_STREAM_END) { |  | ||||||
| -			ERROR("zlib_inflate error, data probably corrupt\n"); |  | ||||||
| -			goto release_mutex; |  | ||||||
| -		} |  | ||||||
| - |  | ||||||
| -		zlib_err = zlib_inflateEnd(&msblk->stream); |  | ||||||
| -		if (zlib_err != Z_OK) { |  | ||||||
| -			ERROR("zlib_inflate error, data probably corrupt\n"); |  | ||||||
| -			goto release_mutex; |  | ||||||
| -		} |  | ||||||
| -		length = msblk->stream.total_out; |  | ||||||
| -		mutex_unlock(&msblk->read_data_mutex); |  | ||||||
| +		length = zlib_uncompress(msblk, buffer, bh, b, offset, length, |  | ||||||
| +			srclength, pages); |  | ||||||
| +		if (length < 0) |  | ||||||
| +			goto read_failure; |  | ||||||
|  	} else { |  | ||||||
|  		/* |  | ||||||
|  		 * Block is uncompressed. |  | ||||||
| @@ -255,9 +192,6 @@ int squashfs_read_data(struct super_bloc |  | ||||||
|  	kfree(bh); |  | ||||||
|  	return length; |  | ||||||
|   |  | ||||||
| -release_mutex: |  | ||||||
| -	mutex_unlock(&msblk->read_data_mutex); |  | ||||||
| - |  | ||||||
|  block_release: |  | ||||||
|  	for (; k < b; k++) |  | ||||||
|  		put_bh(bh[k]); |  | ||||||
| --- a/fs/squashfs/squashfs.h |  | ||||||
| +++ b/fs/squashfs/squashfs.h |  | ||||||
| @@ -70,6 +70,10 @@ extern struct inode *squashfs_iget(struc |  | ||||||
|  				unsigned int); |  | ||||||
|  extern int squashfs_read_inode(struct inode *, long long); |  | ||||||
|   |  | ||||||
| +/* zlib_wrapper.c */ |  | ||||||
| +extern int zlib_uncompress(struct squashfs_sb_info *, void **, |  | ||||||
| +				struct buffer_head **, int, int, int, int, int); |  | ||||||
| + |  | ||||||
|  /* |  | ||||||
|   * Inodes and files operations |  | ||||||
|   */ |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/fs/squashfs/zlib_wrapper.c |  | ||||||
| @@ -0,0 +1,109 @@ |  | ||||||
| +/* |  | ||||||
| + * Squashfs - a compressed read only filesystem for Linux |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |  | ||||||
| + * Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or |  | ||||||
| + * modify it under the terms of the GNU General Public License |  | ||||||
| + * as published by the Free Software Foundation; either version 2, |  | ||||||
| + * or (at your option) any later version. |  | ||||||
| + * |  | ||||||
| + * This program is distributed in the hope that it will be useful, |  | ||||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| + * GNU General Public License for more details. |  | ||||||
| + * |  | ||||||
| + * You should have received a copy of the GNU General Public License |  | ||||||
| + * along with this program; if not, write to the Free Software |  | ||||||
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |  | ||||||
| + * |  | ||||||
| + * zlib_wrapper.c |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +#include <linux/mutex.h> |  | ||||||
| +#include <linux/buffer_head.h> |  | ||||||
| +#include <linux/zlib.h> |  | ||||||
| + |  | ||||||
| +#include "squashfs_fs.h" |  | ||||||
| +#include "squashfs_fs_sb.h" |  | ||||||
| +#include "squashfs_fs_i.h" |  | ||||||
| +#include "squashfs.h" |  | ||||||
| + |  | ||||||
| +int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, |  | ||||||
| +	struct buffer_head **bh, int b, int offset, int length, int srclength, |  | ||||||
| +	int pages) |  | ||||||
| +{ |  | ||||||
| +	int zlib_err = 0, zlib_init = 0; |  | ||||||
| +	int avail, bytes, k = 0, page = 0; |  | ||||||
| + |  | ||||||
| +	mutex_lock(&msblk->read_data_mutex); |  | ||||||
| + |  | ||||||
| +	msblk->stream.avail_out = 0; |  | ||||||
| +	msblk->stream.avail_in = 0; |  | ||||||
| + |  | ||||||
| +	bytes = length; |  | ||||||
| +	do { |  | ||||||
| +		if (msblk->stream.avail_in == 0 && k < b) { |  | ||||||
| +			avail = min(bytes, msblk->devblksize - offset); |  | ||||||
| +			bytes -= avail; |  | ||||||
| +			wait_on_buffer(bh[k]); |  | ||||||
| +			if (!buffer_uptodate(bh[k])) |  | ||||||
| +				goto release_mutex; |  | ||||||
| + |  | ||||||
| +			if (avail == 0) { |  | ||||||
| +				offset = 0; |  | ||||||
| +				put_bh(bh[k++]); |  | ||||||
| +				continue; |  | ||||||
| +			} |  | ||||||
| + |  | ||||||
| +			msblk->stream.next_in = bh[k]->b_data + offset; |  | ||||||
| +			msblk->stream.avail_in = avail; |  | ||||||
| +			offset = 0; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		if (msblk->stream.avail_out == 0 && page < pages) { |  | ||||||
| +			msblk->stream.next_out = buffer[page++]; |  | ||||||
| +			msblk->stream.avail_out = PAGE_CACHE_SIZE; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		if (!zlib_init) { |  | ||||||
| +			zlib_err = zlib_inflateInit(&msblk->stream); |  | ||||||
| +			if (zlib_err != Z_OK) { |  | ||||||
| +				ERROR("zlib_inflateInit returned unexpected " |  | ||||||
| +					"result 0x%x, srclength %d\n", |  | ||||||
| +					zlib_err, srclength); |  | ||||||
| +				goto release_mutex; |  | ||||||
| +			} |  | ||||||
| +			zlib_init = 1; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); |  | ||||||
| + |  | ||||||
| +		if (msblk->stream.avail_in == 0 && k < b) |  | ||||||
| +			put_bh(bh[k++]); |  | ||||||
| +	} while (zlib_err == Z_OK); |  | ||||||
| + |  | ||||||
| +	if (zlib_err != Z_STREAM_END) { |  | ||||||
| +		ERROR("zlib_inflate error, data probably corrupt\n"); |  | ||||||
| +		goto release_mutex; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	zlib_err = zlib_inflateEnd(&msblk->stream); |  | ||||||
| +	if (zlib_err != Z_OK) { |  | ||||||
| +		ERROR("zlib_inflate error, data probably corrupt\n"); |  | ||||||
| +		goto release_mutex; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	mutex_unlock(&msblk->read_data_mutex); |  | ||||||
| +	return msblk->stream.total_out; |  | ||||||
| + |  | ||||||
| +release_mutex: |  | ||||||
| +	mutex_unlock(&msblk->read_data_mutex); |  | ||||||
| + |  | ||||||
| +	for (; k < b; k++) |  | ||||||
| +		put_bh(bh[k]); |  | ||||||
| + |  | ||||||
| +	return -EIO; |  | ||||||
| +} |  | ||||||
| @@ -1,317 +0,0 @@ | |||||||
| From 37c44e85fd49676ec15ccaeea065662c1fbcda7d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Wed, 23 Sep 2009 19:04:49 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: Factor out remaining zlib dependencies into separate wrapper file |  | ||||||
|  |  | ||||||
| Move zlib buffer init/destroy code into separate wrapper file.  Also |  | ||||||
| make zlib z_stream field a void * removing the need to include zlib.h |  | ||||||
| for most files. |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/block.c          |    1 - |  | ||||||
|  fs/squashfs/cache.c          |    1 - |  | ||||||
|  fs/squashfs/dir.c            |    1 - |  | ||||||
|  fs/squashfs/export.c         |    1 - |  | ||||||
|  fs/squashfs/file.c           |    1 - |  | ||||||
|  fs/squashfs/fragment.c       |    1 - |  | ||||||
|  fs/squashfs/id.c             |    1 - |  | ||||||
|  fs/squashfs/inode.c          |    1 - |  | ||||||
|  fs/squashfs/namei.c          |    1 - |  | ||||||
|  fs/squashfs/squashfs.h       |    2 + |  | ||||||
|  fs/squashfs/squashfs_fs_sb.h |    2 +- |  | ||||||
|  fs/squashfs/super.c          |   14 +++------ |  | ||||||
|  fs/squashfs/symlink.c        |    1 - |  | ||||||
|  fs/squashfs/zlib_wrapper.c   |   56 ++++++++++++++++++++++++++++++++--------- |  | ||||||
|  14 files changed, 51 insertions(+), 33 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/block.c |  | ||||||
| +++ b/fs/squashfs/block.c |  | ||||||
| @@ -31,7 +31,6 @@ |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|  #include <linux/string.h> |  | ||||||
|  #include <linux/buffer_head.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/cache.c |  | ||||||
| +++ b/fs/squashfs/cache.c |  | ||||||
| @@ -51,7 +51,6 @@ |  | ||||||
|  #include <linux/sched.h> |  | ||||||
|  #include <linux/spinlock.h> |  | ||||||
|  #include <linux/wait.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|  #include <linux/pagemap.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
| --- a/fs/squashfs/dir.c |  | ||||||
| +++ b/fs/squashfs/dir.c |  | ||||||
| @@ -30,7 +30,6 @@ |  | ||||||
|  #include <linux/fs.h> |  | ||||||
|  #include <linux/vfs.h> |  | ||||||
|  #include <linux/slab.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/export.c |  | ||||||
| +++ b/fs/squashfs/export.c |  | ||||||
| @@ -39,7 +39,6 @@ |  | ||||||
|  #include <linux/vfs.h> |  | ||||||
|  #include <linux/dcache.h> |  | ||||||
|  #include <linux/exportfs.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
| --- a/fs/squashfs/file.c |  | ||||||
| +++ b/fs/squashfs/file.c |  | ||||||
| @@ -47,7 +47,6 @@ |  | ||||||
|  #include <linux/string.h> |  | ||||||
|  #include <linux/pagemap.h> |  | ||||||
|  #include <linux/mutex.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/fragment.c |  | ||||||
| +++ b/fs/squashfs/fragment.c |  | ||||||
| @@ -36,7 +36,6 @@ |  | ||||||
|  #include <linux/fs.h> |  | ||||||
|  #include <linux/vfs.h> |  | ||||||
|  #include <linux/slab.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/id.c |  | ||||||
| +++ b/fs/squashfs/id.c |  | ||||||
| @@ -34,7 +34,6 @@ |  | ||||||
|  #include <linux/fs.h> |  | ||||||
|  #include <linux/vfs.h> |  | ||||||
|  #include <linux/slab.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/inode.c |  | ||||||
| +++ b/fs/squashfs/inode.c |  | ||||||
| @@ -40,7 +40,6 @@ |  | ||||||
|   |  | ||||||
|  #include <linux/fs.h> |  | ||||||
|  #include <linux/vfs.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/namei.c |  | ||||||
| +++ b/fs/squashfs/namei.c |  | ||||||
| @@ -57,7 +57,6 @@ |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|  #include <linux/string.h> |  | ||||||
|  #include <linux/dcache.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/squashfs.h |  | ||||||
| +++ b/fs/squashfs/squashfs.h |  | ||||||
| @@ -71,6 +71,8 @@ extern struct inode *squashfs_iget(struc |  | ||||||
|  extern int squashfs_read_inode(struct inode *, long long); |  | ||||||
|   |  | ||||||
|  /* zlib_wrapper.c */ |  | ||||||
| +extern void *zlib_init(void); |  | ||||||
| +extern void zlib_free(void *); |  | ||||||
|  extern int zlib_uncompress(struct squashfs_sb_info *, void **, |  | ||||||
|  				struct buffer_head **, int, int, int, int, int); |  | ||||||
|   |  | ||||||
| --- a/fs/squashfs/squashfs_fs_sb.h |  | ||||||
| +++ b/fs/squashfs/squashfs_fs_sb.h |  | ||||||
| @@ -64,7 +64,7 @@ struct squashfs_sb_info { |  | ||||||
|  	struct mutex		read_data_mutex; |  | ||||||
|  	struct mutex		meta_index_mutex; |  | ||||||
|  	struct meta_index	*meta_index; |  | ||||||
| -	z_stream		stream; |  | ||||||
| +	void			*stream; |  | ||||||
|  	__le64			*inode_lookup_table; |  | ||||||
|  	u64			inode_table; |  | ||||||
|  	u64			directory_table; |  | ||||||
| --- a/fs/squashfs/super.c |  | ||||||
| +++ b/fs/squashfs/super.c |  | ||||||
| @@ -35,7 +35,6 @@ |  | ||||||
|  #include <linux/pagemap.h> |  | ||||||
|  #include <linux/init.h> |  | ||||||
|  #include <linux/module.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|  #include <linux/magic.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
| @@ -87,12 +86,9 @@ static int squashfs_fill_super(struct su |  | ||||||
|  	} |  | ||||||
|  	msblk = sb->s_fs_info; |  | ||||||
|   |  | ||||||
| -	msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(), |  | ||||||
| -		GFP_KERNEL); |  | ||||||
| -	if (msblk->stream.workspace == NULL) { |  | ||||||
| -		ERROR("Failed to allocate zlib workspace\n"); |  | ||||||
| +	msblk->stream = zlib_init(); |  | ||||||
| +	if (msblk->stream == NULL) |  | ||||||
|  		goto failure; |  | ||||||
| -	} |  | ||||||
|   |  | ||||||
|  	sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); |  | ||||||
|  	if (sblk == NULL) { |  | ||||||
| @@ -292,17 +288,17 @@ failed_mount: |  | ||||||
|  	squashfs_cache_delete(msblk->block_cache); |  | ||||||
|  	squashfs_cache_delete(msblk->fragment_cache); |  | ||||||
|  	squashfs_cache_delete(msblk->read_page); |  | ||||||
| +	zlib_free(msblk->stream); |  | ||||||
|  	kfree(msblk->inode_lookup_table); |  | ||||||
|  	kfree(msblk->fragment_index); |  | ||||||
|  	kfree(msblk->id_table); |  | ||||||
| -	kfree(msblk->stream.workspace); |  | ||||||
|  	kfree(sb->s_fs_info); |  | ||||||
|  	sb->s_fs_info = NULL; |  | ||||||
|  	kfree(sblk); |  | ||||||
|  	return err; |  | ||||||
|   |  | ||||||
|  failure: |  | ||||||
| -	kfree(msblk->stream.workspace); |  | ||||||
| +	zlib_free(msblk->stream); |  | ||||||
|  	kfree(sb->s_fs_info); |  | ||||||
|  	sb->s_fs_info = NULL; |  | ||||||
|  	return -ENOMEM; |  | ||||||
| @@ -346,10 +342,10 @@ static void squashfs_put_super(struct su |  | ||||||
|  		squashfs_cache_delete(sbi->block_cache); |  | ||||||
|  		squashfs_cache_delete(sbi->fragment_cache); |  | ||||||
|  		squashfs_cache_delete(sbi->read_page); |  | ||||||
| +		zlib_free(sbi->stream); |  | ||||||
|  		kfree(sbi->id_table); |  | ||||||
|  		kfree(sbi->fragment_index); |  | ||||||
|  		kfree(sbi->meta_index); |  | ||||||
| -		kfree(sbi->stream.workspace); |  | ||||||
|  		kfree(sb->s_fs_info); |  | ||||||
|  		sb->s_fs_info = NULL; |  | ||||||
|  	} |  | ||||||
| --- a/fs/squashfs/symlink.c |  | ||||||
| +++ b/fs/squashfs/symlink.c |  | ||||||
| @@ -36,7 +36,6 @@ |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|  #include <linux/string.h> |  | ||||||
|  #include <linux/pagemap.h> |  | ||||||
| -#include <linux/zlib.h> |  | ||||||
|   |  | ||||||
|  #include "squashfs_fs.h" |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
| --- a/fs/squashfs/zlib_wrapper.c |  | ||||||
| +++ b/fs/squashfs/zlib_wrapper.c |  | ||||||
| @@ -31,21 +31,51 @@ |  | ||||||
|  #include "squashfs_fs_i.h" |  | ||||||
|  #include "squashfs.h" |  | ||||||
|   |  | ||||||
| +void *zlib_init() |  | ||||||
| +{ |  | ||||||
| +	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); |  | ||||||
| +	if (stream == NULL) |  | ||||||
| +		goto failed; |  | ||||||
| +	stream->workspace = kmalloc(zlib_inflate_workspacesize(), |  | ||||||
| +		GFP_KERNEL); |  | ||||||
| +	if (stream->workspace == NULL) |  | ||||||
| +		goto failed; |  | ||||||
| + |  | ||||||
| +	return stream; |  | ||||||
| + |  | ||||||
| +failed: |  | ||||||
| +	ERROR("Failed to allocate zlib workspace\n"); |  | ||||||
| +	kfree(stream); |  | ||||||
| +	return NULL; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +void zlib_free(void *strm) |  | ||||||
| +{ |  | ||||||
| +	z_stream *stream = strm; |  | ||||||
| + |  | ||||||
| +	if (stream) |  | ||||||
| +		kfree(stream->workspace); |  | ||||||
| +	kfree(stream); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
|  int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, |  | ||||||
|  	struct buffer_head **bh, int b, int offset, int length, int srclength, |  | ||||||
|  	int pages) |  | ||||||
|  { |  | ||||||
|  	int zlib_err = 0, zlib_init = 0; |  | ||||||
|  	int avail, bytes, k = 0, page = 0; |  | ||||||
| +	z_stream *stream = msblk->stream; |  | ||||||
|   |  | ||||||
|  	mutex_lock(&msblk->read_data_mutex); |  | ||||||
|   |  | ||||||
| -	msblk->stream.avail_out = 0; |  | ||||||
| -	msblk->stream.avail_in = 0; |  | ||||||
| +	stream->avail_out = 0; |  | ||||||
| +	stream->avail_in = 0; |  | ||||||
|   |  | ||||||
|  	bytes = length; |  | ||||||
|  	do { |  | ||||||
| -		if (msblk->stream.avail_in == 0 && k < b) { |  | ||||||
| +		if (stream->avail_in == 0 && k < b) { |  | ||||||
|  			avail = min(bytes, msblk->devblksize - offset); |  | ||||||
|  			bytes -= avail; |  | ||||||
|  			wait_on_buffer(bh[k]); |  | ||||||
| @@ -58,18 +88,18 @@ int zlib_uncompress(struct squashfs_sb_i |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
|   |  | ||||||
| -			msblk->stream.next_in = bh[k]->b_data + offset; |  | ||||||
| -			msblk->stream.avail_in = avail; |  | ||||||
| +			stream->next_in = bh[k]->b_data + offset; |  | ||||||
| +			stream->avail_in = avail; |  | ||||||
|  			offset = 0; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| -		if (msblk->stream.avail_out == 0 && page < pages) { |  | ||||||
| -			msblk->stream.next_out = buffer[page++]; |  | ||||||
| -			msblk->stream.avail_out = PAGE_CACHE_SIZE; |  | ||||||
| +		if (stream->avail_out == 0 && page < pages) { |  | ||||||
| +			stream->next_out = buffer[page++]; |  | ||||||
| +			stream->avail_out = PAGE_CACHE_SIZE; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		if (!zlib_init) { |  | ||||||
| -			zlib_err = zlib_inflateInit(&msblk->stream); |  | ||||||
| +			zlib_err = zlib_inflateInit(stream); |  | ||||||
|  			if (zlib_err != Z_OK) { |  | ||||||
|  				ERROR("zlib_inflateInit returned unexpected " |  | ||||||
|  					"result 0x%x, srclength %d\n", |  | ||||||
| @@ -79,9 +109,9 @@ int zlib_uncompress(struct squashfs_sb_i |  | ||||||
|  			zlib_init = 1; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| -		zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); |  | ||||||
| +		zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH); |  | ||||||
|   |  | ||||||
| -		if (msblk->stream.avail_in == 0 && k < b) |  | ||||||
| +		if (stream->avail_in == 0 && k < b) |  | ||||||
|  			put_bh(bh[k++]); |  | ||||||
|  	} while (zlib_err == Z_OK); |  | ||||||
|   |  | ||||||
| @@ -90,14 +120,14 @@ int zlib_uncompress(struct squashfs_sb_i |  | ||||||
|  		goto release_mutex; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	zlib_err = zlib_inflateEnd(&msblk->stream); |  | ||||||
| +	zlib_err = zlib_inflateEnd(stream); |  | ||||||
|  	if (zlib_err != Z_OK) { |  | ||||||
|  		ERROR("zlib_inflate error, data probably corrupt\n"); |  | ||||||
|  		goto release_mutex; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	mutex_unlock(&msblk->read_data_mutex); |  | ||||||
| -	return msblk->stream.total_out; |  | ||||||
| +	return stream->total_out; |  | ||||||
|   |  | ||||||
|  release_mutex: |  | ||||||
|  	mutex_unlock(&msblk->read_data_mutex); |  | ||||||
| @@ -1,426 +0,0 @@ | |||||||
| From 327fbf47a419befc6bff74f3ca42d2b6f0841903 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Tue, 6 Oct 2009 04:04:15 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: add a decompressor framework |  | ||||||
|  |  | ||||||
| This adds a decompressor framework which allows multiple compression |  | ||||||
| algorithms to be cleanly supported. |  | ||||||
|  |  | ||||||
| Also update zlib wrapper and other code to use the new framework. |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/Makefile         |    2 +- |  | ||||||
|  fs/squashfs/block.c          |    6 ++-- |  | ||||||
|  fs/squashfs/decompressor.c   |   58 ++++++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  fs/squashfs/decompressor.h   |   55 +++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  fs/squashfs/squashfs.h       |   14 +++++----- |  | ||||||
|  fs/squashfs/squashfs_fs_sb.h |   41 +++++++++++++++-------------- |  | ||||||
|  fs/squashfs/super.c          |   45 ++++++++++++++++++------------- |  | ||||||
|  fs/squashfs/zlib_wrapper.c   |   17 ++++++++++-- |  | ||||||
|  8 files changed, 185 insertions(+), 53 deletions(-) |  | ||||||
|  create mode 100644 fs/squashfs/decompressor.c |  | ||||||
|  create mode 100644 fs/squashfs/decompressor.h |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/Makefile |  | ||||||
| +++ b/fs/squashfs/Makefile |  | ||||||
| @@ -4,4 +4,4 @@ |  | ||||||
|   |  | ||||||
|  obj-$(CONFIG_SQUASHFS) += squashfs.o |  | ||||||
|  squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o |  | ||||||
| -squashfs-y += namei.o super.o symlink.o zlib_wrapper.o |  | ||||||
| +squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o |  | ||||||
| --- a/fs/squashfs/block.c |  | ||||||
| +++ b/fs/squashfs/block.c |  | ||||||
| @@ -36,7 +36,7 @@ |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
|  #include "squashfs_fs_i.h" |  | ||||||
|  #include "squashfs.h" |  | ||||||
| - |  | ||||||
| +#include "decompressor.h" |  | ||||||
|  /* |  | ||||||
|   * Read the metadata block length, this is stored in the first two |  | ||||||
|   * bytes of the metadata block. |  | ||||||
| @@ -151,8 +151,8 @@ int squashfs_read_data(struct super_bloc |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (compressed) { |  | ||||||
| -		length = zlib_uncompress(msblk, buffer, bh, b, offset, length, |  | ||||||
| -			srclength, pages); |  | ||||||
| +		length = squashfs_decompress(msblk, buffer, bh, b, offset, |  | ||||||
| +			length, srclength, pages); |  | ||||||
|  		if (length < 0) |  | ||||||
|  			goto read_failure; |  | ||||||
|  	} else { |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/fs/squashfs/decompressor.c |  | ||||||
| @@ -0,0 +1,58 @@ |  | ||||||
| +/* |  | ||||||
| + * Squashfs - a compressed read only filesystem for Linux |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |  | ||||||
| + * Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or |  | ||||||
| + * modify it under the terms of the GNU General Public License |  | ||||||
| + * as published by the Free Software Foundation; either version 2, |  | ||||||
| + * or (at your option) any later version. |  | ||||||
| + * |  | ||||||
| + * This program is distributed in the hope that it will be useful, |  | ||||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| + * GNU General Public License for more details. |  | ||||||
| + * |  | ||||||
| + * You should have received a copy of the GNU General Public License |  | ||||||
| + * along with this program; if not, write to the Free Software |  | ||||||
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |  | ||||||
| + * |  | ||||||
| + * decompressor.c |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/types.h> |  | ||||||
| +#include <linux/mutex.h> |  | ||||||
| +#include <linux/buffer_head.h> |  | ||||||
| + |  | ||||||
| +#include "squashfs_fs.h" |  | ||||||
| +#include "squashfs_fs_sb.h" |  | ||||||
| +#include "squashfs_fs_i.h" |  | ||||||
| +#include "decompressor.h" |  | ||||||
| +#include "squashfs.h" |  | ||||||
| + |  | ||||||
| +/* |  | ||||||
| + * This file (and decompressor.h) implements a decompressor framework for |  | ||||||
| + * Squashfs, allowing multiple decompressors to be easily supported |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +static const struct squashfs_decompressor squashfs_unknown_comp_ops = { |  | ||||||
| +	NULL, NULL, NULL, 0, "unknown", 0 |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static const struct squashfs_decompressor *decompressor[] = { |  | ||||||
| +	&squashfs_zlib_comp_ops, |  | ||||||
| +	&squashfs_unknown_comp_ops |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +const struct squashfs_decompressor *squashfs_lookup_decompressor(int id) |  | ||||||
| +{ |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	for (i = 0; decompressor[i]->id; i++) |  | ||||||
| +		if (id == decompressor[i]->id) |  | ||||||
| +			break; |  | ||||||
| + |  | ||||||
| +	return decompressor[i]; |  | ||||||
| +} |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/fs/squashfs/decompressor.h |  | ||||||
| @@ -0,0 +1,55 @@ |  | ||||||
| +#ifndef DECOMPRESSOR_H |  | ||||||
| +#define DECOMPRESSOR_H |  | ||||||
| +/* |  | ||||||
| + * Squashfs - a compressed read only filesystem for Linux |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |  | ||||||
| + * Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or |  | ||||||
| + * modify it under the terms of the GNU General Public License |  | ||||||
| + * as published by the Free Software Foundation; either version 2, |  | ||||||
| + * or (at your option) any later version. |  | ||||||
| + * |  | ||||||
| + * This program is distributed in the hope that it will be useful, |  | ||||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| + * GNU General Public License for more details. |  | ||||||
| + * |  | ||||||
| + * You should have received a copy of the GNU General Public License |  | ||||||
| + * along with this program; if not, write to the Free Software |  | ||||||
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |  | ||||||
| + * |  | ||||||
| + * decompressor.h |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +struct squashfs_decompressor { |  | ||||||
| +	void	*(*init)(void); |  | ||||||
| +	void	(*free)(void *); |  | ||||||
| +	int	(*decompress)(struct squashfs_sb_info *, void **, |  | ||||||
| +		struct buffer_head **, int, int, int, int, int); |  | ||||||
| +	int	id; |  | ||||||
| +	char	*name; |  | ||||||
| +	int	supported; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk) |  | ||||||
| +{ |  | ||||||
| +	return msblk->decompressor->init(); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk, |  | ||||||
| +	void *s) |  | ||||||
| +{ |  | ||||||
| +	if (msblk->decompressor) |  | ||||||
| +		msblk->decompressor->free(s); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline int squashfs_decompress(struct squashfs_sb_info *msblk, |  | ||||||
| +	void **buffer, struct buffer_head **bh, int b, int offset, int length, |  | ||||||
| +	int srclength, int pages) |  | ||||||
| +{ |  | ||||||
| +	return msblk->decompressor->decompress(msblk, buffer, bh, b, offset, |  | ||||||
| +		length, srclength, pages); |  | ||||||
| +} |  | ||||||
| +#endif |  | ||||||
| --- a/fs/squashfs/squashfs.h |  | ||||||
| +++ b/fs/squashfs/squashfs.h |  | ||||||
| @@ -51,6 +51,9 @@ extern struct squashfs_cache_entry *squa |  | ||||||
|  				u64, int); |  | ||||||
|  extern int squashfs_read_table(struct super_block *, void *, u64, int); |  | ||||||
|   |  | ||||||
| +/* decompressor.c */ |  | ||||||
| +extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); |  | ||||||
| + |  | ||||||
|  /* export.c */ |  | ||||||
|  extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, |  | ||||||
|  				unsigned int); |  | ||||||
| @@ -70,14 +73,8 @@ extern struct inode *squashfs_iget(struc |  | ||||||
|  				unsigned int); |  | ||||||
|  extern int squashfs_read_inode(struct inode *, long long); |  | ||||||
|   |  | ||||||
| -/* zlib_wrapper.c */ |  | ||||||
| -extern void *zlib_init(void); |  | ||||||
| -extern void zlib_free(void *); |  | ||||||
| -extern int zlib_uncompress(struct squashfs_sb_info *, void **, |  | ||||||
| -				struct buffer_head **, int, int, int, int, int); |  | ||||||
| - |  | ||||||
|  /* |  | ||||||
| - * Inodes and files operations |  | ||||||
| + * Inodes, files and decompressor operations |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
|  /* dir.c */ |  | ||||||
| @@ -94,3 +91,6 @@ extern const struct inode_operations squ |  | ||||||
|   |  | ||||||
|  /* symlink.c */ |  | ||||||
|  extern const struct address_space_operations squashfs_symlink_aops; |  | ||||||
| + |  | ||||||
| +/* zlib_wrapper.c */ |  | ||||||
| +extern const struct squashfs_decompressor squashfs_zlib_comp_ops; |  | ||||||
| --- a/fs/squashfs/squashfs_fs_sb.h |  | ||||||
| +++ b/fs/squashfs/squashfs_fs_sb.h |  | ||||||
| @@ -52,25 +52,26 @@ struct squashfs_cache_entry { |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  struct squashfs_sb_info { |  | ||||||
| -	int			devblksize; |  | ||||||
| -	int			devblksize_log2; |  | ||||||
| -	struct squashfs_cache	*block_cache; |  | ||||||
| -	struct squashfs_cache	*fragment_cache; |  | ||||||
| -	struct squashfs_cache	*read_page; |  | ||||||
| -	int			next_meta_index; |  | ||||||
| -	__le64			*id_table; |  | ||||||
| -	__le64			*fragment_index; |  | ||||||
| -	unsigned int		*fragment_index_2; |  | ||||||
| -	struct mutex		read_data_mutex; |  | ||||||
| -	struct mutex		meta_index_mutex; |  | ||||||
| -	struct meta_index	*meta_index; |  | ||||||
| -	void			*stream; |  | ||||||
| -	__le64			*inode_lookup_table; |  | ||||||
| -	u64			inode_table; |  | ||||||
| -	u64			directory_table; |  | ||||||
| -	unsigned int		block_size; |  | ||||||
| -	unsigned short		block_log; |  | ||||||
| -	long long		bytes_used; |  | ||||||
| -	unsigned int		inodes; |  | ||||||
| +	const struct squashfs_decompressor	*decompressor; |  | ||||||
| +	int					devblksize; |  | ||||||
| +	int					devblksize_log2; |  | ||||||
| +	struct squashfs_cache			*block_cache; |  | ||||||
| +	struct squashfs_cache			*fragment_cache; |  | ||||||
| +	struct squashfs_cache			*read_page; |  | ||||||
| +	int					next_meta_index; |  | ||||||
| +	__le64					*id_table; |  | ||||||
| +	__le64					*fragment_index; |  | ||||||
| +	unsigned int				*fragment_index_2; |  | ||||||
| +	struct mutex				read_data_mutex; |  | ||||||
| +	struct mutex				meta_index_mutex; |  | ||||||
| +	struct meta_index			*meta_index; |  | ||||||
| +	void					*stream; |  | ||||||
| +	__le64					*inode_lookup_table; |  | ||||||
| +	u64					inode_table; |  | ||||||
| +	u64					directory_table; |  | ||||||
| +	unsigned int				block_size; |  | ||||||
| +	unsigned short				block_log; |  | ||||||
| +	long long				bytes_used; |  | ||||||
| +	unsigned int				inodes; |  | ||||||
|  }; |  | ||||||
|  #endif |  | ||||||
| --- a/fs/squashfs/super.c |  | ||||||
| +++ b/fs/squashfs/super.c |  | ||||||
| @@ -41,27 +41,35 @@ |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
|  #include "squashfs_fs_i.h" |  | ||||||
|  #include "squashfs.h" |  | ||||||
| +#include "decompressor.h" |  | ||||||
|   |  | ||||||
|  static struct file_system_type squashfs_fs_type; |  | ||||||
|  static const struct super_operations squashfs_super_ops; |  | ||||||
|   |  | ||||||
| -static int supported_squashfs_filesystem(short major, short minor, short comp) |  | ||||||
| +static const struct squashfs_decompressor *supported_squashfs_filesystem(short |  | ||||||
| +	major, short minor, short id) |  | ||||||
|  { |  | ||||||
| +	const struct squashfs_decompressor *decompressor; |  | ||||||
| + |  | ||||||
|  	if (major < SQUASHFS_MAJOR) { |  | ||||||
|  		ERROR("Major/Minor mismatch, older Squashfs %d.%d " |  | ||||||
|  			"filesystems are unsupported\n", major, minor); |  | ||||||
| -		return -EINVAL; |  | ||||||
| +		return NULL; |  | ||||||
|  	} else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { |  | ||||||
|  		ERROR("Major/Minor mismatch, trying to mount newer " |  | ||||||
|  			"%d.%d filesystem\n", major, minor); |  | ||||||
|  		ERROR("Please update your kernel\n"); |  | ||||||
| -		return -EINVAL; |  | ||||||
| +		return NULL; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	if (comp != ZLIB_COMPRESSION) |  | ||||||
| -		return -EINVAL; |  | ||||||
| +	decompressor = squashfs_lookup_decompressor(id); |  | ||||||
| +	if (!decompressor->supported) { |  | ||||||
| +		ERROR("Filesystem uses \"%s\" compression. This is not " |  | ||||||
| +			"supported\n", decompressor->name); |  | ||||||
| +		return NULL; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
| -	return 0; |  | ||||||
| +	return decompressor; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -86,10 +94,6 @@ static int squashfs_fill_super(struct su |  | ||||||
|  	} |  | ||||||
|  	msblk = sb->s_fs_info; |  | ||||||
|   |  | ||||||
| -	msblk->stream = zlib_init(); |  | ||||||
| -	if (msblk->stream == NULL) |  | ||||||
| -		goto failure; |  | ||||||
| - |  | ||||||
|  	sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); |  | ||||||
|  	if (sblk == NULL) { |  | ||||||
|  		ERROR("Failed to allocate squashfs_super_block\n"); |  | ||||||
| @@ -116,25 +120,25 @@ static int squashfs_fill_super(struct su |  | ||||||
|  		goto failed_mount; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	err = -EINVAL; |  | ||||||
| + |  | ||||||
|  	/* Check it is a SQUASHFS superblock */ |  | ||||||
|  	sb->s_magic = le32_to_cpu(sblk->s_magic); |  | ||||||
|  	if (sb->s_magic != SQUASHFS_MAGIC) { |  | ||||||
|  		if (!silent) |  | ||||||
|  			ERROR("Can't find a SQUASHFS superblock on %s\n", |  | ||||||
|  						bdevname(sb->s_bdev, b)); |  | ||||||
| -		err = -EINVAL; |  | ||||||
|  		goto failed_mount; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	/* Check the MAJOR & MINOR versions and compression type */ |  | ||||||
| -	err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major), |  | ||||||
| +	/* Check the MAJOR & MINOR versions and lookup compression type */ |  | ||||||
| +	msblk->decompressor = supported_squashfs_filesystem( |  | ||||||
| +			le16_to_cpu(sblk->s_major), |  | ||||||
|  			le16_to_cpu(sblk->s_minor), |  | ||||||
|  			le16_to_cpu(sblk->compression)); |  | ||||||
| -	if (err < 0) |  | ||||||
| +	if (msblk->decompressor == NULL) |  | ||||||
|  		goto failed_mount; |  | ||||||
|   |  | ||||||
| -	err = -EINVAL; |  | ||||||
| - |  | ||||||
|  	/* |  | ||||||
|  	 * Check if there's xattrs in the filesystem.  These are not |  | ||||||
|  	 * supported in this version, so warn that they will be ignored. |  | ||||||
| @@ -201,6 +205,10 @@ static int squashfs_fill_super(struct su |  | ||||||
|   |  | ||||||
|  	err = -ENOMEM; |  | ||||||
|   |  | ||||||
| +	msblk->stream = squashfs_decompressor_init(msblk); |  | ||||||
| +	if (msblk->stream == NULL) |  | ||||||
| +		goto failed_mount; |  | ||||||
| + |  | ||||||
|  	msblk->block_cache = squashfs_cache_init("metadata", |  | ||||||
|  			SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); |  | ||||||
|  	if (msblk->block_cache == NULL) |  | ||||||
| @@ -288,7 +296,7 @@ failed_mount: |  | ||||||
|  	squashfs_cache_delete(msblk->block_cache); |  | ||||||
|  	squashfs_cache_delete(msblk->fragment_cache); |  | ||||||
|  	squashfs_cache_delete(msblk->read_page); |  | ||||||
| -	zlib_free(msblk->stream); |  | ||||||
| +	squashfs_decompressor_free(msblk, msblk->stream); |  | ||||||
|  	kfree(msblk->inode_lookup_table); |  | ||||||
|  	kfree(msblk->fragment_index); |  | ||||||
|  	kfree(msblk->id_table); |  | ||||||
| @@ -298,7 +306,6 @@ failed_mount: |  | ||||||
|  	return err; |  | ||||||
|   |  | ||||||
|  failure: |  | ||||||
| -	zlib_free(msblk->stream); |  | ||||||
|  	kfree(sb->s_fs_info); |  | ||||||
|  	sb->s_fs_info = NULL; |  | ||||||
|  	return -ENOMEM; |  | ||||||
| @@ -342,7 +349,7 @@ static void squashfs_put_super(struct su |  | ||||||
|  		squashfs_cache_delete(sbi->block_cache); |  | ||||||
|  		squashfs_cache_delete(sbi->fragment_cache); |  | ||||||
|  		squashfs_cache_delete(sbi->read_page); |  | ||||||
| -		zlib_free(sbi->stream); |  | ||||||
| +		squashfs_decompressor_free(sbi, sbi->stream); |  | ||||||
|  		kfree(sbi->id_table); |  | ||||||
|  		kfree(sbi->fragment_index); |  | ||||||
|  		kfree(sbi->meta_index); |  | ||||||
| --- a/fs/squashfs/zlib_wrapper.c |  | ||||||
| +++ b/fs/squashfs/zlib_wrapper.c |  | ||||||
| @@ -30,8 +30,9 @@ |  | ||||||
|  #include "squashfs_fs_sb.h" |  | ||||||
|  #include "squashfs_fs_i.h" |  | ||||||
|  #include "squashfs.h" |  | ||||||
| +#include "decompressor.h" |  | ||||||
|   |  | ||||||
| -void *zlib_init() |  | ||||||
| +static void *zlib_init(void) |  | ||||||
|  { |  | ||||||
|  	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); |  | ||||||
|  	if (stream == NULL) |  | ||||||
| @@ -50,7 +51,7 @@ failed: |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -void zlib_free(void *strm) |  | ||||||
| +static void zlib_free(void *strm) |  | ||||||
|  { |  | ||||||
|  	z_stream *stream = strm; |  | ||||||
|   |  | ||||||
| @@ -60,7 +61,7 @@ void zlib_free(void *strm) |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, |  | ||||||
| +static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, |  | ||||||
|  	struct buffer_head **bh, int b, int offset, int length, int srclength, |  | ||||||
|  	int pages) |  | ||||||
|  { |  | ||||||
| @@ -137,3 +138,13 @@ release_mutex: |  | ||||||
|   |  | ||||||
|  	return -EIO; |  | ||||||
|  } |  | ||||||
| + |  | ||||||
| +const struct squashfs_decompressor squashfs_zlib_comp_ops = { |  | ||||||
| +	.init = zlib_init, |  | ||||||
| +	.free = zlib_free, |  | ||||||
| +	.decompress = zlib_uncompress, |  | ||||||
| +	.id = ZLIB_COMPRESSION, |  | ||||||
| +	.name = "zlib", |  | ||||||
| +	.supported = 1 |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| From 1885ca0a1973944684f252094a703b7c80dfc974 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Wed, 14 Oct 2009 03:58:11 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: add decompressor entries for lzma and lzo |  | ||||||
|  |  | ||||||
| Add knowledge of lzma/lzo compression formats to the decompressor |  | ||||||
| framework.  For now these are added as unsupported.  Without |  | ||||||
| these entries lzma/lzo compressed filesystems will be flagged as |  | ||||||
| having unknown compression which is undesirable. |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/decompressor.c |   10 ++++++++++ |  | ||||||
|  fs/squashfs/squashfs_fs.h  |    4 +++- |  | ||||||
|  2 files changed, 13 insertions(+), 1 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/decompressor.c |  | ||||||
| +++ b/fs/squashfs/decompressor.c |  | ||||||
| @@ -36,12 +36,22 @@ |  | ||||||
|   * Squashfs, allowing multiple decompressors to be easily supported |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
| +static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = { |  | ||||||
| +	NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = { |  | ||||||
| +	NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
|  static const struct squashfs_decompressor squashfs_unknown_comp_ops = { |  | ||||||
|  	NULL, NULL, NULL, 0, "unknown", 0 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  static const struct squashfs_decompressor *decompressor[] = { |  | ||||||
|  	&squashfs_zlib_comp_ops, |  | ||||||
| +	&squashfs_lzma_unsupported_comp_ops, |  | ||||||
| +	&squashfs_lzo_unsupported_comp_ops, |  | ||||||
|  	&squashfs_unknown_comp_ops |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| --- a/fs/squashfs/squashfs_fs.h |  | ||||||
| +++ b/fs/squashfs/squashfs_fs.h |  | ||||||
| @@ -211,7 +211,9 @@ struct meta_index { |  | ||||||
|  /* |  | ||||||
|   * definitions for structures on disk |  | ||||||
|   */ |  | ||||||
| -#define ZLIB_COMPRESSION	 1 |  | ||||||
| +#define ZLIB_COMPRESSION	1 |  | ||||||
| +#define LZMA_COMPRESSION	2 |  | ||||||
| +#define LZO_COMPRESSION		3 |  | ||||||
|   |  | ||||||
|  struct squashfs_super_block { |  | ||||||
|  	__le32			s_magic; |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| From 5f393ede3ddb5dd4cc2a9f243182fac45f1ce10b Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Wed, 14 Oct 2009 04:07:54 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: add an extra parameter to the decompressor init function |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/decompressor.h |    4 ++-- |  | ||||||
|  fs/squashfs/zlib_wrapper.c |    2 +- |  | ||||||
|  2 files changed, 3 insertions(+), 3 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/decompressor.h |  | ||||||
| +++ b/fs/squashfs/decompressor.h |  | ||||||
| @@ -24,7 +24,7 @@ |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
|  struct squashfs_decompressor { |  | ||||||
| -	void	*(*init)(void); |  | ||||||
| +	void	*(*init)(struct squashfs_sb_info *); |  | ||||||
|  	void	(*free)(void *); |  | ||||||
|  	int	(*decompress)(struct squashfs_sb_info *, void **, |  | ||||||
|  		struct buffer_head **, int, int, int, int, int); |  | ||||||
| @@ -35,7 +35,7 @@ struct squashfs_decompressor { |  | ||||||
|   |  | ||||||
|  static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk) |  | ||||||
|  { |  | ||||||
| -	return msblk->decompressor->init(); |  | ||||||
| +	return msblk->decompressor->init(msblk); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk, |  | ||||||
| --- a/fs/squashfs/zlib_wrapper.c |  | ||||||
| +++ b/fs/squashfs/zlib_wrapper.c |  | ||||||
| @@ -32,7 +32,7 @@ |  | ||||||
|  #include "squashfs.h" |  | ||||||
|  #include "decompressor.h" |  | ||||||
|   |  | ||||||
| -static void *zlib_init(void) |  | ||||||
| +static void *zlib_init(struct squashfs_sb_info *dummy) |  | ||||||
|  { |  | ||||||
|  	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); |  | ||||||
|  	if (stream == NULL) |  | ||||||
| @@ -1,216 +0,0 @@ | |||||||
| From f49e1efdd179d54e814ff2a8e8f469496583062c Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Tue, 20 Oct 2009 10:54:36 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: add LZMA compression |  | ||||||
|  |  | ||||||
| Add support for LZMA compressed filesystems.  This is an initial |  | ||||||
| implementation. |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/Kconfig        |    5 ++ |  | ||||||
|  fs/squashfs/Makefile       |    1 + |  | ||||||
|  fs/squashfs/decompressor.c |    4 + |  | ||||||
|  fs/squashfs/lzma_wrapper.c |  151 ++++++++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  fs/squashfs/squashfs.h     |    3 + |  | ||||||
|  5 files changed, 164 insertions(+), 0 deletions(-) |  | ||||||
|  create mode 100644 fs/squashfs/lzma_wrapper.c |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/Kconfig |  | ||||||
| +++ b/fs/squashfs/Kconfig |  | ||||||
| @@ -26,6 +26,11 @@ config SQUASHFS |  | ||||||
|   |  | ||||||
|  	  If unsure, say N. |  | ||||||
|   |  | ||||||
| +config SQUASHFS_LZMA |  | ||||||
| +	bool "Include support for LZMA compressed file systems" |  | ||||||
| +	depends on SQUASHFS |  | ||||||
| +	select DECOMPRESS_LZMA |  | ||||||
| + |  | ||||||
|  config SQUASHFS_EMBEDDED |  | ||||||
|   |  | ||||||
|  	bool "Additional option for memory-constrained systems"  |  | ||||||
| --- a/fs/squashfs/Makefile |  | ||||||
| +++ b/fs/squashfs/Makefile |  | ||||||
| @@ -5,3 +5,4 @@ |  | ||||||
|  obj-$(CONFIG_SQUASHFS) += squashfs.o |  | ||||||
|  squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o |  | ||||||
|  squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o |  | ||||||
| +squashfs-$(CONFIG_SQUASHFS_LZMA) += lzma_wrapper.o |  | ||||||
| --- a/fs/squashfs/decompressor.c |  | ||||||
| +++ b/fs/squashfs/decompressor.c |  | ||||||
| @@ -50,7 +50,11 @@ static const struct squashfs_decompresso |  | ||||||
|   |  | ||||||
|  static const struct squashfs_decompressor *decompressor[] = { |  | ||||||
|  	&squashfs_zlib_comp_ops, |  | ||||||
| +#ifdef CONFIG_SQUASHFS_LZMA |  | ||||||
| +	&squashfs_lzma_comp_ops, |  | ||||||
| +#else |  | ||||||
|  	&squashfs_lzma_unsupported_comp_ops, |  | ||||||
| +#endif |  | ||||||
|  	&squashfs_lzo_unsupported_comp_ops, |  | ||||||
|  	&squashfs_unknown_comp_ops |  | ||||||
|  }; |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/fs/squashfs/lzma_wrapper.c |  | ||||||
| @@ -0,0 +1,151 @@ |  | ||||||
| +/* |  | ||||||
| + * Squashfs - a compressed read only filesystem for Linux |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |  | ||||||
| + * Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or |  | ||||||
| + * modify it under the terms of the GNU General Public License |  | ||||||
| + * as published by the Free Software Foundation; either version 2, |  | ||||||
| + * or (at your option) any later version. |  | ||||||
| + * |  | ||||||
| + * This program is distributed in the hope that it will be useful, |  | ||||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| + * GNU General Public License for more details. |  | ||||||
| + * |  | ||||||
| + * You should have received a copy of the GNU General Public License |  | ||||||
| + * along with this program; if not, write to the Free Software |  | ||||||
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |  | ||||||
| + * |  | ||||||
| + * lzma_wrapper.c |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <asm/unaligned.h> |  | ||||||
| +#include <linux/buffer_head.h> |  | ||||||
| +#include <linux/mutex.h> |  | ||||||
| +#include <linux/vmalloc.h> |  | ||||||
| +#include <linux/decompress/unlzma.h> |  | ||||||
| + |  | ||||||
| +#include "squashfs_fs.h" |  | ||||||
| +#include "squashfs_fs_sb.h" |  | ||||||
| +#include "squashfs_fs_i.h" |  | ||||||
| +#include "squashfs.h" |  | ||||||
| +#include "decompressor.h" |  | ||||||
| + |  | ||||||
| +struct squashfs_lzma { |  | ||||||
| +	void	*input; |  | ||||||
| +	void	*output; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/* decompress_unlzma.c is currently non re-entrant... */ |  | ||||||
| +DEFINE_MUTEX(lzma_mutex); |  | ||||||
| + |  | ||||||
| +/* decompress_unlzma.c doesn't provide any context in its callbacks... */ |  | ||||||
| +static int lzma_error; |  | ||||||
| + |  | ||||||
| +static void error(char *m) |  | ||||||
| +{ |  | ||||||
| +	ERROR("unlzma error: %s\n", m); |  | ||||||
| +	lzma_error = 1; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +	 |  | ||||||
| +static void *lzma_init(struct squashfs_sb_info *msblk) |  | ||||||
| +{ |  | ||||||
| +	struct squashfs_lzma *stream = kzalloc(sizeof(*stream), GFP_KERNEL); |  | ||||||
| +	if (stream == NULL) |  | ||||||
| +		goto failed; |  | ||||||
| +	stream->input = vmalloc(msblk->block_size); |  | ||||||
| +	if (stream->input == NULL) |  | ||||||
| +		goto failed; |  | ||||||
| +	stream->output = vmalloc(msblk->block_size); |  | ||||||
| +	if (stream->output == NULL) |  | ||||||
| +		goto failed2; |  | ||||||
| + |  | ||||||
| +	return stream; |  | ||||||
| + |  | ||||||
| +failed2: |  | ||||||
| +	vfree(stream->input); |  | ||||||
| +failed: |  | ||||||
| +	ERROR("failed to allocate lzma workspace\n"); |  | ||||||
| +	kfree(stream); |  | ||||||
| +	return NULL; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static void lzma_free(void *strm) |  | ||||||
| +{ |  | ||||||
| +	struct squashfs_lzma *stream = strm; |  | ||||||
| + |  | ||||||
| +	if (stream) { |  | ||||||
| +		vfree(stream->input); |  | ||||||
| +		vfree(stream->output); |  | ||||||
| +	} |  | ||||||
| +	kfree(stream); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static int lzma_uncompress(struct squashfs_sb_info *msblk, void **buffer, |  | ||||||
| +	struct buffer_head **bh, int b, int offset, int length, int srclength, |  | ||||||
| +	int pages) |  | ||||||
| +{ |  | ||||||
| +	struct squashfs_lzma *stream = msblk->stream; |  | ||||||
| +	void *buff = stream->input; |  | ||||||
| +	int avail, i, bytes = length, res; |  | ||||||
| + |  | ||||||
| +	mutex_lock(&lzma_mutex); |  | ||||||
| + |  | ||||||
| +	for (i = 0; i < b; i++) { |  | ||||||
| +		wait_on_buffer(bh[i]); |  | ||||||
| +		if (!buffer_uptodate(bh[i])) |  | ||||||
| +			goto block_release; |  | ||||||
| + |  | ||||||
| +		avail = min(bytes, msblk->devblksize - offset); |  | ||||||
| +		memcpy(buff, bh[i]->b_data + offset, avail); |  | ||||||
| +		buff += avail; |  | ||||||
| +		bytes -= avail; |  | ||||||
| +		offset = 0; |  | ||||||
| +		put_bh(bh[i]); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	lzma_error = 0; |  | ||||||
| +	res = unlzma(stream->input, length, NULL, NULL, stream->output, NULL, |  | ||||||
| +							error); |  | ||||||
| +	if (res || lzma_error) |  | ||||||
| +		goto failed; |  | ||||||
| + |  | ||||||
| +	/* uncompressed size is stored in the LZMA header (5 byte offset) */ |  | ||||||
| +	res = bytes = get_unaligned_le32(stream->input + 5); |  | ||||||
| +	for (i = 0, buff = stream->output; bytes && i < pages; i++) { |  | ||||||
| +		avail = min_t(int, bytes, PAGE_CACHE_SIZE); |  | ||||||
| +		memcpy(buffer[i], buff, avail); |  | ||||||
| +		buff += avail; |  | ||||||
| +		bytes -= avail; |  | ||||||
| +	} |  | ||||||
| +	if (bytes) |  | ||||||
| +		goto failed; |  | ||||||
| + |  | ||||||
| +	mutex_unlock(&lzma_mutex); |  | ||||||
| +	return res; |  | ||||||
| + |  | ||||||
| +block_release: |  | ||||||
| +	for (; i < b; i++) |  | ||||||
| +		put_bh(bh[i]); |  | ||||||
| + |  | ||||||
| +failed: |  | ||||||
| +	mutex_unlock(&lzma_mutex); |  | ||||||
| + |  | ||||||
| +	ERROR("lzma decompression failed, data probably corrupt\n"); |  | ||||||
| +	return -EIO; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +const struct squashfs_decompressor squashfs_lzma_comp_ops = { |  | ||||||
| +	.init = lzma_init, |  | ||||||
| +	.free = lzma_free, |  | ||||||
| +	.decompress = lzma_uncompress, |  | ||||||
| +	.id = LZMA_COMPRESSION, |  | ||||||
| +	.name = "lzma", |  | ||||||
| +	.supported = 1 |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| --- a/fs/squashfs/squashfs.h |  | ||||||
| +++ b/fs/squashfs/squashfs.h |  | ||||||
| @@ -94,3 +94,6 @@ extern const struct address_space_operat |  | ||||||
|   |  | ||||||
|  /* zlib_wrapper.c */ |  | ||||||
|  extern const struct squashfs_decompressor squashfs_zlib_comp_ops; |  | ||||||
| + |  | ||||||
| +/* lzma wrapper.c */ |  | ||||||
| +extern const struct squashfs_decompressor squashfs_lzma_comp_ops; |  | ||||||
| @@ -1,165 +0,0 @@ | |||||||
| From fdf23ed283bc6ef5c25076ce2065f892120ff556 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| Date: Thu, 22 Oct 2009 04:57:38 +0100 |  | ||||||
| Subject: [PATCH] Squashfs: Make unlzma available to non initramfs/initrd code |  | ||||||
|  |  | ||||||
| Add a config option DECOMPRESS_LZMA_NEEDED which allows subsystems to |  | ||||||
| specify they need the unlzma code.  Normally decompress_unlzma.c is |  | ||||||
| compiled with __init and unlzma is not exported to modules. |  | ||||||
|  |  | ||||||
| Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk> |  | ||||||
| --- |  | ||||||
|  fs/squashfs/Kconfig                   |    1 + |  | ||||||
|  include/linux/decompress/bunzip2_mm.h |   12 ++++++++++++ |  | ||||||
|  include/linux/decompress/inflate_mm.h |   12 ++++++++++++ |  | ||||||
|  include/linux/decompress/mm.h         |    3 --- |  | ||||||
|  include/linux/decompress/unlzma_mm.h  |   20 ++++++++++++++++++++ |  | ||||||
|  lib/Kconfig                           |    3 +++ |  | ||||||
|  lib/decompress_bunzip2.c              |    1 + |  | ||||||
|  lib/decompress_inflate.c              |    1 + |  | ||||||
|  lib/decompress_unlzma.c               |    5 ++++- |  | ||||||
|  9 files changed, 54 insertions(+), 4 deletions(-) |  | ||||||
|  create mode 100644 include/linux/decompress/bunzip2_mm.h |  | ||||||
|  create mode 100644 include/linux/decompress/inflate_mm.h |  | ||||||
|  create mode 100644 include/linux/decompress/unlzma_mm.h |  | ||||||
|  |  | ||||||
| --- a/fs/squashfs/Kconfig |  | ||||||
| +++ b/fs/squashfs/Kconfig |  | ||||||
| @@ -30,6 +30,7 @@ config SQUASHFS_LZMA |  | ||||||
|  	bool "Include support for LZMA compressed file systems" |  | ||||||
|  	depends on SQUASHFS |  | ||||||
|  	select DECOMPRESS_LZMA |  | ||||||
| +	select DECOMPRESS_LZMA_NEEDED |  | ||||||
|   |  | ||||||
|  config SQUASHFS_EMBEDDED |  | ||||||
|   |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/decompress/bunzip2_mm.h |  | ||||||
| @@ -0,0 +1,12 @@ |  | ||||||
| +#ifndef BUNZIP2_MM_H |  | ||||||
| +#define BUNZIP2_MM_H |  | ||||||
| + |  | ||||||
| +#ifdef STATIC |  | ||||||
| +/* Code active when included from pre-boot environment: */ |  | ||||||
| +#define INIT |  | ||||||
| +#else |  | ||||||
| +/* Compile for initramfs/initrd code only */ |  | ||||||
| +#define INIT __init |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#endif |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/decompress/inflate_mm.h |  | ||||||
| @@ -0,0 +1,12 @@ |  | ||||||
| +#ifndef INFLATE_MM_H |  | ||||||
| +#define INFLATE_MM_H |  | ||||||
| + |  | ||||||
| +#ifdef STATIC |  | ||||||
| +/* Code active when included from pre-boot environment: */ |  | ||||||
| +#define INIT |  | ||||||
| +#else |  | ||||||
| +/* Compile for initramfs/initrd code only */ |  | ||||||
| +#define INIT __init |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#endif |  | ||||||
| --- a/include/linux/decompress/mm.h |  | ||||||
| +++ b/include/linux/decompress/mm.h |  | ||||||
| @@ -63,8 +63,6 @@ static void free(void *where) |  | ||||||
|   |  | ||||||
|  #define set_error_fn(x) |  | ||||||
|   |  | ||||||
| -#define INIT |  | ||||||
| - |  | ||||||
|  #else /* STATIC */ |  | ||||||
|   |  | ||||||
|  /* Code active when compiled standalone for use when loading ramdisk: */ |  | ||||||
| @@ -87,7 +85,6 @@ static void free(void *where) |  | ||||||
|  static void(*error)(char *m); |  | ||||||
|  #define set_error_fn(x) error = x; |  | ||||||
|   |  | ||||||
| -#define INIT __init |  | ||||||
|  #define STATIC |  | ||||||
|   |  | ||||||
|  #include <linux/init.h> |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/decompress/unlzma_mm.h |  | ||||||
| @@ -0,0 +1,20 @@ |  | ||||||
| +#ifndef UNLZMA_MM_H |  | ||||||
| +#define UNLZMA_MM_H |  | ||||||
| + |  | ||||||
| +#ifdef STATIC |  | ||||||
| + |  | ||||||
| +/* Code active when included from pre-boot environment: */ |  | ||||||
| +#define INIT |  | ||||||
| + |  | ||||||
| +#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED) |  | ||||||
| + |  | ||||||
| +/* Make it available to non initramfs/initrd code */ |  | ||||||
| +#define INIT |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#else |  | ||||||
| + |  | ||||||
| +/* Compile for initramfs/initrd code only */ |  | ||||||
| +#define INIT __init |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#endif |  | ||||||
| --- a/lib/Kconfig |  | ||||||
| +++ b/lib/Kconfig |  | ||||||
| @@ -117,6 +117,9 @@ config DECOMPRESS_BZIP2 |  | ||||||
|  config DECOMPRESS_LZMA |  | ||||||
|  	tristate |  | ||||||
|   |  | ||||||
| +config DECOMPRESS_LZMA_NEEDED |  | ||||||
| +	 boolean |  | ||||||
| + |  | ||||||
|  # |  | ||||||
|  # Generic allocator support is selected if needed |  | ||||||
|  # |  | ||||||
| --- a/lib/decompress_bunzip2.c |  | ||||||
| +++ b/lib/decompress_bunzip2.c |  | ||||||
| @@ -52,6 +52,7 @@ |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|  #endif /* STATIC */ |  | ||||||
|   |  | ||||||
| +#include <linux/decompress/bunzip2_mm.h> |  | ||||||
|  #include <linux/decompress/mm.h> |  | ||||||
|   |  | ||||||
|  #ifndef INT_MAX |  | ||||||
| --- a/lib/decompress_inflate.c |  | ||||||
| +++ b/lib/decompress_inflate.c |  | ||||||
| @@ -23,6 +23,7 @@ |  | ||||||
|   |  | ||||||
|  #endif /* STATIC */ |  | ||||||
|   |  | ||||||
| +#include <linux/decompress/inflate_mm.h> |  | ||||||
|  #include <linux/decompress/mm.h> |  | ||||||
|   |  | ||||||
|  #define GZIP_IOBUF_SIZE (16*1024) |  | ||||||
| --- a/lib/decompress_unlzma.c |  | ||||||
| +++ b/lib/decompress_unlzma.c |  | ||||||
| @@ -36,6 +36,7 @@ |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|  #endif /* STATIC */ |  | ||||||
|   |  | ||||||
| +#include <linux/decompress/unlzma_mm.h> |  | ||||||
|  #include <linux/decompress/mm.h> |  | ||||||
|   |  | ||||||
|  #define	MIN(a, b) (((a) < (b)) ? (a) : (b)) |  | ||||||
| @@ -531,7 +532,7 @@ static inline void INIT process_bit1(str |  | ||||||
|   |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -STATIC inline int INIT unlzma(unsigned char *buf, int in_len, |  | ||||||
| +STATIC int INIT unlzma(unsigned char *buf, int in_len, |  | ||||||
|  			      int(*fill)(void*, unsigned int), |  | ||||||
|  			      int(*flush)(void*, unsigned int), |  | ||||||
|  			      unsigned char *output, |  | ||||||
| @@ -664,4 +665,6 @@ STATIC int INIT decompress(unsigned char |  | ||||||
|  { |  | ||||||
|  	return unlzma(buf, in_len - 4, fill, flush, output, posp, error_fn); |  | ||||||
|  } |  | ||||||
| +#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED) |  | ||||||
| +EXPORT_SYMBOL(unlzma); |  | ||||||
|  #endif |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,25 +0,0 @@ | |||||||
| From 0fed784b0f1ecf57d568ae60b2cada43f9d90759 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Roel Kluin <roel.kluin@gmail.com> |  | ||||||
| Date: Sat, 21 Nov 2009 16:34:36 +0100 |  | ||||||
| Subject: [PATCH] JFFS2: fix min/max confusion |  | ||||||
|  |  | ||||||
| MAX_SUMMARY_SIZE was meant as a limit, not as a minimum |  | ||||||
|  |  | ||||||
| Signed-off-by: Roel Kluin <roel.kluin@gmail.com> |  | ||||||
| Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> |  | ||||||
| Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> |  | ||||||
| --- |  | ||||||
|  fs/jffs2/summary.c |    2 +- |  | ||||||
|  1 files changed, 1 insertions(+), 1 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/jffs2/summary.c |  | ||||||
| +++ b/fs/jffs2/summary.c |  | ||||||
| @@ -23,7 +23,7 @@ |  | ||||||
|   |  | ||||||
|  int jffs2_sum_init(struct jffs2_sb_info *c) |  | ||||||
|  { |  | ||||||
| -	uint32_t sum_size = max_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); |  | ||||||
| +	uint32_t sum_size = min_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); |  | ||||||
|   |  | ||||||
|  	c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); |  | ||||||
|   |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/arch/mips/kernel/head.S |  | ||||||
| +++ b/arch/mips/kernel/head.S |  | ||||||
| @@ -121,6 +121,8 @@ |  | ||||||
|  #endif |  | ||||||
|  	.endm |  | ||||||
|   |  | ||||||
| +	j kernel_entry |  | ||||||
| +	nop |  | ||||||
|  #ifndef CONFIG_NO_EXCEPT_FILL |  | ||||||
|  	/* |  | ||||||
|  	 * Reserved space for exception handlers. |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| --- a/Makefile |  | ||||||
| +++ b/Makefile |  | ||||||
| @@ -523,7 +523,7 @@ all: vmlinux |  | ||||||
|  ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE |  | ||||||
|  KBUILD_CFLAGS	+= -Os |  | ||||||
|  else |  | ||||||
| -KBUILD_CFLAGS	+= -O2 |  | ||||||
| +KBUILD_CFLAGS	+= -O2 -fno-reorder-blocks -fno-tree-ch |  | ||||||
|  endif |  | ||||||
|   |  | ||||||
|  include $(srctree)/arch/$(SRCARCH)/Makefile |  | ||||||
| @@ -561,6 +561,9 @@ endif |  | ||||||
|  NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) |  | ||||||
|  CHECKFLAGS     += $(NOSTDINC_FLAGS) |  | ||||||
|   |  | ||||||
| +# improve gcc optimization |  | ||||||
| +CFLAGS += $(call cc-option,-funit-at-a-time,) |  | ||||||
| + |  | ||||||
|  # warn about C99 declaration after statement |  | ||||||
|  KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) |  | ||||||
|   |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/arch/mips/include/asm/system.h |  | ||||||
| +++ b/arch/mips/include/asm/system.h |  | ||||||
| @@ -194,7 +194,7 @@ extern __u64 __xchg_u64_unsupported_on_3 |  | ||||||
|  #define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) |  | ||||||
| +static __always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) |  | ||||||
|  { |  | ||||||
|  	switch (size) { |  | ||||||
|  	case 4: |  | ||||||
| @@ -1,50 +0,0 @@ | |||||||
| --- a/drivers/mtd/chips/cfi_cmdset_0002.c |  | ||||||
| +++ b/drivers/mtd/chips/cfi_cmdset_0002.c |  | ||||||
| @@ -325,6 +325,8 @@ static struct cfi_fixup fixup_table[] = |  | ||||||
|  static void cfi_fixup_major_minor(struct cfi_private *cfi, |  | ||||||
|  				  struct cfi_pri_amdstd *extp) |  | ||||||
|  { |  | ||||||
| +	// manufacturers defined in include/linux/mtd/cfi.h |  | ||||||
| + |  | ||||||
|  	if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e && |  | ||||||
|  	    extp->MajorVersion == '0') |  | ||||||
|  		extp->MajorVersion = '1'; |  | ||||||
| @@ -355,6 +357,9 @@ struct mtd_info *cfi_cmdset_0002(struct |  | ||||||
|  	mtd->name    = map->name; |  | ||||||
|  	mtd->writesize = 1; |  | ||||||
|   |  | ||||||
| +	printk(" CFI mfr 0x%08x\n", cfi->mfr);	// TODO: Is there a more general place to print this info? |  | ||||||
| +	printk(" CFI id  0x%08x\n", cfi->id); |  | ||||||
| + |  | ||||||
|  	if (cfi->cfi_mode==CFI_MODE_CFI){ |  | ||||||
|  		unsigned char bootloc; |  | ||||||
|  		/* |  | ||||||
| @@ -373,16 +378,24 @@ struct mtd_info *cfi_cmdset_0002(struct |  | ||||||
|   |  | ||||||
|  		cfi_fixup_major_minor(cfi, extp); |  | ||||||
|   |  | ||||||
| -		if (extp->MajorVersion != '1' || |  | ||||||
| -		    (extp->MinorVersion < '0' || extp->MinorVersion > '4')) { |  | ||||||
| +		// valid primary extension versions are: 1.0, 1.1, 1.2, 1.3 |  | ||||||
| +		// see: http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf, page 19 and on |  | ||||||
| +		//      http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_100_20011201.pdf |  | ||||||
| +		if (extp->MajorVersion < '1' || |  | ||||||
| +		    extp->MajorVersion > '1' || |  | ||||||
| +		    (extp->MajorVersion == '1' && ( extp->MinorVersion < '0' || extp->MinorVersion > '3'))) { |  | ||||||
|  			printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query " |  | ||||||
| -			       "version %c.%c.\n",  extp->MajorVersion, |  | ||||||
| -			       extp->MinorVersion); |  | ||||||
| +			       "version %c.%c (0x%02x/0x%02x).\n", |  | ||||||
| +			       extp->MajorVersion, extp->MinorVersion, |  | ||||||
| +			       extp->MajorVersion, extp->MinorVersion); |  | ||||||
|  			kfree(extp); |  | ||||||
|  			kfree(mtd); |  | ||||||
|  			return NULL; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| +		printk("  Amd/Fujitsu Extended Query version %c.%c.\n", |  | ||||||
| +		       extp->MajorVersion, extp->MinorVersion); |  | ||||||
| + |  | ||||||
|  		/* Install our own private info structure */ |  | ||||||
|  		cfi->cmdset_priv = extp; |  | ||||||
|   |  | ||||||
| @@ -1,208 +0,0 @@ | |||||||
| --- /dev/null |  | ||||||
| +++ b/arch/mips/include/asm/mips_machine.h |  | ||||||
| @@ -0,0 +1,54 @@ |  | ||||||
| +/* |  | ||||||
| + *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |  | ||||||
| + * |  | ||||||
| + *  This program is free software; you can redistribute it and/or modify it |  | ||||||
| + *  under the terms of the GNU General Public License version 2 as published |  | ||||||
| + *  by the Free Software Foundation. |  | ||||||
| + * |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#ifndef __ASM_MIPS_MACHINE_H |  | ||||||
| +#define __ASM_MIPS_MACHINE_H |  | ||||||
| + |  | ||||||
| +#include <linux/init.h> |  | ||||||
| +#include <linux/list.h> |  | ||||||
| + |  | ||||||
| +#include <asm/bootinfo.h> |  | ||||||
| + |  | ||||||
| +struct mips_machine { |  | ||||||
| +	unsigned long		mach_type; |  | ||||||
| +	const char		*mach_id; |  | ||||||
| +	const char		*mach_name; |  | ||||||
| +	void			(*mach_setup)(void); |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +#define MIPS_MACHINE(_type, _id, _name, _setup) 		\ |  | ||||||
| +static const char machine_name_##_type[] __initconst		\ |  | ||||||
| +			__aligned(1) = _name;			\ |  | ||||||
| +static const char machine_id_##_type[] __initconst		\ |  | ||||||
| +			__aligned(1) = _id;			\ |  | ||||||
| +static struct mips_machine machine_##_type			\ |  | ||||||
| +		__used __section(.mips.machines.init) =		\ |  | ||||||
| +{								\ |  | ||||||
| +	.mach_type	= _type,				\ |  | ||||||
| +	.mach_id	= machine_id_##_type,			\ |  | ||||||
| +	.mach_name	= machine_name_##_type,			\ |  | ||||||
| +	.mach_setup	= _setup,				\ |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +extern long __mips_machines_start; |  | ||||||
| +extern long __mips_machines_end; |  | ||||||
| + |  | ||||||
| +#ifdef CONFIG_MIPS_MACHINE |  | ||||||
| +int  mips_machtype_setup(char *id) __init; |  | ||||||
| +void mips_machine_setup(void) __init; |  | ||||||
| +void mips_set_machine_name(const char *name) __init; |  | ||||||
| +char *mips_get_machine_name(void); |  | ||||||
| +#else |  | ||||||
| +static inline int mips_machtype_setup(char *id) { return 1; } |  | ||||||
| +static inline void mips_machine_setup(void) { } |  | ||||||
| +static inline void mips_set_machine_name(const char *name) { } |  | ||||||
| +static inline char *mips_get_machine_name(void) { return NULL; } |  | ||||||
| +#endif /* CONFIG_MIPS_MACHINE */ |  | ||||||
| + |  | ||||||
| +#endif /* __ASM_MIPS_MACHINE_H */ |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/arch/mips/kernel/mips_machine.c |  | ||||||
| @@ -0,0 +1,86 @@ |  | ||||||
| +/* |  | ||||||
| + *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |  | ||||||
| + * |  | ||||||
| + *  This program is free software; you can redistribute it and/or modify it |  | ||||||
| + *  under the terms of the GNU General Public License version 2 as published |  | ||||||
| + *  by the Free Software Foundation. |  | ||||||
| + * |  | ||||||
| + */ |  | ||||||
| +#include <linux/mm.h> |  | ||||||
| +#include <linux/string.h> |  | ||||||
| +#include <linux/slab.h> |  | ||||||
| + |  | ||||||
| +#include <asm/mips_machine.h> |  | ||||||
| + |  | ||||||
| +static struct mips_machine *mips_machine __initdata; |  | ||||||
| +static char *mips_machine_name = "Unknown"; |  | ||||||
| + |  | ||||||
| +#define for_each_machine(mach) \ |  | ||||||
| +	for ((mach) = (struct mips_machine *)&__mips_machines_start; \ |  | ||||||
| +	     (mach) && \ |  | ||||||
| +	     (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \ |  | ||||||
| +	     (mach)++) |  | ||||||
| + |  | ||||||
| +__init void mips_set_machine_name(const char *name) |  | ||||||
| +{ |  | ||||||
| +	char *p; |  | ||||||
| + |  | ||||||
| +	if (name == NULL) |  | ||||||
| +		return; |  | ||||||
| + |  | ||||||
| +	p = kstrdup(name, GFP_KERNEL); |  | ||||||
| +	if (!p) |  | ||||||
| +		pr_err("MIPS: no memory for machine_name\n"); |  | ||||||
| + |  | ||||||
| +	mips_machine_name = p; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +char *mips_get_machine_name(void) |  | ||||||
| +{ |  | ||||||
| +	return mips_machine_name; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +__init int mips_machtype_setup(char *id) |  | ||||||
| +{ |  | ||||||
| +	struct mips_machine *mach; |  | ||||||
| + |  | ||||||
| +	for_each_machine(mach) { |  | ||||||
| +		if (mach->mach_id == NULL) |  | ||||||
| +			continue; |  | ||||||
| + |  | ||||||
| +		if (strcmp(mach->mach_id, id) == 0) { |  | ||||||
| +			mips_machtype = mach->mach_type; |  | ||||||
| +			return 0; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	pr_err("MIPS: no machine found for id '%s', supported machines:\n", id); |  | ||||||
| +	pr_err("%-24s : %s\n", "id", "name"); |  | ||||||
| +	for_each_machine(mach) |  | ||||||
| +		pr_err("%-24s : %s\n", mach->mach_id, mach->mach_name); |  | ||||||
| + |  | ||||||
| +	return 1; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +__setup("machtype=", mips_machtype_setup); |  | ||||||
| + |  | ||||||
| +__init void mips_machine_setup(void) |  | ||||||
| +{ |  | ||||||
| +	struct mips_machine *mach; |  | ||||||
| + |  | ||||||
| +	for_each_machine(mach) { |  | ||||||
| +		if (mips_machtype == mach->mach_type) { |  | ||||||
| +			mips_machine = mach; |  | ||||||
| +			break; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (!mips_machine) |  | ||||||
| +		return; |  | ||||||
| + |  | ||||||
| +	mips_set_machine_name(mips_machine->mach_name); |  | ||||||
| +	pr_info("MIPS: machine is %s\n", mips_machine_name); |  | ||||||
| + |  | ||||||
| +	if (mips_machine->mach_setup) |  | ||||||
| +		mips_machine->mach_setup(); |  | ||||||
| +} |  | ||||||
| --- a/arch/mips/kernel/Makefile |  | ||||||
| +++ b/arch/mips/kernel/Makefile |  | ||||||
| @@ -87,6 +87,7 @@ obj-$(CONFIG_GPIO_TXX9)		+= gpio_txx9.o |  | ||||||
|   |  | ||||||
|  obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o |  | ||||||
|  obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o |  | ||||||
| +obj-$(CONFIG_MIPS_MACHINE)	+= mips_machine.o |  | ||||||
|   |  | ||||||
|  CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) |  | ||||||
|   |  | ||||||
| --- a/arch/mips/Kconfig |  | ||||||
| +++ b/arch/mips/Kconfig |  | ||||||
| @@ -854,6 +854,9 @@ config MIPS_DISABLE_OBSOLETE_IDE |  | ||||||
|  config SYNC_R4K |  | ||||||
|  	bool |  | ||||||
|   |  | ||||||
| +config MIPS_MACHINE |  | ||||||
| +	def_bool n |  | ||||||
| + |  | ||||||
|  config NO_IOPORT |  | ||||||
|  	def_bool n |  | ||||||
|   |  | ||||||
| --- a/arch/mips/kernel/proc.c |  | ||||||
| +++ b/arch/mips/kernel/proc.c |  | ||||||
| @@ -12,6 +12,7 @@ |  | ||||||
|  #include <asm/cpu-features.h> |  | ||||||
|  #include <asm/mipsregs.h> |  | ||||||
|  #include <asm/processor.h> |  | ||||||
| +#include <asm/mips_machine.h> |  | ||||||
|   |  | ||||||
|  unsigned int vced_count, vcei_count; |  | ||||||
|   |  | ||||||
| @@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file |  | ||||||
|  	/* |  | ||||||
|  	 * For the first processor also print the system type |  | ||||||
|  	 */ |  | ||||||
| -	if (n == 0) |  | ||||||
| +	if (n == 0) { |  | ||||||
|  		seq_printf(m, "system type\t\t: %s\n", get_system_type()); |  | ||||||
| +		if (mips_get_machine_name()) |  | ||||||
| +			seq_printf(m, "machine\t\t\t: %s\n", |  | ||||||
| +				   mips_get_machine_name()); |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	seq_printf(m, "processor\t\t: %ld\n", n); |  | ||||||
|  	sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", |  | ||||||
| --- a/arch/mips/kernel/vmlinux.lds.S |  | ||||||
| +++ b/arch/mips/kernel/vmlinux.lds.S |  | ||||||
| @@ -97,6 +97,13 @@ SECTIONS |  | ||||||
|  	INIT_TEXT_SECTION(PAGE_SIZE) |  | ||||||
|  	INIT_DATA_SECTION(16) |  | ||||||
|   |  | ||||||
| +	. = ALIGN(4); |  | ||||||
| +	.mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) { |  | ||||||
| +		__mips_machines_start = .; |  | ||||||
| +		*(.mips.machines.init) |  | ||||||
| +		__mips_machines_end = .; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* .exit.text is discarded at runtime, not link time, to deal with |  | ||||||
|  	 * references from .rodata |  | ||||||
|  	 */ |  | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| --- a/arch/mips/Kconfig |  | ||||||
| +++ b/arch/mips/Kconfig |  | ||||||
| @@ -857,6 +857,10 @@ config SYNC_R4K |  | ||||||
|  config MIPS_MACHINE |  | ||||||
|  	def_bool n |  | ||||||
|   |  | ||||||
| +config IMAGE_CMDLINE_HACK |  | ||||||
| +	bool "OpenWrt specific image command line hack" |  | ||||||
| +	default n |  | ||||||
| + |  | ||||||
|  config NO_IOPORT |  | ||||||
|  	def_bool n |  | ||||||
|   |  | ||||||
| --- a/arch/mips/kernel/head.S |  | ||||||
| +++ b/arch/mips/kernel/head.S |  | ||||||
| @@ -143,6 +143,12 @@ FEXPORT(__kernel_entry) |  | ||||||
|  	j	kernel_entry |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifdef CONFIG_IMAGE_CMDLINE_HACK |  | ||||||
| +	.ascii	"CMDLINE:" |  | ||||||
| +EXPORT(__image_cmdline) |  | ||||||
| +	.fill	0x400 |  | ||||||
| +#endif /* CONFIG_IMAGE_CMDLINE_HACK */ |  | ||||||
| + |  | ||||||
|  	__REF |  | ||||||
|   |  | ||||||
|  NESTED(kernel_entry, 16, sp)			# kernel entry point |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| --- a/arch/mips/include/asm/thread_info.h |  | ||||||
| +++ b/arch/mips/include/asm/thread_info.h |  | ||||||
| @@ -83,6 +83,7 @@ register struct thread_info *__current_t |  | ||||||
|  #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |  | ||||||
|  #define THREAD_MASK (THREAD_SIZE - 1UL) |  | ||||||
|   |  | ||||||
| +#if 0 |  | ||||||
|  #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_DEBUG_STACK_USAGE |  | ||||||
| @@ -92,6 +93,7 @@ register struct thread_info *__current_t |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  #define free_thread_info(info) kfree(info) |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
|  #endif /* !__ASSEMBLY__ */ |  | ||||||
|   |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/arch/mips/kernel/machine_kexec.c |  | ||||||
| +++ b/arch/mips/kernel/machine_kexec.c |  | ||||||
| @@ -52,7 +52,7 @@ machine_kexec(struct kimage *image) |  | ||||||
|  	reboot_code_buffer = |  | ||||||
|  	  (unsigned long)page_address(image->control_code_page); |  | ||||||
|   |  | ||||||
| -	kexec_start_address = image->start; |  | ||||||
| +	kexec_start_address = (unsigned long) phys_to_virt(image->start); |  | ||||||
|  	kexec_indirection_page = |  | ||||||
|  		(unsigned long) phys_to_virt(image->head & PAGE_MASK); |  | ||||||
|   |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,155 +0,0 @@ | |||||||
| MIPS: allow disabling the kernel FPU emulator |  | ||||||
|  |  | ||||||
| This patch allows turning off the in-kernel Algorithmics |  | ||||||
| FPU emulator support, which allows one to save a couple of |  | ||||||
| precious blocks on an embedded system. |  | ||||||
|  |  | ||||||
| Signed-off-by: Florian Fainelli <florian@openwrt.org> |  | ||||||
| -- |  | ||||||
| --- a/arch/mips/Kconfig |  | ||||||
| +++ b/arch/mips/Kconfig |  | ||||||
| @@ -842,6 +842,17 @@ config I8259 |  | ||||||
|  config MIPS_BONITO64 |  | ||||||
|  	bool |  | ||||||
|   |  | ||||||
| +config MIPS_FPU_EMU |  | ||||||
| +	bool "Enable FPU emulation" |  | ||||||
| +	default y |  | ||||||
| +	help |  | ||||||
| +	   This option allows building a kernel with or without the Algorithmics |  | ||||||
| +	   FPU emulator enabled. Turning off this option results in a kernel which |  | ||||||
| +	   does not catch floating operations exceptions. Make sure that your toolchain |  | ||||||
| +	   is configured to enable software floating point emulation in that case. |  | ||||||
| +		 |  | ||||||
| +	   If unsure say Y here. |  | ||||||
| + |  | ||||||
|  config MIPS_MSC |  | ||||||
|  	bool |  | ||||||
|   |  | ||||||
| --- a/arch/mips/math-emu/Makefile |  | ||||||
| +++ b/arch/mips/math-emu/Makefile |  | ||||||
| @@ -2,12 +2,14 @@ |  | ||||||
|  # Makefile for the Linux/MIPS kernel FPU emulation. |  | ||||||
|  # |  | ||||||
|   |  | ||||||
| -obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ |  | ||||||
| +obj-y	:=	kernel_linkage.o dsemul.o cp1emu.o |  | ||||||
| + |  | ||||||
| +obj-$(CONFIG_MIPS_FPU_EMU)	+= ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ |  | ||||||
|  	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \ |  | ||||||
|  	   dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \ |  | ||||||
|  	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \ |  | ||||||
|  	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \ |  | ||||||
|  	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ |  | ||||||
| -	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o |  | ||||||
| +	   dp_sqrt.o sp_sqrt.o |  | ||||||
|   |  | ||||||
|  EXTRA_CFLAGS += -Werror |  | ||||||
| --- a/arch/mips/math-emu/cp1emu.c |  | ||||||
| +++ b/arch/mips/math-emu/cp1emu.c |  | ||||||
| @@ -56,6 +56,12 @@ |  | ||||||
|  #endif |  | ||||||
|  #define __mips 4 |  | ||||||
|   |  | ||||||
| +/* Further private data for which no space exists in mips_fpu_struct */ |  | ||||||
| + |  | ||||||
| +struct mips_fpu_emulator_stats fpuemustats; |  | ||||||
| + |  | ||||||
| +#ifdef CONFIG_MIPS_FPU_EMU |  | ||||||
| + |  | ||||||
|  /* Function which emulates a floating point instruction. */ |  | ||||||
|   |  | ||||||
|  static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, |  | ||||||
| @@ -66,10 +72,6 @@ static int fpux_emu(struct pt_regs *, |  | ||||||
|  	struct mips_fpu_struct *, mips_instruction); |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -/* Further private data for which no space exists in mips_fpu_struct */ |  | ||||||
| - |  | ||||||
| -struct mips_fpu_emulator_stats fpuemustats; |  | ||||||
| - |  | ||||||
|  /* Control registers */ |  | ||||||
|   |  | ||||||
|  #define FPCREG_RID	0	/* $0  = revision id */ |  | ||||||
| @@ -1281,6 +1283,13 @@ int fpu_emulator_cop1Handler(struct pt_r |  | ||||||
|   |  | ||||||
|  	return sig; |  | ||||||
|  } |  | ||||||
| +#else |  | ||||||
| +int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |  | ||||||
| +        int has_fpu) |  | ||||||
| +{ |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| +#endif /* CONFIG_MIPS_FPU_EMU */ |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_DEBUG_FS |  | ||||||
|  extern struct dentry *mips_debugfs_dir; |  | ||||||
| --- a/arch/mips/math-emu/dsemul.c |  | ||||||
| +++ b/arch/mips/math-emu/dsemul.c |  | ||||||
| @@ -109,6 +109,7 @@ int mips_dsemul(struct pt_regs *regs, mi |  | ||||||
|  	return SIGILL;		/* force out of emulation loop */ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +#ifdef CONFIG_MIPS_FPU_EMU |  | ||||||
|  int do_dsemulret(struct pt_regs *xcp) |  | ||||||
|  { |  | ||||||
|  	struct emuframe __user *fr; |  | ||||||
| @@ -165,3 +166,9 @@ int do_dsemulret(struct pt_regs *xcp) |  | ||||||
|   |  | ||||||
|  	return 1; |  | ||||||
|  } |  | ||||||
| +#else |  | ||||||
| +int do_dsemulret(struct pt_regs *xcp) |  | ||||||
| +{ |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| +#endif /* CONFIG_MIPS_FPU_EMU */ |  | ||||||
| --- a/arch/mips/math-emu/kernel_linkage.c |  | ||||||
| +++ b/arch/mips/math-emu/kernel_linkage.c |  | ||||||
| @@ -29,6 +29,7 @@ |  | ||||||
|   |  | ||||||
|  #define SIGNALLING_NAN 0x7ff800007ff80000LL |  | ||||||
|   |  | ||||||
| +#ifdef CONFIG_MIPS_FPU_EMU |  | ||||||
|  void fpu_emulator_init_fpu(void) |  | ||||||
|  { |  | ||||||
|  	static int first = 1; |  | ||||||
| @@ -112,4 +113,36 @@ int fpu_emulator_restore_context32(struc |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
| -#endif |  | ||||||
| +#endif	/* CONFIG_64BIT */ |  | ||||||
| +#else |  | ||||||
| + |  | ||||||
| +void fpu_emulator_init_fpu(void) |  | ||||||
| +{ |  | ||||||
| +	printk(KERN_INFO "FPU emulator disabled, make sure your toolchain" |  | ||||||
| +		"was compiled with software floating point support (soft-float)\n"); |  | ||||||
| +	return; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +int fpu_emulator_save_context(struct sigcontext __user *sc) |  | ||||||
| +{ |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +int fpu_emulator_restore_context(struct sigcontext __user *sc) |  | ||||||
| +{ |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +int fpu_emulator_save_context32(struct sigcontext32 __user *sc) |  | ||||||
| +{ |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +int fpu_emulator_restore_context32(struct sigcontext32 __user *sc) |  | ||||||
| +{ |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +#ifdef CONFIG_64BIT |  | ||||||
| +#endif	/* CONFIG_64BIT */ |  | ||||||
| +#endif /* CONFIG_MIPS_FPU_EMU */ |  | ||||||
| @@ -1,368 +0,0 @@ | |||||||
| --- a/arch/mips/Makefile |  | ||||||
| +++ b/arch/mips/Makefile |  | ||||||
| @@ -83,7 +83,7 @@ all-$(CONFIG_BOOT_ELF64)	:= $(vmlinux-64 |  | ||||||
|  cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe |  | ||||||
|  cflags-y			+= -msoft-float |  | ||||||
|  LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib |  | ||||||
| -MODFLAGS			+= -mlong-calls |  | ||||||
| +MODFLAGS			+= -mno-long-calls |  | ||||||
|   |  | ||||||
|  cflags-y += -ffreestanding |  | ||||||
|   |  | ||||||
| --- a/arch/mips/include/asm/module.h |  | ||||||
| +++ b/arch/mips/include/asm/module.h |  | ||||||
| @@ -9,6 +9,11 @@ struct mod_arch_specific { |  | ||||||
|  	struct list_head dbe_list; |  | ||||||
|  	const struct exception_table_entry *dbe_start; |  | ||||||
|  	const struct exception_table_entry *dbe_end; |  | ||||||
| + |  | ||||||
| +	void *phys_plt_tbl; |  | ||||||
| +	void *virt_plt_tbl; |  | ||||||
| +	unsigned int phys_plt_offset; |  | ||||||
| +	unsigned int virt_plt_offset; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity.  */ |  | ||||||
| --- a/arch/mips/kernel/module.c |  | ||||||
| +++ b/arch/mips/kernel/module.c |  | ||||||
| @@ -43,6 +43,117 @@ static struct mips_hi16 *mips_hi16_list; |  | ||||||
|  static LIST_HEAD(dbe_list); |  | ||||||
|  static DEFINE_SPINLOCK(dbe_lock); |  | ||||||
|   |  | ||||||
| +/* |  | ||||||
| + * Get the potential max trampolines size required of the init and |  | ||||||
| + * non-init sections. Only used if we cannot find enough contiguous |  | ||||||
| + * physically mapped memory to put the module into. |  | ||||||
| + */ |  | ||||||
| +static unsigned int |  | ||||||
| +get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, |  | ||||||
| +             const char *secstrings, unsigned int symindex, bool is_init) |  | ||||||
| +{ |  | ||||||
| +	unsigned long ret = 0; |  | ||||||
| +	unsigned int i, j; |  | ||||||
| +	Elf_Sym *syms; |  | ||||||
| + |  | ||||||
| +	/* Everything marked ALLOC (this includes the exported symbols) */ |  | ||||||
| +	for (i = 1; i < hdr->e_shnum; ++i) { |  | ||||||
| +		unsigned int info = sechdrs[i].sh_info; |  | ||||||
| + |  | ||||||
| +		if (sechdrs[i].sh_type != SHT_REL |  | ||||||
| +		    && sechdrs[i].sh_type != SHT_RELA) |  | ||||||
| +			continue; |  | ||||||
| + |  | ||||||
| +		/* Not a valid relocation section? */ |  | ||||||
| +		if (info >= hdr->e_shnum) |  | ||||||
| +			continue; |  | ||||||
| + |  | ||||||
| +		/* Don't bother with non-allocated sections */ |  | ||||||
| +		if (!(sechdrs[info].sh_flags & SHF_ALLOC)) |  | ||||||
| +			continue; |  | ||||||
| + |  | ||||||
| +		/* If it's called *.init*, and we're not init, we're |  | ||||||
| +                   not interested */ |  | ||||||
| +		if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) |  | ||||||
| +		    != is_init) |  | ||||||
| +			continue; |  | ||||||
| + |  | ||||||
| +		syms = (Elf_Sym *) sechdrs[symindex].sh_addr; |  | ||||||
| +		if (sechdrs[i].sh_type == SHT_REL) { |  | ||||||
| +			Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; |  | ||||||
| +			unsigned int size = sechdrs[i].sh_size / sizeof(*rel); |  | ||||||
| + |  | ||||||
| +			for (j = 0; j < size; ++j) { |  | ||||||
| +				Elf_Sym *sym; |  | ||||||
| + |  | ||||||
| +				if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) |  | ||||||
| +					continue; |  | ||||||
| + |  | ||||||
| +				sym = syms + ELF_MIPS_R_SYM(rel[j]); |  | ||||||
| +				if (!is_init && sym->st_shndx != SHN_UNDEF) |  | ||||||
| +					continue; |  | ||||||
| + |  | ||||||
| +				ret += 4 * sizeof(int); |  | ||||||
| +			} |  | ||||||
| +		} else { |  | ||||||
| +			Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; |  | ||||||
| +			unsigned int size = sechdrs[i].sh_size / sizeof(*rela); |  | ||||||
| + |  | ||||||
| +			for (j = 0; j < size; ++j) { |  | ||||||
| +				Elf_Sym *sym; |  | ||||||
| + |  | ||||||
| +				if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) |  | ||||||
| +					continue; |  | ||||||
| + |  | ||||||
| +				sym = syms + ELF_MIPS_R_SYM(rela[j]); |  | ||||||
| +				if (!is_init && sym->st_shndx != SHN_UNDEF) |  | ||||||
| +					continue; |  | ||||||
| + |  | ||||||
| +				ret += 4 * sizeof(int); |  | ||||||
| +			} |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +#ifndef MODULE_START |  | ||||||
| +static void *alloc_phys(unsigned long size) |  | ||||||
| +{ |  | ||||||
| +	unsigned order; |  | ||||||
| +	struct page *page; |  | ||||||
| +	struct page *p; |  | ||||||
| + |  | ||||||
| +	size = PAGE_ALIGN(size); |  | ||||||
| +	order = get_order(size); |  | ||||||
| + |  | ||||||
| +	page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | |  | ||||||
| +			__GFP_THISNODE, order); |  | ||||||
| +	if (!page) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	split_page(page, order); |  | ||||||
| + |  | ||||||
| +	for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) |  | ||||||
| +		__free_page(p); |  | ||||||
| + |  | ||||||
| +	return page_address(page); |  | ||||||
| +} |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +static void free_phys(void *ptr, unsigned long size) |  | ||||||
| +{ |  | ||||||
| +	struct page *page; |  | ||||||
| +	struct page *end; |  | ||||||
| + |  | ||||||
| +	page = virt_to_page(ptr); |  | ||||||
| +	end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT); |  | ||||||
| + |  | ||||||
| +	for (; page < end; ++page) |  | ||||||
| +		__free_page(page); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
|  void *module_alloc(unsigned long size) |  | ||||||
|  { |  | ||||||
|  #ifdef MODULE_START |  | ||||||
| @@ -58,21 +169,99 @@ void *module_alloc(unsigned long size) |  | ||||||
|   |  | ||||||
|  	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); |  | ||||||
|  #else |  | ||||||
| +	void *ptr; |  | ||||||
| + |  | ||||||
|  	if (size == 0) |  | ||||||
|  		return NULL; |  | ||||||
| -	return vmalloc(size); |  | ||||||
| + |  | ||||||
| +	ptr = alloc_phys(size); |  | ||||||
| + |  | ||||||
| +	/* If we failed to allocate physically contiguous memory, |  | ||||||
| +	 * fall back to regular vmalloc. The module loader code will |  | ||||||
| +	 * create jump tables to handle long jumps */ |  | ||||||
| +	if (!ptr) |  | ||||||
| +		return vmalloc(size); |  | ||||||
| + |  | ||||||
| +	return ptr; |  | ||||||
| +#endif |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline bool is_phys_addr(void *ptr) |  | ||||||
| +{ |  | ||||||
| +#ifdef CONFIG_64BIT |  | ||||||
| +	return (KSEGX((unsigned long)ptr) == CKSEG0); |  | ||||||
| +#else |  | ||||||
| +	return (KSEGX(ptr) == KSEG0); |  | ||||||
|  #endif |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* Free memory returned from module_alloc */ |  | ||||||
|  void module_free(struct module *mod, void *module_region) |  | ||||||
|  { |  | ||||||
| -	vfree(module_region); |  | ||||||
| +	if (is_phys_addr(module_region)) { |  | ||||||
| +		if (mod->module_init == module_region) |  | ||||||
| +			free_phys(module_region, mod->init_size); |  | ||||||
| +		else if (mod->module_core == module_region) |  | ||||||
| +			free_phys(module_region, mod->core_size); |  | ||||||
| +		else |  | ||||||
| +			BUG(); |  | ||||||
| +	} else { |  | ||||||
| +		vfree(module_region); |  | ||||||
| +	} |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void *__module_alloc(int size, bool phys) |  | ||||||
| +{ |  | ||||||
| +	void *ptr; |  | ||||||
| + |  | ||||||
| +	if (phys) |  | ||||||
| +		ptr = kmalloc(size, GFP_KERNEL); |  | ||||||
| +	else |  | ||||||
| +		ptr = vmalloc(size); |  | ||||||
| +	return ptr; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void __module_free(void *ptr) |  | ||||||
| +{ |  | ||||||
| +	if (is_phys_addr(ptr)) |  | ||||||
| +		kfree(ptr); |  | ||||||
| +	else |  | ||||||
| +		vfree(ptr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, |  | ||||||
|  			      char *secstrings, struct module *mod) |  | ||||||
|  { |  | ||||||
| +	unsigned int symindex = 0; |  | ||||||
| +	unsigned int core_size, init_size; |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	for (i = 1; i < hdr->e_shnum; i++) |  | ||||||
| +		if (sechdrs[i].sh_type == SHT_SYMTAB) |  | ||||||
| +			symindex = i; |  | ||||||
| + |  | ||||||
| +	core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); |  | ||||||
| +	init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); |  | ||||||
| + |  | ||||||
| +	mod->arch.phys_plt_offset = 0; |  | ||||||
| +	mod->arch.virt_plt_offset = 0; |  | ||||||
| +	mod->arch.phys_plt_tbl = NULL; |  | ||||||
| +	mod->arch.virt_plt_tbl = NULL; |  | ||||||
| + |  | ||||||
| +	if ((core_size + init_size) == 0) |  | ||||||
| +		return 0; |  | ||||||
| + |  | ||||||
| +	mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); |  | ||||||
| +	if (!mod->arch.phys_plt_tbl) |  | ||||||
| +		return -ENOMEM; |  | ||||||
| + |  | ||||||
| +	mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); |  | ||||||
| +	if (!mod->arch.virt_plt_tbl) { |  | ||||||
| +		__module_free(mod->arch.phys_plt_tbl); |  | ||||||
| +		mod->arch.phys_plt_tbl = NULL; |  | ||||||
| +		return -ENOMEM; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -95,28 +284,36 @@ static int apply_r_mips_32_rela(struct m |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) |  | ||||||
| +static Elf_Addr add_plt_entry_to(unsigned *plt_offset, |  | ||||||
| +				 void *start, Elf_Addr v) |  | ||||||
|  { |  | ||||||
| -	if (v % 4) { |  | ||||||
| -		pr_err("module %s: dangerous R_MIPS_26 REL relocation\n", |  | ||||||
| -		       me->name); |  | ||||||
| -		return -ENOEXEC; |  | ||||||
| -	} |  | ||||||
| +	unsigned *tramp = start + *plt_offset; |  | ||||||
| +	*plt_offset += 4 * sizeof(int); |  | ||||||
|   |  | ||||||
| -	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { |  | ||||||
| -		printk(KERN_ERR |  | ||||||
| -		       "module %s: relocation overflow\n", |  | ||||||
| -		       me->name); |  | ||||||
| -		return -ENOEXEC; |  | ||||||
| -	} |  | ||||||
| +	/* adjust carry for addiu */ |  | ||||||
| +	if (v & 0x00008000) |  | ||||||
| +		v += 0x10000; |  | ||||||
|   |  | ||||||
| -	*location = (*location & ~0x03ffffff) | |  | ||||||
| -	            ((*location + (v >> 2)) & 0x03ffffff); |  | ||||||
| +	tramp[0] = 0x3c190000 | (v >> 16);      /* lui t9, hi16 */ |  | ||||||
| +	tramp[1] = 0x27390000 | (v & 0xffff);   /* addiu t9, t9, lo16 */ |  | ||||||
| +	tramp[2] = 0x03200008;                  /* jr t9 */ |  | ||||||
| +	tramp[3] = 0x00000000;                  /* nop */ |  | ||||||
|   |  | ||||||
| -	return 0; |  | ||||||
| +	return (Elf_Addr) tramp; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) |  | ||||||
| +static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) |  | ||||||
| +{ |  | ||||||
| +	if (is_phys_addr(location)) |  | ||||||
| +		return add_plt_entry_to(&me->arch.phys_plt_offset, |  | ||||||
| +				me->arch.phys_plt_tbl, v); |  | ||||||
| +	else |  | ||||||
| +		return add_plt_entry_to(&me->arch.virt_plt_offset, |  | ||||||
| +				me->arch.virt_plt_tbl, v); |  | ||||||
| + |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v) |  | ||||||
|  { |  | ||||||
|  	if (v % 4) { |  | ||||||
|  		pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", |  | ||||||
| @@ -125,17 +322,31 @@ static int apply_r_mips_26_rela(struct m |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { |  | ||||||
| -		printk(KERN_ERR |  | ||||||
| +	    v = add_plt_entry(me, location, v + (ofs << 2)); |  | ||||||
| +		if (!v) { |  | ||||||
| +			printk(KERN_ERR |  | ||||||
|  		       "module %s: relocation overflow\n", |  | ||||||
|  		       me->name); |  | ||||||
| -		return -ENOEXEC; |  | ||||||
| +			return -ENOEXEC; |  | ||||||
| +		} |  | ||||||
| +		ofs = 0; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	*location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); |  | ||||||
| +	*location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) |  | ||||||
| +{ |  | ||||||
| +	return set_r_mips_26(me, location, *location & 0x03ffffff, v); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) |  | ||||||
| +{ |  | ||||||
| +	return set_r_mips_26(me, location, 0, v); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) |  | ||||||
|  { |  | ||||||
|  	struct mips_hi16 *n; |  | ||||||
| @@ -400,11 +611,32 @@ int module_finalize(const Elf_Ehdr *hdr, |  | ||||||
|  		list_add(&me->arch.dbe_list, &dbe_list); |  | ||||||
|  		spin_unlock_irq(&dbe_lock); |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	/* Get rid of the fixup trampoline if we're running the module |  | ||||||
| +	 * from physically mapped address space */ |  | ||||||
| +	if (me->arch.phys_plt_offset == 0) { |  | ||||||
| +		__module_free(me->arch.phys_plt_tbl); |  | ||||||
| +		me->arch.phys_plt_tbl = NULL; |  | ||||||
| +	} |  | ||||||
| +	if (me->arch.virt_plt_offset == 0) { |  | ||||||
| +		__module_free(me->arch.virt_plt_tbl); |  | ||||||
| +		me->arch.virt_plt_tbl = NULL; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  void module_arch_cleanup(struct module *mod) |  | ||||||
|  { |  | ||||||
| +	if (mod->arch.phys_plt_tbl) { |  | ||||||
| +		__module_free(mod->arch.phys_plt_tbl); |  | ||||||
| +		mod->arch.phys_plt_tbl = NULL; |  | ||||||
| +	} |  | ||||||
| +	if (mod->arch.virt_plt_tbl) { |  | ||||||
| +		__module_free(mod->arch.virt_plt_tbl); |  | ||||||
| +		mod->arch.virt_plt_tbl = NULL; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	spin_lock_irq(&dbe_lock); |  | ||||||
|  	list_del(&mod->arch.dbe_list); |  | ||||||
|  	spin_unlock_irq(&dbe_lock); |  | ||||||
| @@ -1,119 +0,0 @@ | |||||||
| --- a/include/asm-generic/vmlinux.lds.h |  | ||||||
| +++ b/include/asm-generic/vmlinux.lds.h |  | ||||||
| @@ -52,6 +52,27 @@ |  | ||||||
|  #define LOAD_OFFSET 0 |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifndef SYMTAB_KEEP_STR |  | ||||||
| +#define SYMTAB_KEEP_STR *(__ksymtab_strings.*) |  | ||||||
| +#define SYMTAB_DISCARD_STR |  | ||||||
| +#else |  | ||||||
| +#define SYMTAB_DISCARD_STR *(__ksymtab_strings.*) |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#ifndef SYMTAB_KEEP |  | ||||||
| +#define SYMTAB_KEEP *(__ksymtab.*) |  | ||||||
| +#define SYMTAB_DISCARD |  | ||||||
| +#else |  | ||||||
| +#define SYMTAB_DISCARD *(__ksymtab.*) |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#ifndef SYMTAB_KEEP_GPL |  | ||||||
| +#define SYMTAB_KEEP_GPL *(__ksymtab_gpl.*) |  | ||||||
| +#define SYMTAB_DISCARD_GPL |  | ||||||
| +#else |  | ||||||
| +#define SYMTAB_DISCARD_GPL *(__ksymtab_gpl.*) |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  #ifndef VMLINUX_SYMBOL |  | ||||||
|  #define VMLINUX_SYMBOL(_sym_) _sym_ |  | ||||||
|  #endif |  | ||||||
| @@ -254,35 +275,35 @@ |  | ||||||
|  	/* Kernel symbol table: Normal symbols */			\ |  | ||||||
|  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\ |  | ||||||
|  		VMLINUX_SYMBOL(__start___ksymtab) = .;			\ |  | ||||||
| -		*(__ksymtab)						\ |  | ||||||
| +		SYMTAB_KEEP						\ |  | ||||||
|  		VMLINUX_SYMBOL(__stop___ksymtab) = .;			\ |  | ||||||
|  	}								\ |  | ||||||
|  									\ |  | ||||||
|  	/* Kernel symbol table: GPL-only symbols */			\ |  | ||||||
|  	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\ |  | ||||||
|  		VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;		\ |  | ||||||
| -		*(__ksymtab_gpl)					\ |  | ||||||
| +		SYMTAB_KEEP_GPL						\ |  | ||||||
|  		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\ |  | ||||||
|  	}								\ |  | ||||||
|  									\ |  | ||||||
|  	/* Kernel symbol table: Normal unused symbols */		\ |  | ||||||
|  	__ksymtab_unused  : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) {	\ |  | ||||||
|  		VMLINUX_SYMBOL(__start___ksymtab_unused) = .;		\ |  | ||||||
| -		*(__ksymtab_unused)					\ |  | ||||||
| +		*(__ksymtab_unused.*)					\ |  | ||||||
|  		VMLINUX_SYMBOL(__stop___ksymtab_unused) = .;		\ |  | ||||||
|  	}								\ |  | ||||||
|  									\ |  | ||||||
|  	/* Kernel symbol table: GPL-only unused symbols */		\ |  | ||||||
|  	__ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ |  | ||||||
|  		VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .;	\ |  | ||||||
| -		*(__ksymtab_unused_gpl)					\ |  | ||||||
| +		*(__ksymtab_unused_gpl.*)				\ |  | ||||||
|  		VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .;	\ |  | ||||||
|  	}								\ |  | ||||||
|  									\ |  | ||||||
|  	/* Kernel symbol table: GPL-future-only symbols */		\ |  | ||||||
|  	__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ |  | ||||||
|  		VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .;	\ |  | ||||||
| -		*(__ksymtab_gpl_future)					\ |  | ||||||
| +		*(__ksymtab_gpl_future.*)				\ |  | ||||||
|  		VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .;	\ |  | ||||||
|  	}								\ |  | ||||||
|  									\ |  | ||||||
| @@ -323,7 +344,7 @@ |  | ||||||
|  									\ |  | ||||||
|  	/* Kernel symbol table: strings */				\ |  | ||||||
|          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\ |  | ||||||
| -		*(__ksymtab_strings)					\ |  | ||||||
| +		SYMTAB_KEEP_STR						\ |  | ||||||
|  	}								\ |  | ||||||
|  									\ |  | ||||||
|  	/* __*init sections */						\ |  | ||||||
| @@ -638,6 +659,9 @@ |  | ||||||
|  	EXIT_TEXT							\ |  | ||||||
|  	EXIT_DATA							\ |  | ||||||
|  	EXIT_CALL							\ |  | ||||||
| +	SYMTAB_DISCARD							\ |  | ||||||
| +	SYMTAB_DISCARD_GPL						\ |  | ||||||
| +	SYMTAB_DISCARD_STR						\ |  | ||||||
|  	*(.discard)							\ |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| --- a/include/linux/module.h |  | ||||||
| +++ b/include/linux/module.h |  | ||||||
| @@ -192,16 +192,24 @@ void *__symbol_get_gpl(const char *symbo |  | ||||||
|  #define __CRC_SYMBOL(sym, sec) |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifdef MODULE |  | ||||||
| +#define __EXPORT_SUFFIX(sym) |  | ||||||
| +#else |  | ||||||
| +#define __EXPORT_SUFFIX(sym) "." #sym |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  /* For every exported symbol, place a struct in the __ksymtab section */ |  | ||||||
|  #define __EXPORT_SYMBOL(sym, sec)				\ |  | ||||||
|  	extern typeof(sym) sym;					\ |  | ||||||
|  	__CRC_SYMBOL(sym, sec)					\ |  | ||||||
|  	static const char __kstrtab_##sym[]			\ |  | ||||||
| -	__attribute__((section("__ksymtab_strings"), aligned(1))) \ |  | ||||||
| +	__attribute__((section("__ksymtab_strings"		\ |  | ||||||
| +	  __EXPORT_SUFFIX(sym)), aligned(1)))			\ |  | ||||||
|  	= MODULE_SYMBOL_PREFIX #sym;                    	\ |  | ||||||
|  	static const struct kernel_symbol __ksymtab_##sym	\ |  | ||||||
|  	__used							\ |  | ||||||
| -	__attribute__((section("__ksymtab" sec), unused))	\ |  | ||||||
| +	__attribute__((section("__ksymtab" sec			\ |  | ||||||
| +	  __EXPORT_SUFFIX(sym)), unused))			\ |  | ||||||
|  	= { (unsigned long)&sym, __kstrtab_##sym } |  | ||||||
|   |  | ||||||
|  #define EXPORT_SYMBOL(sym)					\ |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| --- a/arch/arm/kernel/module.c |  | ||||||
| +++ b/arch/arm/kernel/module.c |  | ||||||
| @@ -121,6 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons |  | ||||||
|  			return -ENOEXEC; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| +		if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && |  | ||||||
| +		    ELF_ST_BIND(sym->st_info) == STB_WEAK) |  | ||||||
| +			continue; |  | ||||||
| + |  | ||||||
|  		loc = dstsec->sh_addr + rel->r_offset; |  | ||||||
|   |  | ||||||
|  		switch (ELF32_R_TYPE(rel->r_info)) { |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| --- a/drivers/pci/Kconfig |  | ||||||
| +++ b/drivers/pci/Kconfig |  | ||||||
| @@ -51,6 +51,12 @@ config PCI_STUB |  | ||||||
|   |  | ||||||
|  	  When in doubt, say N. |  | ||||||
|   |  | ||||||
| +config PCI_DISABLE_COMMON_QUIRKS |  | ||||||
| +	bool "PCI disable common quirks" |  | ||||||
| +	depends on PCI |  | ||||||
| +	help |  | ||||||
| +	  If you don't know what to do here, say N. |  | ||||||
| + |  | ||||||
|  config HT_IRQ |  | ||||||
|  	bool "Interrupts on hypertransport devices" |  | ||||||
|  	default y |  | ||||||
| --- a/drivers/pci/quirks.c |  | ||||||
| +++ b/drivers/pci/quirks.c |  | ||||||
| @@ -96,6 +96,7 @@ static void __devinit quirk_resource_ali |  | ||||||
|  } |  | ||||||
|  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); |  | ||||||
|   |  | ||||||
| +#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS |  | ||||||
|  /* The Mellanox Tavor device gives false positive parity errors |  | ||||||
|   * Mark this device with a broken_parity_status, to allow |  | ||||||
|   * PCI scanning code to "skip" this now blacklisted device. |  | ||||||
| @@ -1907,7 +1908,9 @@ static void __devinit fixup_rev1_53c810( |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); |  | ||||||
| +#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ |  | ||||||
|   |  | ||||||
| +#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS |  | ||||||
|  /* Enable 1k I/O space granularity on the Intel P64H2 */ |  | ||||||
|  static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) |  | ||||||
|  { |  | ||||||
| @@ -2546,6 +2549,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I |  | ||||||
|  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); |  | ||||||
|   |  | ||||||
|  #endif	/* CONFIG_PCI_IOV */ |  | ||||||
| +#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ |  | ||||||
|   |  | ||||||
|  static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |  | ||||||
|  			  struct pci_fixup *end) |  | ||||||
| @@ -1,226 +0,0 @@ | |||||||
| GCC 4.4.x looks to be adding support for generating out-of-line register |  | ||||||
| saves/restores based on: |  | ||||||
|  |  | ||||||
| http://gcc.gnu.org/ml/gcc-patches/2008-04/msg01678.html |  | ||||||
|  |  | ||||||
| This breaks the kernel build as we'd have to link with libgcc to get the |  | ||||||
| implementation of the register save/restores. |  | ||||||
|  |  | ||||||
| To workaround this issue, we just stole the save/restore code from gcc |  | ||||||
| and simplified it down for our needs (integer only).  We only do this if |  | ||||||
| PPC32 as gcc makes believe the linker on ppc64 will deal with this and |  | ||||||
| only if CONFIG_CC_OPTIMIZE_FOR_SIZE is set (thus -Os). |  | ||||||
|  |  | ||||||
| Signed-off-by: Kumar Gala <[EMAIL PROTECTED]> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| If someone using cutting edge toolchains for ppc64 could test and make |  | ||||||
| sure if we enable CONFIG_CC_OPTIMIZE_FOR_SIZE things work that would be |  | ||||||
| nice. |  | ||||||
|  |  | ||||||
| - k |  | ||||||
|  |  | ||||||
|  arch/powerpc/kernel/misc_32.S   |   77 +++++++++++++++++++++++++++ |  | ||||||
|  arch/powerpc/kernel/ppc_ksyms.c |  111 +++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  2 files changed, 188 insertions(+), 0 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/arch/powerpc/kernel/misc_32.S |  | ||||||
| +++ b/arch/powerpc/kernel/misc_32.S |  | ||||||
| @@ -820,3 +820,80 @@ relocate_new_kernel_end: |  | ||||||
|  relocate_new_kernel_size: |  | ||||||
|  	.long relocate_new_kernel_end - relocate_new_kernel |  | ||||||
|  #endif |  | ||||||
| + |  | ||||||
| +#if defined(CONFIG_PPC32) && defined(CONFIG_CC_OPTIMIZE_FOR_SIZE) |  | ||||||
| +/* Routines for saving integer registers, called by the compiler.  */ |  | ||||||
| +/* Called with r11 pointing to the stack header word of the caller of the */ |  | ||||||
| +/* function, just beyond the end of the integer save area.  */ |  | ||||||
| + |  | ||||||
| +_GLOBAL(_savegpr_14)   stw     14,-72(11)      /* save gp registers */ |  | ||||||
| +_GLOBAL(_savegpr_15)   stw     15,-68(11) |  | ||||||
| +_GLOBAL(_savegpr_16)   stw     16,-64(11) |  | ||||||
| +_GLOBAL(_savegpr_17)   stw     17,-60(11) |  | ||||||
| +_GLOBAL(_savegpr_18)   stw     18,-56(11) |  | ||||||
| +_GLOBAL(_savegpr_19)   stw     19,-52(11) |  | ||||||
| +_GLOBAL(_savegpr_20)   stw     20,-48(11) |  | ||||||
| +_GLOBAL(_savegpr_21)   stw     21,-44(11) |  | ||||||
| +_GLOBAL(_savegpr_22)   stw     22,-40(11) |  | ||||||
| +_GLOBAL(_savegpr_23)   stw     23,-36(11) |  | ||||||
| +_GLOBAL(_savegpr_24)   stw     24,-32(11) |  | ||||||
| +_GLOBAL(_savegpr_25)   stw     25,-28(11) |  | ||||||
| +_GLOBAL(_savegpr_26)   stw     26,-24(11) |  | ||||||
| +_GLOBAL(_savegpr_27)   stw     27,-20(11) |  | ||||||
| +_GLOBAL(_savegpr_28)   stw     28,-16(11) |  | ||||||
| +_GLOBAL(_savegpr_29)   stw     29,-12(11) |  | ||||||
| +_GLOBAL(_savegpr_30)   stw     30,-8(11) |  | ||||||
| +_GLOBAL(_savegpr_31)   stw     31,-4(11) |  | ||||||
| +                       blr |  | ||||||
| + |  | ||||||
| +/* Routines for restoring integer registers, called by the compiler.  */ |  | ||||||
| +/* Called with r11 pointing to the stack header word of the caller of the */ |  | ||||||
| +/* function, just beyond the end of the integer restore area.  */ |  | ||||||
| + |  | ||||||
| +_GLOBAL(_restgpr_14)   lwz     14,-72(11)      /* restore gp registers */ |  | ||||||
| +_GLOBAL(_restgpr_15)   lwz     15,-68(11) |  | ||||||
| +_GLOBAL(_restgpr_16)   lwz     16,-64(11) |  | ||||||
| +_GLOBAL(_restgpr_17)   lwz     17,-60(11) |  | ||||||
| +_GLOBAL(_restgpr_18)   lwz     18,-56(11) |  | ||||||
| +_GLOBAL(_restgpr_19)   lwz     19,-52(11) |  | ||||||
| +_GLOBAL(_restgpr_20)   lwz     20,-48(11) |  | ||||||
| +_GLOBAL(_restgpr_21)   lwz     21,-44(11) |  | ||||||
| +_GLOBAL(_restgpr_22)   lwz     22,-40(11) |  | ||||||
| +_GLOBAL(_restgpr_23)   lwz     23,-36(11) |  | ||||||
| +_GLOBAL(_restgpr_24)   lwz     24,-32(11) |  | ||||||
| +_GLOBAL(_restgpr_25)   lwz     25,-28(11) |  | ||||||
| +_GLOBAL(_restgpr_26)   lwz     26,-24(11) |  | ||||||
| +_GLOBAL(_restgpr_27)   lwz     27,-20(11) |  | ||||||
| +_GLOBAL(_restgpr_28)   lwz     28,-16(11) |  | ||||||
| +_GLOBAL(_restgpr_29)   lwz     29,-12(11) |  | ||||||
| +_GLOBAL(_restgpr_30)   lwz     30,-8(11) |  | ||||||
| +_GLOBAL(_restgpr_31)   lwz     31,-4(11) |  | ||||||
| +                       blr |  | ||||||
| + |  | ||||||
| +/* Routines for restoring integer registers, called by the compiler.  */ |  | ||||||
| +/* Called with r11 pointing to the stack header word of the caller of the */ |  | ||||||
| +/* function, just beyond the end of the integer restore area.  */ |  | ||||||
| + |  | ||||||
| +_GLOBAL(_restgpr_14_x) lwz     14,-72(11)      /* restore gp registers */ |  | ||||||
| +_GLOBAL(_restgpr_15_x) lwz     15,-68(11) |  | ||||||
| +_GLOBAL(_restgpr_16_x) lwz     16,-64(11) |  | ||||||
| +_GLOBAL(_restgpr_17_x) lwz     17,-60(11) |  | ||||||
| +_GLOBAL(_restgpr_18_x) lwz     18,-56(11) |  | ||||||
| +_GLOBAL(_restgpr_19_x) lwz     19,-52(11) |  | ||||||
| +_GLOBAL(_restgpr_20_x) lwz     20,-48(11) |  | ||||||
| +_GLOBAL(_restgpr_21_x) lwz     21,-44(11) |  | ||||||
| +_GLOBAL(_restgpr_22_x) lwz     22,-40(11) |  | ||||||
| +_GLOBAL(_restgpr_23_x) lwz     23,-36(11) |  | ||||||
| +_GLOBAL(_restgpr_24_x) lwz     24,-32(11) |  | ||||||
| +_GLOBAL(_restgpr_25_x) lwz     25,-28(11) |  | ||||||
| +_GLOBAL(_restgpr_26_x) lwz     26,-24(11) |  | ||||||
| +_GLOBAL(_restgpr_27_x) lwz     27,-20(11) |  | ||||||
| +_GLOBAL(_restgpr_28_x) lwz     28,-16(11) |  | ||||||
| +_GLOBAL(_restgpr_29_x) lwz     29,-12(11) |  | ||||||
| +_GLOBAL(_restgpr_30_x) lwz     30,-8(11) |  | ||||||
| +_GLOBAL(_restgpr_31_x) lwz     0,4(11) |  | ||||||
| +                       lwz     31,-4(11) |  | ||||||
| +                       mtlr    0 |  | ||||||
| +                       mr      1,11 |  | ||||||
| +                       blr |  | ||||||
| +#endif |  | ||||||
| --- a/arch/powerpc/kernel/ppc_ksyms.c |  | ||||||
| +++ b/arch/powerpc/kernel/ppc_ksyms.c |  | ||||||
| @@ -188,3 +188,114 @@ EXPORT_SYMBOL(__mtdcr); |  | ||||||
|  EXPORT_SYMBOL(__mfdcr); |  | ||||||
|  #endif |  | ||||||
|  EXPORT_SYMBOL(empty_zero_page); |  | ||||||
| + |  | ||||||
| +#if defined(CONFIG_PPC32) && defined(CONFIG_CC_OPTIMIZE_FOR_SIZE) |  | ||||||
| +void _savegpr_14(void); |  | ||||||
| +void _savegpr_15(void); |  | ||||||
| +void _savegpr_16(void); |  | ||||||
| +void _savegpr_17(void); |  | ||||||
| +void _savegpr_18(void); |  | ||||||
| +void _savegpr_19(void); |  | ||||||
| +void _savegpr_20(void); |  | ||||||
| +void _savegpr_21(void); |  | ||||||
| +void _savegpr_22(void); |  | ||||||
| +void _savegpr_23(void); |  | ||||||
| +void _savegpr_24(void); |  | ||||||
| +void _savegpr_25(void); |  | ||||||
| +void _savegpr_26(void); |  | ||||||
| +void _savegpr_27(void); |  | ||||||
| +void _savegpr_28(void); |  | ||||||
| +void _savegpr_29(void); |  | ||||||
| +void _savegpr_30(void); |  | ||||||
| +void _savegpr_31(void); |  | ||||||
| +void _restgpr_14(void); |  | ||||||
| +void _restgpr_15(void); |  | ||||||
| +void _restgpr_16(void); |  | ||||||
| +void _restgpr_17(void); |  | ||||||
| +void _restgpr_18(void); |  | ||||||
| +void _restgpr_19(void); |  | ||||||
| +void _restgpr_20(void); |  | ||||||
| +void _restgpr_21(void); |  | ||||||
| +void _restgpr_22(void); |  | ||||||
| +void _restgpr_23(void); |  | ||||||
| +void _restgpr_24(void); |  | ||||||
| +void _restgpr_25(void); |  | ||||||
| +void _restgpr_26(void); |  | ||||||
| +void _restgpr_27(void); |  | ||||||
| +void _restgpr_28(void); |  | ||||||
| +void _restgpr_29(void); |  | ||||||
| +void _restgpr_30(void); |  | ||||||
| +void _restgpr_31(void); |  | ||||||
| +void _restgpr_14_x(void); |  | ||||||
| +void _restgpr_15_x(void); |  | ||||||
| +void _restgpr_16_x(void); |  | ||||||
| +void _restgpr_17_x(void); |  | ||||||
| +void _restgpr_18_x(void); |  | ||||||
| +void _restgpr_19_x(void); |  | ||||||
| +void _restgpr_20_x(void); |  | ||||||
| +void _restgpr_21_x(void); |  | ||||||
| +void _restgpr_22_x(void); |  | ||||||
| +void _restgpr_23_x(void); |  | ||||||
| +void _restgpr_24_x(void); |  | ||||||
| +void _restgpr_25_x(void); |  | ||||||
| +void _restgpr_26_x(void); |  | ||||||
| +void _restgpr_27_x(void); |  | ||||||
| +void _restgpr_28_x(void); |  | ||||||
| +void _restgpr_29_x(void); |  | ||||||
| +void _restgpr_30_x(void); |  | ||||||
| +void _restgpr_31_x(void); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_14); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_15); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_16); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_17); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_18); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_19); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_20); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_21); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_22); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_23); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_24); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_25); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_26); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_27); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_28); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_29); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_30); |  | ||||||
| +EXPORT_SYMBOL(_savegpr_31); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_14); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_15); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_16); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_17); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_18); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_19); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_20); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_21); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_22); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_23); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_24); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_25); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_26); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_27); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_28); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_29); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_30); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_31); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_14_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_15_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_16_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_17_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_18_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_19_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_20_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_21_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_22_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_23_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_24_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_25_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_26_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_27_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_28_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_29_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_30_x); |  | ||||||
| +EXPORT_SYMBOL(_restgpr_31_x); |  | ||||||
| +#endif /* CONFIG_PPC32 && CONFIG_CC_OPTIMIZE_FOR_SIZE */ |  | ||||||
| @@ -1,55 +0,0 @@ | |||||||
| --- a/arch/mips/kernel/signal.c |  | ||||||
| +++ b/arch/mips/kernel/signal.c |  | ||||||
| @@ -101,7 +101,7 @@ static int protected_save_fp_context(str |  | ||||||
|   |  | ||||||
|  static int protected_restore_fp_context(struct sigcontext __user *sc) |  | ||||||
|  { |  | ||||||
| -	int err, tmp; |  | ||||||
| +	int err, tmp __maybe_unused; |  | ||||||
|  	while (1) { |  | ||||||
|  		lock_fpu_owner(); |  | ||||||
|  		own_fpu_inatomic(0); |  | ||||||
| --- a/arch/mips/kernel/syscall.c |  | ||||||
| +++ b/arch/mips/kernel/syscall.c |  | ||||||
| @@ -372,7 +372,7 @@ save_static_function(sys_sysmips); |  | ||||||
|  static int __used noinline |  | ||||||
|  _sys_sysmips(nabi_no_regargs struct pt_regs regs) |  | ||||||
|  { |  | ||||||
| -	long cmd, arg1, arg2, arg3; |  | ||||||
| +	long cmd, arg1, arg2, arg3 __maybe_unused; |  | ||||||
|   |  | ||||||
|  	cmd = regs.regs[4]; |  | ||||||
|  	arg1 = regs.regs[5]; |  | ||||||
| --- a/arch/mips/mm/init.c |  | ||||||
| +++ b/arch/mips/mm/init.c |  | ||||||
| @@ -323,7 +323,7 @@ static int __init page_is_ram(unsigned l |  | ||||||
|  void __init paging_init(void) |  | ||||||
|  { |  | ||||||
|  	unsigned long max_zone_pfns[MAX_NR_ZONES]; |  | ||||||
| -	unsigned long lastpfn; |  | ||||||
| +	unsigned long lastpfn __maybe_unused; |  | ||||||
|   |  | ||||||
|  	pagetable_init(); |  | ||||||
|   |  | ||||||
| --- a/include/linux/pagemap.h |  | ||||||
| +++ b/include/linux/pagemap.h |  | ||||||
| @@ -412,7 +412,7 @@ static inline int fault_in_pages_writeab |  | ||||||
|   |  | ||||||
|  static inline int fault_in_pages_readable(const char __user *uaddr, int size) |  | ||||||
|  { |  | ||||||
| -	volatile char c; |  | ||||||
| +	volatile char c __maybe_unused; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
|  	if (unlikely(size == 0)) |  | ||||||
| --- a/arch/mips/mm/c-r4k.c |  | ||||||
| +++ b/arch/mips/mm/c-r4k.c |  | ||||||
| @@ -1076,7 +1076,7 @@ static int __cpuinit probe_scache(void) |  | ||||||
|  	unsigned long flags, addr, begin, end, pow2; |  | ||||||
|  	unsigned int config = read_c0_config(); |  | ||||||
|  	struct cpuinfo_mips *c = ¤t_cpu_data; |  | ||||||
| -	int tmp; |  | ||||||
| +	int tmp __maybe_unused; |  | ||||||
|   |  | ||||||
|  	if (config & CONF_SC) |  | ||||||
|  		return 0; |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/arch/x86/include/asm/percpu.h |  | ||||||
| +++ b/arch/x86/include/asm/percpu.h |  | ||||||
| @@ -76,7 +76,7 @@ extern void __bad_percpu_size(void); |  | ||||||
|  do {							\ |  | ||||||
|  	typedef typeof(var) T__;			\ |  | ||||||
|  	if (0) {					\ |  | ||||||
| -		T__ tmp__;				\ |  | ||||||
| +		T__ tmp__ __maybe_unused;		\ |  | ||||||
|  		tmp__ = (val);				\ |  | ||||||
|  	}						\ |  | ||||||
|  	switch (sizeof(var)) {				\ |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| --- a/include/linux/eeprom_93cx6.h |  | ||||||
| +++ b/include/linux/eeprom_93cx6.h |  | ||||||
| @@ -30,6 +30,7 @@ |  | ||||||
|  #define PCI_EEPROM_WIDTH_93C46	6 |  | ||||||
|  #define PCI_EEPROM_WIDTH_93C56	8 |  | ||||||
|  #define PCI_EEPROM_WIDTH_93C66	8 |  | ||||||
| +#define PCI_EEPROM_WIDTH_93C86	8 |  | ||||||
|  #define PCI_EEPROM_WIDTH_OPCODE	3 |  | ||||||
|  #define PCI_EEPROM_WRITE_OPCODE	0x05 |  | ||||||
|  #define PCI_EEPROM_READ_OPCODE	0x06 |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| --- a/include/linux/gpio_keys.h |  | ||||||
| +++ b/include/linux/gpio_keys.h |  | ||||||
| @@ -15,7 +15,12 @@ struct gpio_keys_button { |  | ||||||
|  struct gpio_keys_platform_data { |  | ||||||
|  	struct gpio_keys_button *buttons; |  | ||||||
|  	int nbuttons; |  | ||||||
| +	unsigned int poll_interval;     /* polling interval in msecs - |  | ||||||
| +					   for polling driver only */ |  | ||||||
|  	unsigned int rep:1;		/* enable input subsystem auto repeat */ |  | ||||||
| +	int (*enable)(struct device *dev); |  | ||||||
| +	void (*disable)(struct device *dev); |  | ||||||
| +	const char *name;		/* input device name */ |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  #endif |  | ||||||
| @@ -1,908 +0,0 @@ | |||||||
| --- a/arch/arm/tools/mach-types |  | ||||||
| +++ b/arch/arm/tools/mach-types |  | ||||||
| @@ -12,7 +12,7 @@ |  | ||||||
|  # |  | ||||||
|  #   http://www.arm.linux.org.uk/developer/machines/?action=new |  | ||||||
|  # |  | ||||||
| -# Last update: Wed Nov 25 22:14:58 2009 |  | ||||||
| +# Last update: Wed Feb 2 22:36:01 2011 |  | ||||||
|  # |  | ||||||
|  # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number |  | ||||||
|  # |  | ||||||
| @@ -1319,7 +1319,7 @@ mistral			MACH_MISTRAL		MISTRAL			1315 |  | ||||||
|  msm			MACH_MSM		MSM			1316 |  | ||||||
|  ct5910			MACH_CT5910		CT5910			1317 |  | ||||||
|  ct5912			MACH_CT5912		CT5912			1318 |  | ||||||
| -hynet_ine		MACH_HYNET_INE		HYNET_INE		1319 |  | ||||||
| +argonst_mp		MACH_HYNET_INE		HYNET_INE		1319 |  | ||||||
|  hynet_app		MACH_HYNET_APP		HYNET_APP		1320 |  | ||||||
|  msm7200			MACH_MSM7200		MSM7200			1321 |  | ||||||
|  msm7600			MACH_MSM7600		MSM7600			1322 |  | ||||||
| @@ -1776,7 +1776,8 @@ cybook3			MACH_CYBOOK3		CYBOOK3			1784 |  | ||||||
|  wdg002			MACH_WDG002		WDG002			1785 |  | ||||||
|  sg560adsl		MACH_SG560ADSL		SG560ADSL		1786 |  | ||||||
|  nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787 |  | ||||||
| -marvell_newdb		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789 |  | ||||||
| +dove_db			MACH_DOVE_DB		DOVE_DB			1788 |  | ||||||
| +dove_avng		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789 |  | ||||||
|  vandihud		MACH_VANDIHUD		VANDIHUD		1790 |  | ||||||
|  magx_e8			MACH_MAGX_E8		MAGX_E8			1791 |  | ||||||
|  magx_z6			MACH_MAGX_Z6		MAGX_Z6			1792 |  | ||||||
| @@ -1876,7 +1877,7 @@ ued			MACH_UED		UED			1885 |  | ||||||
|  esiblade		MACH_ESIBLADE		ESIBLADE		1886 |  | ||||||
|  eye02			MACH_EYE02		EYE02			1887 |  | ||||||
|  imx27kbd		MACH_IMX27KBD		IMX27KBD		1888 |  | ||||||
| -sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889 |  | ||||||
| +p87_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889 |  | ||||||
|  kixvp435		MACH_KIXVP435		KIXVP435		1890 |  | ||||||
|  kixnp435		MACH_KIXNP435		KIXNP435		1891 |  | ||||||
|  africa			MACH_AFRICA		AFRICA			1892 |  | ||||||
| @@ -1993,7 +1994,7 @@ spark			MACH_SPARK		SPARK			2002 |  | ||||||
|  benzina			MACH_BENZINA		BENZINA			2003 |  | ||||||
|  blaze			MACH_BLAZE		BLAZE			2004 |  | ||||||
|  linkstation_ls_hgl	MACH_LINKSTATION_LS_HGL	LINKSTATION_LS_HGL	2005 |  | ||||||
| -htckovsky		MACH_HTCVENUS		HTCVENUS		2006 |  | ||||||
| +htckovsky		MACH_HTCKOVSKY		HTCKOVSKY		2006 |  | ||||||
|  sony_prs505		MACH_SONY_PRS505	SONY_PRS505		2007 |  | ||||||
|  hanlin_v3		MACH_HANLIN_V3		HANLIN_V3		2008 |  | ||||||
|  sapphira		MACH_SAPPHIRA		SAPPHIRA		2009 |  | ||||||
| @@ -2239,7 +2240,7 @@ arm_ultimator2		MACH_ARM_ULTIMATOR2	ARM_ |  | ||||||
|  vs_v210			MACH_VS_V210		VS_V210			2252 |  | ||||||
|  vs_v212			MACH_VS_V212		VS_V212			2253 |  | ||||||
|  hmt			MACH_HMT		HMT			2254 |  | ||||||
| -suen3			MACH_SUEN3		SUEN3			2255 |  | ||||||
| +km_kirkwood		MACH_KM_KIRKWOOD	KM_KIRKWOOD		2255 |  | ||||||
|  vesper			MACH_VESPER		VESPER			2256 |  | ||||||
|  str9			MACH_STR9		STR9			2257 |  | ||||||
|  omap3_wl_ff		MACH_OMAP3_WL_FF	OMAP3_WL_FF		2258 |  | ||||||
| @@ -2256,7 +2257,7 @@ oratisalog		MACH_ORATISALOG		ORATISALOG |  | ||||||
|  oratismadi		MACH_ORATISMADI		ORATISMADI		2269 |  | ||||||
|  oratisot16		MACH_ORATISOT16		ORATISOT16		2270 |  | ||||||
|  oratisdesk		MACH_ORATISDESK		ORATISDESK		2271 |  | ||||||
| -v2_ca9			MACH_V2P_CA9		V2P_CA9			2272 |  | ||||||
| +vexpress		MACH_VEXPRESS		VEXPRESS		2272 |  | ||||||
|  sintexo			MACH_SINTEXO		SINTEXO			2273 |  | ||||||
|  cm3389			MACH_CM3389		CM3389			2274 |  | ||||||
|  omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275 |  | ||||||
| @@ -2307,7 +2308,7 @@ ecac2378		MACH_ECAC2378		ECAC2378		2319 |  | ||||||
|  tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320 |  | ||||||
|  whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321 |  | ||||||
|  sbox9263		MACH_SBOX9263		SBOX9263		2322 |  | ||||||
| -oreo			MACH_OREO		OREO			2323 |  | ||||||
| +oreo_camera		MACH_OREO		OREO			2323 |  | ||||||
|  smdk6442		MACH_SMDK6442		SMDK6442		2324 |  | ||||||
|  openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325 |  | ||||||
|  incredible		MACH_INCREDIBLE		INCREDIBLE		2326 |  | ||||||
| @@ -2320,7 +2321,7 @@ mx31txtr		MACH_MX31TXTR		MX31TXTR		2332 |  | ||||||
|  u380			MACH_U380		U380			2333 |  | ||||||
|  oamp3_hualu		MACH_HUALU_BOARD	HUALU_BOARD		2334 |  | ||||||
|  npcmx50			MACH_NPCMX50		NPCMX50			2335 |  | ||||||
| -mx51_lange51		MACH_MX51_LANGE51	MX51_LANGE51		2336 |  | ||||||
| +mx51_efikamx		MACH_MX51_EFIKAMX	MX51_EFIKAMX		2336 |  | ||||||
|  mx51_lange52		MACH_MX51_LANGE52	MX51_LANGE52		2337 |  | ||||||
|  riom			MACH_RIOM		RIOM			2338 |  | ||||||
|  comcas			MACH_COMCAS		COMCAS			2339 |  | ||||||
| @@ -2354,7 +2355,7 @@ at91sam9263cs		MACH_AT91SAM9263CS	AT91SA |  | ||||||
|  csb732			MACH_CSB732		CSB732			2367 |  | ||||||
|  u8500			MACH_U8500		U8500			2368 |  | ||||||
|  huqiu			MACH_HUQIU		HUQIU			2369 |  | ||||||
| -mx51_kunlun		MACH_MX51_KUNLUN	MX51_KUNLUN		2370 |  | ||||||
| +mx51_efikasb		MACH_MX51_EFIKASB	MX51_EFIKASB		2370 |  | ||||||
|  pmt1g			MACH_PMT1G		PMT1G			2371 |  | ||||||
|  htcelf			MACH_HTCELF		HTCELF			2372 |  | ||||||
|  armadillo420		MACH_ARMADILLO420	ARMADILLO420		2373 |  | ||||||
| @@ -2373,7 +2374,7 @@ sch_m490		MACH_SCH_M490		SCH_M490		2386 |  | ||||||
|  rbl01			MACH_RBL01		RBL01			2387 |  | ||||||
|  omnifi			MACH_OMNIFI		OMNIFI			2388 |  | ||||||
|  otavalo			MACH_OTAVALO		OTAVALO			2389 |  | ||||||
| -sienna			MACH_SIENNA		SIENNA			2390 |  | ||||||
| +siena			MACH_SIENNA		SIENNA			2390 |  | ||||||
|  htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391 |  | ||||||
|  htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392 |  | ||||||
|  touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393 |  | ||||||
| @@ -2445,7 +2446,7 @@ siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1 |  | ||||||
|  siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459 |  | ||||||
|  sm3k			MACH_SM3K		SM3K			2460 |  | ||||||
|  acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461 |  | ||||||
| -sst61vc010_dev		MACH_SST61VC010_DEV	SST61VC010_DEV		2462 |  | ||||||
| +p87_dev			MACH_SST61VC010_DEV	SST61VC010_DEV		2462 |  | ||||||
|  glittertind		MACH_GLITTERTIND	GLITTERTIND		2463 |  | ||||||
|  omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464 |  | ||||||
|  omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465 |  | ||||||
| @@ -2497,7 +2498,7 @@ hiram			MACH_HIRAM		HIRAM			2510 |  | ||||||
|  phy3250			MACH_PHY3250		PHY3250			2511 |  | ||||||
|  ea3250			MACH_EA3250		EA3250			2512 |  | ||||||
|  fdi3250			MACH_FDI3250		FDI3250			2513 |  | ||||||
| -whitestone		MACH_WHITESTONE		WHITESTONE		2514 |  | ||||||
| +htcwhitestone		MACH_WHITESTONE		WHITESTONE		2514 |  | ||||||
|  at91sam9263nit		MACH_AT91SAM9263NIT	AT91SAM9263NIT		2515 |  | ||||||
|  ccmx51			MACH_CCMX51		CCMX51			2516 |  | ||||||
|  ccmx51js		MACH_CCMX51JS		CCMX51JS		2517 |  | ||||||
| @@ -2535,4 +2536,787 @@ davinci_dm6467tevm	MACH_DAVINCI_DM6467TE |  | ||||||
|  c3ax03			MACH_C3AX03		C3AX03			2549 |  | ||||||
|  mxt_td60		MACH_MXT_TD60		MXT_TD60		2550 |  | ||||||
|  esyx			MACH_ESYX		ESYX			2551 |  | ||||||
| +dove_db2		MACH_DOVE_DB2		DOVE_DB2		2552 |  | ||||||
|  bulldog			MACH_BULLDOG		BULLDOG			2553 |  | ||||||
| +derell_me2000		MACH_DERELL_ME2000	DERELL_ME2000		2554 |  | ||||||
| +bcmring_base		MACH_BCMRING_BASE	BCMRING_BASE		2555 |  | ||||||
| +bcmring_evm		MACH_BCMRING_EVM	BCMRING_EVM		2556 |  | ||||||
| +bcmring_evm_jazz	MACH_BCMRING_EVM_JAZZ	BCMRING_EVM_JAZZ	2557 |  | ||||||
| +bcmring_sp		MACH_BCMRING_SP		BCMRING_SP		2558 |  | ||||||
| +bcmring_sv		MACH_BCMRING_SV		BCMRING_SV		2559 |  | ||||||
| +bcmring_sv_jazz		MACH_BCMRING_SV_JAZZ	BCMRING_SV_JAZZ		2560 |  | ||||||
| +bcmring_tablet		MACH_BCMRING_TABLET	BCMRING_TABLET		2561 |  | ||||||
| +bcmring_vp		MACH_BCMRING_VP		BCMRING_VP		2562 |  | ||||||
| +bcmring_evm_seikor	MACH_BCMRING_EVM_SEIKOR	BCMRING_EVM_SEIKOR	2563 |  | ||||||
| +bcmring_sp_wqvga	MACH_BCMRING_SP_WQVGA	BCMRING_SP_WQVGA	2564 |  | ||||||
| +bcmring_custom		MACH_BCMRING_CUSTOM	BCMRING_CUSTOM		2565 |  | ||||||
| +acer_s200		MACH_ACER_S200		ACER_S200		2566 |  | ||||||
| +bt270			MACH_BT270		BT270			2567 |  | ||||||
| +iseo			MACH_ISEO		ISEO			2568 |  | ||||||
| +cezanne			MACH_CEZANNE		CEZANNE			2569 |  | ||||||
| +lucca			MACH_LUCCA		LUCCA			2570 |  | ||||||
| +supersmart		MACH_SUPERSMART		SUPERSMART		2571 |  | ||||||
| +arm11_board		MACH_CS_MISANO		CS_MISANO		2572 |  | ||||||
| +magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573 |  | ||||||
| +emxx			MACH_EMXX		EMXX			2574 |  | ||||||
| +outlaw			MACH_OUTLAW		OUTLAW			2575 |  | ||||||
| +riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576 |  | ||||||
| +riot_gx2		MACH_RIOT_VOX		RIOT_VOX		2577 |  | ||||||
| +riot_x37		MACH_RIOT_X37		RIOT_X37		2578 |  | ||||||
| +mega25mx		MACH_MEGA25MX		MEGA25MX		2579 |  | ||||||
| +benzina2		MACH_BENZINA2		BENZINA2		2580 |  | ||||||
| +ignite			MACH_IGNITE		IGNITE			2581 |  | ||||||
| +foggia			MACH_FOGGIA		FOGGIA			2582 |  | ||||||
| +arezzo			MACH_AREZZO		AREZZO			2583 |  | ||||||
| +leica_skywalker		MACH_LEICA_SKYWALKER	LEICA_SKYWALKER		2584 |  | ||||||
| +jacinto2_jamr		MACH_JACINTO2_JAMR	JACINTO2_JAMR		2585 |  | ||||||
| +gts_nova		MACH_GTS_NOVA		GTS_NOVA		2586 |  | ||||||
| +p3600			MACH_P3600		P3600			2587 |  | ||||||
| +dlt2			MACH_DLT2		DLT2			2588 |  | ||||||
| +df3120			MACH_DF3120		DF3120			2589 |  | ||||||
| +ecucore_9g20		MACH_ECUCORE_9G20	ECUCORE_9G20		2590 |  | ||||||
| +nautel_lpc3240		MACH_NAUTEL_LPC3240	NAUTEL_LPC3240		2591 |  | ||||||
| +glacier			MACH_GLACIER		GLACIER			2592 |  | ||||||
| +phrazer_bulldog		MACH_PHRAZER_BULLDOG	PHRAZER_BULLDOG		2593 |  | ||||||
| +omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_BULLDOG		2594 |  | ||||||
| +pca101			MACH_PCA101		PCA101			2595 |  | ||||||
| +buzzc			MACH_BUZZC		BUZZC			2596 |  | ||||||
| +sasie2			MACH_SASIE2		SASIE2			2597 |  | ||||||
| +davinci_dm6467_cio	MACH_DAVINCI_CIO	DAVINCI_CIO		2598 |  | ||||||
| +smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599 |  | ||||||
| +wzl6410			MACH_WZL6410		WZL6410			2600 |  | ||||||
| +wzl6410m		MACH_WZL6410M		WZL6410M		2601 |  | ||||||
| +wzl6410f		MACH_WZL6410F		WZL6410F		2602 |  | ||||||
| +wzl6410i		MACH_WZL6410I		WZL6410I		2603 |  | ||||||
| +spacecom1		MACH_SPACECOM1		SPACECOM1		2604 |  | ||||||
| +pingu920		MACH_PINGU920		PINGU920		2605 |  | ||||||
| +bravoc			MACH_BRAVOC		BRAVOC			2606 |  | ||||||
| +mydev			MACH_CYBO2440		CYBO2440		2607 |  | ||||||
| +vdssw			MACH_VDSSW		VDSSW			2608 |  | ||||||
| +romulus			MACH_ROMULUS		ROMULUS			2609 |  | ||||||
| +omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610 |  | ||||||
| +eltd100			MACH_ELTD100		ELTD100			2611 |  | ||||||
| +capc7117		MACH_CAPC7117		CAPC7117		2612 |  | ||||||
| +swan			MACH_SWAN		SWAN			2613 |  | ||||||
| +veu			MACH_VEU		VEU			2614 |  | ||||||
| +rm2			MACH_RM2		RM2			2615 |  | ||||||
| +tt2100			MACH_TT2100		TT2100			2616 |  | ||||||
| +venice			MACH_VENICE		VENICE			2617 |  | ||||||
| +pc7323			MACH_PC7323		PC7323			2618 |  | ||||||
| +masp			MACH_MASP		MASP			2619 |  | ||||||
| +fujitsu_tvstbsoc0	MACH_FUJITSU_TVSTBSOC	FUJITSU_TVSTBSOC	2620 |  | ||||||
| +fujitsu_tvstbsoc1	MACH_FUJITSU_TVSTBSOC1	FUJITSU_TVSTBSOC1	2621 |  | ||||||
| +lexikon			MACH_LEXIKON		LEXIKON			2622 |  | ||||||
| +mini2440v2		MACH_MINI2440V2		MINI2440V2		2623 |  | ||||||
| +icontrol		MACH_ICONTROL		ICONTROL		2624 |  | ||||||
| +gplugd			MACH_SHEEVAD		SHEEVAD			2625 |  | ||||||
| +qsd8x50a_st1_1		MACH_QSD8X50A_ST1_1	QSD8X50A_ST1_1		2626 |  | ||||||
| +qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627 |  | ||||||
| +bee			MACH_BEE		BEE			2628 |  | ||||||
| +mx23evk			MACH_MX23EVK		MX23EVK			2629 |  | ||||||
| +ap4evb			MACH_AP4EVB		AP4EVB			2630 |  | ||||||
| +stockholm		MACH_STOCKHOLM		STOCKHOLM		2631 |  | ||||||
| +lpc_h3131		MACH_LPC_H3131		LPC_H3131		2632 |  | ||||||
| +stingray		MACH_STINGRAY		STINGRAY		2633 |  | ||||||
| +kraken			MACH_KRAKEN		KRAKEN			2634 |  | ||||||
| +gw2388			MACH_GW2388		GW2388			2635 |  | ||||||
| +jadecpu			MACH_JADECPU		JADECPU			2636 |  | ||||||
| +carlisle		MACH_CARLISLE		CARLISLE		2637 |  | ||||||
| +lux_sf9			MACH_LUX_SF9		LUX_SF9			2638 |  | ||||||
| +nemid_tb		MACH_NEMID_TB		NEMID_TB		2639 |  | ||||||
| +terrier			MACH_TERRIER		TERRIER			2640 |  | ||||||
| +turbot			MACH_TURBOT		TURBOT			2641 |  | ||||||
| +sanddab			MACH_SANDDAB		SANDDAB			2642 |  | ||||||
| +mx35_cicada		MACH_MX35_CICADA	MX35_CICADA		2643 |  | ||||||
| +ghi2703d		MACH_GHI2703D		GHI2703D		2644 |  | ||||||
| +lux_sfx9		MACH_LUX_SFX9		LUX_SFX9		2645 |  | ||||||
| +lux_sf9g		MACH_LUX_SF9G		LUX_SF9G		2646 |  | ||||||
| +lux_edk9		MACH_LUX_EDK9		LUX_EDK9		2647 |  | ||||||
| +hw90240			MACH_HW90240		HW90240			2648 |  | ||||||
| +dm365_leopard		MACH_DM365_LEOPARD	DM365_LEOPARD		2649 |  | ||||||
| +mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650 |  | ||||||
| +scat110			MACH_SCAT110		SCAT110			2651 |  | ||||||
| +acer_a1			MACH_ACER_A1		ACER_A1			2652 |  | ||||||
| +cmcontrol		MACH_CMCONTROL		CMCONTROL		2653 |  | ||||||
| +pelco_lamar		MACH_PELCO_LAMAR	PELCO_LAMAR		2654 |  | ||||||
| +rfp43			MACH_RFP43		RFP43			2655 |  | ||||||
| +sk86r0301		MACH_SK86R0301		SK86R0301		2656 |  | ||||||
| +ctpxa			MACH_CTPXA		CTPXA			2657 |  | ||||||
| +epb_arm9_a		MACH_EPB_ARM9_A		EPB_ARM9_A		2658 |  | ||||||
| +guruplug		MACH_GURUPLUG		GURUPLUG		2659 |  | ||||||
| +spear310		MACH_SPEAR310		SPEAR310		2660 |  | ||||||
| +spear320		MACH_SPEAR320		SPEAR320		2661 |  | ||||||
| +robotx			MACH_ROBOTX		ROBOTX			2662 |  | ||||||
| +lsxhl			MACH_LSXHL		LSXHL			2663 |  | ||||||
| +smartlite		MACH_SMARTLITE		SMARTLITE		2664 |  | ||||||
| +cws2			MACH_CWS2		CWS2			2665 |  | ||||||
| +m619			MACH_M619		M619			2666 |  | ||||||
| +smartview		MACH_SMARTVIEW		SMARTVIEW		2667 |  | ||||||
| +lsa_salsa		MACH_LSA_SALSA		LSA_SALSA		2668 |  | ||||||
| +kizbox			MACH_KIZBOX		KIZBOX			2669 |  | ||||||
| +htccharmer		MACH_HTCCHARMER		HTCCHARMER		2670 |  | ||||||
| +guf_neso_lt		MACH_GUF_NESO_LT	GUF_NESO_LT		2671 |  | ||||||
| +pm9g45			MACH_PM9G45		PM9G45			2672 |  | ||||||
| +htcpanther		MACH_HTCPANTHER		HTCPANTHER		2673 |  | ||||||
| +htcpanther_cdma		MACH_HTCPANTHER_CDMA	HTCPANTHER_CDMA		2674 |  | ||||||
| +reb01			MACH_REB01		REB01			2675 |  | ||||||
| +aquila			MACH_AQUILA		AQUILA			2676 |  | ||||||
| +spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677 |  | ||||||
| +sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678 |  | ||||||
| +msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679 |  | ||||||
| +micro2440		MACH_MICRO2440		MICRO2440		2680 |  | ||||||
| +am2440			MACH_AM2440		AM2440			2681 |  | ||||||
| +tq2440			MACH_TQ2440		TQ2440			2682 |  | ||||||
| +lpc2478oem		MACH_LPC2478OEM		LPC2478OEM		2683 |  | ||||||
| +ak880x			MACH_AK880X		AK880X			2684 |  | ||||||
| +cobra3530		MACH_COBRA3530		COBRA3530		2685 |  | ||||||
| +pmppb			MACH_PMPPB		PMPPB			2686 |  | ||||||
| +u6715			MACH_U6715		U6715			2687 |  | ||||||
| +axar1500_sender		MACH_AXAR1500_SENDER	AXAR1500_SENDER		2688 |  | ||||||
| +g30_dvb			MACH_G30_DVB		G30_DVB			2689 |  | ||||||
| +vc088x			MACH_VC088X		VC088X			2690 |  | ||||||
| +mioa702			MACH_MIOA702		MIOA702			2691 |  | ||||||
| +hpmin			MACH_HPMIN		HPMIN			2692 |  | ||||||
| +ak880xak		MACH_AK880XAK		AK880XAK		2693 |  | ||||||
| +arm926tomap850		MACH_ARM926TOMAP850	ARM926TOMAP850		2694 |  | ||||||
| +lkevm			MACH_LKEVM		LKEVM			2695 |  | ||||||
| +mw6410			MACH_MW6410		MW6410			2696 |  | ||||||
| +terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697 |  | ||||||
| +cpu8000e		MACH_CPU8000E		CPU8000E		2698 |  | ||||||
| +catania_s		MACH_CATANIA		CATANIA			2699 |  | ||||||
| +tokyo			MACH_TOKYO		TOKYO			2700 |  | ||||||
| +msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701 |  | ||||||
| +msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702 |  | ||||||
| +msm7x25_surf		MACH_MSM7X25_SURF	MSM7X25_SURF		2703 |  | ||||||
| +msm7x25_ffa		MACH_MSM7X25_FFA	MSM7X25_FFA		2704 |  | ||||||
| +msm7x27_surf		MACH_MSM7X27_SURF	MSM7X27_SURF		2705 |  | ||||||
| +msm7x27_ffa		MACH_MSM7X27_FFA	MSM7X27_FFA		2706 |  | ||||||
| +msm7x30_ffa		MACH_MSM7X30_FFA	MSM7X30_FFA		2707 |  | ||||||
| +qsd8x50_surf		MACH_QSD8X50_SURF	QSD8X50_SURF		2708 |  | ||||||
| +qsd8x50_comet		MACH_QSD8X50_COMET	QSD8X50_COMET		2709 |  | ||||||
| +qsd8x50_ffa		MACH_QSD8X50_FFA	QSD8X50_FFA		2710 |  | ||||||
| +qsd8x50a_surf		MACH_QSD8X50A_SURF	QSD8X50A_SURF		2711 |  | ||||||
| +qsd8x50a_ffa		MACH_QSD8X50A_FFA	QSD8X50A_FFA		2712 |  | ||||||
| +adx_xgcp10		MACH_ADX_XGCP10		ADX_XGCP10		2713 |  | ||||||
| +mcgwumts2a		MACH_MCGWUMTS2A		MCGWUMTS2A		2714 |  | ||||||
| +mobikt			MACH_MOBIKT		MOBIKT			2715 |  | ||||||
| +mx53_evk		MACH_MX53_EVK		MX53_EVK		2716 |  | ||||||
| +igep0030		MACH_IGEP0030		IGEP0030		2717 |  | ||||||
| +axell_h40_h50_ctrl	MACH_AXELL_H40_H50_CTRL	AXELL_H40_H50_CTRL	2718 |  | ||||||
| +dtcommod		MACH_DTCOMMOD		DTCOMMOD		2719 |  | ||||||
| +gould			MACH_GOULD		GOULD			2720 |  | ||||||
| +siberia			MACH_SIBERIA		SIBERIA			2721 |  | ||||||
| +sbc3530			MACH_SBC3530		SBC3530			2722 |  | ||||||
| +qarm			MACH_QARM		QARM			2723 |  | ||||||
| +mips			MACH_MIPS		MIPS			2724 |  | ||||||
| +mx27grb			MACH_MX27GRB		MX27GRB			2725 |  | ||||||
| +sbc8100			MACH_SBC8100		SBC8100			2726 |  | ||||||
| +saarb			MACH_SAARB		SAARB			2727 |  | ||||||
| +omap3mini		MACH_OMAP3MINI		OMAP3MINI		2728 |  | ||||||
| +cnmbook7se		MACH_CNMBOOK7SE		CNMBOOK7SE		2729 |  | ||||||
| +catan			MACH_CATAN		CATAN			2730 |  | ||||||
| +harmony			MACH_HARMONY		HARMONY			2731 |  | ||||||
| +tonga			MACH_TONGA		TONGA			2732 |  | ||||||
| +cybook_orizon		MACH_CYBOOK_ORIZON	CYBOOK_ORIZON		2733 |  | ||||||
| +htcrhodiumcdma		MACH_HTCRHODIUMCDMA	HTCRHODIUMCDMA		2734 |  | ||||||
| +epc_g45			MACH_EPC_G45		EPC_G45			2735 |  | ||||||
| +epc_lpc3250		MACH_EPC_LPC3250	EPC_LPC3250		2736 |  | ||||||
| +mxc91341evb		MACH_MXC91341EVB	MXC91341EVB		2737 |  | ||||||
| +rtw1000			MACH_RTW1000		RTW1000			2738 |  | ||||||
| +bobcat			MACH_BOBCAT		BOBCAT			2739 |  | ||||||
| +trizeps6		MACH_TRIZEPS6		TRIZEPS6		2740 |  | ||||||
| +msm7x30_fluid		MACH_MSM7X30_FLUID	MSM7X30_FLUID		2741 |  | ||||||
| +nedap9263		MACH_NEDAP9263		NEDAP9263		2742 |  | ||||||
| +netgear_ms2110		MACH_NETGEAR_MS2110	NETGEAR_MS2110		2743 |  | ||||||
| +bmx			MACH_BMX		BMX			2744 |  | ||||||
| +netstream		MACH_NETSTREAM		NETSTREAM		2745 |  | ||||||
| +vpnext_rcu		MACH_VPNEXT_RCU		VPNEXT_RCU		2746 |  | ||||||
| +vpnext_mpu		MACH_VPNEXT_MPU		VPNEXT_MPU		2747 |  | ||||||
| +bcmring_tablet_v1	MACH_BCMRING_TABLET_V1	BCMRING_TABLET_V1	2748 |  | ||||||
| +sgarm10			MACH_SGARM10		SGARM10			2749 |  | ||||||
| +cm_t3517		MACH_CM_T3517		CM_T3517		2750 |  | ||||||
| +omap3_cps		MACH_OMAP3_CPS		OMAP3_CPS		2751 |  | ||||||
| +axar1500_receiver	MACH_AXAR1500_RECEIVER	AXAR1500_RECEIVER	2752 |  | ||||||
| +wbd222			MACH_WBD222		WBD222			2753 |  | ||||||
| +mt65xx			MACH_MT65XX		MT65XX			2754 |  | ||||||
| +msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755 |  | ||||||
| +msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756 |  | ||||||
| +cvc600			MACH_VMC300		VMC300			2757 |  | ||||||
| +tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758 |  | ||||||
| +nanos			MACH_NANOS		NANOS			2759 |  | ||||||
| +stamp9g10		MACH_STAMP9G10		STAMP9G10		2760 |  | ||||||
| +stamp9g45		MACH_STAMP9G45		STAMP9G45		2761 |  | ||||||
| +h6053			MACH_H6053		H6053			2762 |  | ||||||
| +smint01			MACH_SMINT01		SMINT01			2763 |  | ||||||
| +prtlvt2			MACH_PRTLVT2		PRTLVT2			2764 |  | ||||||
| +ap420			MACH_AP420		AP420			2765 |  | ||||||
| +htcclio			MACH_HTCSHIFT		HTCSHIFT		2766 |  | ||||||
| +davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767 |  | ||||||
| +msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768 |  | ||||||
| +msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769 |  | ||||||
| +esl_vamana		MACH_ESL_VAMANA		ESL_VAMANA		2770 |  | ||||||
| +sbc35			MACH_SBC35		SBC35			2771 |  | ||||||
| +mpx6446			MACH_MPX6446		MPX6446			2772 |  | ||||||
| +oreo_controller		MACH_OREO_CONTROLLER	OREO_CONTROLLER		2773 |  | ||||||
| +kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774 |  | ||||||
| +ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775 |  | ||||||
| +cns3420vb		MACH_CNS3420VB		CNS3420VB		2776 |  | ||||||
| +lpc_evo			MACH_LPC2		LPC2			2777 |  | ||||||
| +olympus			MACH_OLYMPUS		OLYMPUS			2778 |  | ||||||
| +vortex			MACH_VORTEX		VORTEX			2779 |  | ||||||
| +s5pc200			MACH_S5PC200		S5PC200			2780 |  | ||||||
| +ecucore_9263		MACH_ECUCORE_9263	ECUCORE_9263		2781 |  | ||||||
| +smdkc200		MACH_SMDKC200		SMDKC200		2782 |  | ||||||
| +emsiso_sx27		MACH_EMSISO_SX27	EMSISO_SX27		2783 |  | ||||||
| +apx_som9g45_ek		MACH_APX_SOM9G45_EK	APX_SOM9G45_EK		2784 |  | ||||||
| +songshan		MACH_SONGSHAN		SONGSHAN		2785 |  | ||||||
| +tianshan		MACH_TIANSHAN		TIANSHAN		2786 |  | ||||||
| +vpx500			MACH_VPX500		VPX500			2787 |  | ||||||
| +am3517sam		MACH_AM3517SAM		AM3517SAM		2788 |  | ||||||
| +skat91_sim508		MACH_SKAT91_SIM508	SKAT91_SIM508		2789 |  | ||||||
| +skat91_s3e		MACH_SKAT91_S3E		SKAT91_S3E		2790 |  | ||||||
| +omap4_panda		MACH_OMAP4_PANDA	OMAP4_PANDA		2791 |  | ||||||
| +df7220			MACH_DF7220		DF7220			2792 |  | ||||||
| +nemini			MACH_NEMINI		NEMINI			2793 |  | ||||||
| +t8200			MACH_T8200		T8200			2794 |  | ||||||
| +apf51			MACH_APF51		APF51			2795 |  | ||||||
| +dr_rc_unit		MACH_DR_RC_UNIT		DR_RC_UNIT		2796 |  | ||||||
| +bordeaux		MACH_BORDEAUX		BORDEAUX		2797 |  | ||||||
| +catania_b		MACH_CATANIA_B		CATANIA_B		2798 |  | ||||||
| +mx51_ocean		MACH_MX51_OCEAN		MX51_OCEAN		2799 |  | ||||||
| +ti8168evm		MACH_TI8168EVM		TI8168EVM		2800 |  | ||||||
| +neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801 |  | ||||||
| +withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802 |  | ||||||
| +dbps			MACH_DBPS		DBPS			2803 |  | ||||||
| +at91sam9261		MACH_SBC9261		SBC9261			2804 |  | ||||||
| +pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805 |  | ||||||
| +speedy			MACH_SPEEDY		SPEEDY			2806 |  | ||||||
| +chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807 |  | ||||||
| +tango			MACH_TANGO		TANGO			2808 |  | ||||||
| +synology_dsx11		MACH_SYNOLOGY_DSX11	SYNOLOGY_DSX11		2809 |  | ||||||
| +hanlin_v3ext		MACH_HANLIN_V3EXT	HANLIN_V3EXT		2810 |  | ||||||
| +hanlin_v5		MACH_HANLIN_V5		HANLIN_V5		2811 |  | ||||||
| +hanlin_v3plus		MACH_HANLIN_V3PLUS	HANLIN_V3PLUS		2812 |  | ||||||
| +iriver_story		MACH_IRIVER_STORY	IRIVER_STORY		2813 |  | ||||||
| +irex_iliad		MACH_IREX_ILIAD		IREX_ILIAD		2814 |  | ||||||
| +irex_dr1000		MACH_IREX_DR1000	IREX_DR1000		2815 |  | ||||||
| +teton_bga		MACH_TETON_BGA		TETON_BGA		2816 |  | ||||||
| +snapper9g45		MACH_SNAPPER9G45	SNAPPER9G45		2817 |  | ||||||
| +tam3517			MACH_TAM3517		TAM3517			2818 |  | ||||||
| +pdc100			MACH_PDC100		PDC100			2819 |  | ||||||
| +eukrea_cpuimx25sd	MACH_EUKREA_CPUIMX25	EUKREA_CPUIMX25		2820 |  | ||||||
| +eukrea_cpuimx35sd	MACH_EUKREA_CPUIMX35	EUKREA_CPUIMX35		2821 |  | ||||||
| +eukrea_cpuimx51sd	MACH_EUKREA_CPUIMX51SD	EUKREA_CPUIMX51SD	2822 |  | ||||||
| +eukrea_cpuimx51		MACH_EUKREA_CPUIMX51	EUKREA_CPUIMX51		2823 |  | ||||||
| +p565			MACH_P565		P565			2824 |  | ||||||
| +acer_a4			MACH_ACER_A4		ACER_A4			2825 |  | ||||||
| +davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826 |  | ||||||
| +eshare			MACH_ESHARE		ESHARE			2827 |  | ||||||
| +omapl138_europa		MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828 |  | ||||||
| +wlbargn			MACH_WLBARGN		WLBARGN			2829 |  | ||||||
| +bm170			MACH_BM170		BM170			2830 |  | ||||||
| +netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831 |  | ||||||
| +netspace_plug_v2	MACH_NETSPACE_PLUG_V2	NETSPACE_PLUG_V2	2832 |  | ||||||
| +siemens_l1		MACH_SIEMENS_L1		SIEMENS_L1		2833 |  | ||||||
| +elv_lcu1		MACH_ELV_LCU1		ELV_LCU1		2834 |  | ||||||
| +mcu1			MACH_MCU1		MCU1			2835 |  | ||||||
| +omap3_tao3530		MACH_OMAP3_TAO3530	OMAP3_TAO3530		2836 |  | ||||||
| +omap3_pcutouch		MACH_OMAP3_PCUTOUCH	OMAP3_PCUTOUCH		2837 |  | ||||||
| +smdkc210		MACH_SMDKC210		SMDKC210		2838 |  | ||||||
| +omap3_braillo		MACH_OMAP3_BRAILLO	OMAP3_BRAILLO		2839 |  | ||||||
| +spyplug			MACH_SPYPLUG		SPYPLUG			2840 |  | ||||||
| +ginger			MACH_GINGER		GINGER			2841 |  | ||||||
| +tny_t3530		MACH_TNY_T3530		TNY_T3530		2842 |  | ||||||
| +pca102			MACH_PCA102		PCA102			2843 |  | ||||||
| +spade			MACH_SPADE		SPADE			2844 |  | ||||||
| +mxc25_topaz		MACH_MXC25_TOPAZ	MXC25_TOPAZ		2845 |  | ||||||
| +t5325			MACH_T5325		T5325			2846 |  | ||||||
| +gw2361			MACH_GW2361		GW2361			2847 |  | ||||||
| +elog			MACH_ELOG		ELOG			2848 |  | ||||||
| +income			MACH_INCOME		INCOME			2849 |  | ||||||
| +bcm589x			MACH_BCM589X		BCM589X			2850 |  | ||||||
| +etna			MACH_ETNA		ETNA			2851 |  | ||||||
| +hawks			MACH_HAWKS		HAWKS			2852 |  | ||||||
| +meson			MACH_MESON		MESON			2853 |  | ||||||
| +xsbase255		MACH_XSBASE255		XSBASE255		2854 |  | ||||||
| +pvm2030			MACH_PVM2030		PVM2030			2855 |  | ||||||
| +mioa502			MACH_MIOA502		MIOA502			2856 |  | ||||||
| +vvbox_sdorig2		MACH_VVBOX_SDORIG2	VVBOX_SDORIG2		2857 |  | ||||||
| +vvbox_sdlite2		MACH_VVBOX_SDLITE2	VVBOX_SDLITE2		2858 |  | ||||||
| +vvbox_sdpro4		MACH_VVBOX_SDPRO4	VVBOX_SDPRO4		2859 |  | ||||||
| +htc_spv_m700		MACH_HTC_SPV_M700	HTC_SPV_M700		2860 |  | ||||||
| +mx257sx			MACH_MX257SX		MX257SX			2861 |  | ||||||
| +goni			MACH_GONI		GONI			2862 |  | ||||||
| +msm8x55_svlte_ffa	MACH_MSM8X55_SVLTE_FFA	MSM8X55_SVLTE_FFA	2863 |  | ||||||
| +msm8x55_svlte_surf	MACH_MSM8X55_SVLTE_SURF	MSM8X55_SVLTE_SURF	2864 |  | ||||||
| +quickstep		MACH_QUICKSTEP		QUICKSTEP		2865 |  | ||||||
| +dmw96			MACH_DMW96		DMW96			2866 |  | ||||||
| +hammerhead		MACH_HAMMERHEAD		HAMMERHEAD		2867 |  | ||||||
| +trident			MACH_TRIDENT		TRIDENT			2868 |  | ||||||
| +lightning		MACH_LIGHTNING		LIGHTNING		2869 |  | ||||||
| +iconnect		MACH_ICONNECT		ICONNECT		2870 |  | ||||||
| +autobot			MACH_AUTOBOT		AUTOBOT			2871 |  | ||||||
| +coconut			MACH_COCONUT		COCONUT			2872 |  | ||||||
| +durian			MACH_DURIAN		DURIAN			2873 |  | ||||||
| +cayenne			MACH_CAYENNE		CAYENNE			2874 |  | ||||||
| +fuji			MACH_FUJI		FUJI			2875 |  | ||||||
| +synology_6282		MACH_SYNOLOGY_6282	SYNOLOGY_6282		2876 |  | ||||||
| +em1sy			MACH_EM1SY		EM1SY			2877 |  | ||||||
| +m502			MACH_M502		M502			2878 |  | ||||||
| +matrix518		MACH_MATRIX518		MATRIX518		2879 |  | ||||||
| +tiny_gurnard		MACH_TINY_GURNARD	TINY_GURNARD		2880 |  | ||||||
| +spear1310		MACH_SPEAR1310		SPEAR1310		2881 |  | ||||||
| +bv07			MACH_BV07		BV07			2882 |  | ||||||
| +mxt_td61		MACH_MXT_TD61		MXT_TD61		2883 |  | ||||||
| +openrd_ultimate		MACH_OPENRD_ULTIMATE	OPENRD_ULTIMATE		2884 |  | ||||||
| +devixp			MACH_DEVIXP		DEVIXP			2885 |  | ||||||
| +miccpt			MACH_MICCPT		MICCPT			2886 |  | ||||||
| +mic256			MACH_MIC256		MIC256			2887 |  | ||||||
| +as1167			MACH_AS1167		AS1167			2888 |  | ||||||
| +omap3_ibiza		MACH_OMAP3_IBIZA	OMAP3_IBIZA		2889 |  | ||||||
| +u5500			MACH_U5500		U5500			2890 |  | ||||||
| +davinci_picto		MACH_DAVINCI_PICTO	DAVINCI_PICTO		2891 |  | ||||||
| +mecha			MACH_MECHA		MECHA			2892 |  | ||||||
| +bubba3			MACH_BUBBA3		BUBBA3			2893 |  | ||||||
| +pupitre			MACH_PUPITRE		PUPITRE			2894 |  | ||||||
| +tegra_unused		MACH_TEGRA_HARMONY	TEGRA_HARMONY		2895 |  | ||||||
| +tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896 |  | ||||||
| +tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897 |  | ||||||
| +simplenet		MACH_SIMPLENET		SIMPLENET		2898 |  | ||||||
| +ec4350tbm		MACH_EC4350TBM		EC4350TBM		2899 |  | ||||||
| +pec_tc			MACH_PEC_TC		PEC_TC			2900 |  | ||||||
| +pec_hc2			MACH_PEC_HC2		PEC_HC2			2901 |  | ||||||
| +esl_mobilis_a		MACH_ESL_MOBILIS_A	ESL_MOBILIS_A		2902 |  | ||||||
| +esl_mobilis_b		MACH_ESL_MOBILIS_B	ESL_MOBILIS_B		2903 |  | ||||||
| +esl_wave_a		MACH_ESL_WAVE_A		ESL_WAVE_A		2904 |  | ||||||
| +esl_wave_b		MACH_ESL_WAVE_B		ESL_WAVE_B		2905 |  | ||||||
| +unisense_mmm		MACH_UNISENSE_MMM	UNISENSE_MMM		2906 |  | ||||||
| +blueshark		MACH_BLUESHARK		BLUESHARK		2907 |  | ||||||
| +e10			MACH_E10		E10			2908 |  | ||||||
| +app3k_robin		MACH_APP3K_ROBIN	APP3K_ROBIN		2909 |  | ||||||
| +pov15hd			MACH_POV15HD		POV15HD			2910 |  | ||||||
| +stella			MACH_STELLA		STELLA			2911 |  | ||||||
| +htc_iolite		MACH_MACH_HTC_IOLITE	MACH_HTC_IOLITE		2912 |  | ||||||
| +linkstation_lschl	MACH_LINKSTATION_LSCHL	LINKSTATION_LSCHL	2913 |  | ||||||
| +netwalker		MACH_NETWALKER		NETWALKER		2914 |  | ||||||
| +acsx106			MACH_ACSX106		ACSX106			2915 |  | ||||||
| +atlas5_c1		MACH_ATLAS5_C1		ATLAS5_C1		2916 |  | ||||||
| +nsb3ast			MACH_NSB3AST		NSB3AST			2917 |  | ||||||
| +gnet_slc		MACH_GNET_SLC		GNET_SLC		2918 |  | ||||||
| +af4000			MACH_AF4000		AF4000			2919 |  | ||||||
| +ark9431			MACH_ARK9431		ARK9431			2920 |  | ||||||
| +fs_s5pc100		MACH_FS_S5PC100		FS_S5PC100		2921 |  | ||||||
| +omap3505nova8		MACH_OMAP3505NOVA8	OMAP3505NOVA8		2922 |  | ||||||
| +omap3621_edp1		MACH_OMAP3621_EDP1	OMAP3621_EDP1		2923 |  | ||||||
| +oratisaes		MACH_ORATISAES		ORATISAES		2924 |  | ||||||
| +smdkv310		MACH_SMDKV310		SMDKV310		2925 |  | ||||||
| +siemens_l0		MACH_SIEMENS_L0		SIEMENS_L0		2926 |  | ||||||
| +ventana			MACH_VENTANA		VENTANA			2927 |  | ||||||
| +wm8505_7in_netbook	MACH_WM8505_7IN_NETBOOK	WM8505_7IN_NETBOOK	2928 |  | ||||||
| +ec4350sdb		MACH_EC4350SDB		EC4350SDB		2929 |  | ||||||
| +mimas			MACH_MIMAS		MIMAS			2930 |  | ||||||
| +titan			MACH_TITAN		TITAN			2931 |  | ||||||
| +craneboard		MACH_CRANEBOARD		CRANEBOARD		2932 |  | ||||||
| +es2440			MACH_ES2440		ES2440			2933 |  | ||||||
| +najay_a9263		MACH_NAJAY_A9263	NAJAY_A9263		2934 |  | ||||||
| +htctornado		MACH_HTCTORNADO		HTCTORNADO		2935 |  | ||||||
| +dimm_mx257		MACH_DIMM_MX257		DIMM_MX257		2936 |  | ||||||
| +jigen301		MACH_JIGEN		JIGEN			2937 |  | ||||||
| +smdk6450		MACH_SMDK6450		SMDK6450		2938 |  | ||||||
| +meno_qng		MACH_MENO_QNG		MENO_QNG		2939 |  | ||||||
| +ns2416			MACH_NS2416		NS2416			2940 |  | ||||||
| +rpc353			MACH_RPC353		RPC353			2941 |  | ||||||
| +tq6410			MACH_TQ6410		TQ6410			2942 |  | ||||||
| +sky6410			MACH_SKY6410		SKY6410			2943 |  | ||||||
| +dynasty			MACH_DYNASTY		DYNASTY			2944 |  | ||||||
| +vivo			MACH_VIVO		VIVO			2945 |  | ||||||
| +bury_bl7582		MACH_BURY_BL7582	BURY_BL7582		2946 |  | ||||||
| +bury_bps5270		MACH_BURY_BPS5270	BURY_BPS5270		2947 |  | ||||||
| +basi			MACH_BASI		BASI			2948 |  | ||||||
| +tn200			MACH_TN200		TN200			2949 |  | ||||||
| +c2mmi			MACH_C2MMI		C2MMI			2950 |  | ||||||
| +meson_6236m		MACH_MESON_6236M	MESON_6236M		2951 |  | ||||||
| +meson_8626m		MACH_MESON_8626M	MESON_8626M		2952 |  | ||||||
| +tube			MACH_TUBE		TUBE			2953 |  | ||||||
| +messina			MACH_MESSINA		MESSINA			2954 |  | ||||||
| +mx50_arm2		MACH_MX50_ARM2		MX50_ARM2		2955 |  | ||||||
| +cetus9263		MACH_CETUS9263		CETUS9263		2956 |  | ||||||
| +brownstone		MACH_BROWNSTONE		BROWNSTONE		2957 |  | ||||||
| +vmx25			MACH_VMX25		VMX25			2958 |  | ||||||
| +vmx51			MACH_VMX51		VMX51			2959 |  | ||||||
| +abacus			MACH_ABACUS		ABACUS			2960 |  | ||||||
| +cm4745			MACH_CM4745		CM4745			2961 |  | ||||||
| +oratislink		MACH_ORATISLINK		ORATISLINK		2962 |  | ||||||
| +davinci_dm365_dvr	MACH_DAVINCI_DM365_DVR	DAVINCI_DM365_DVR	2963 |  | ||||||
| +netviz			MACH_NETVIZ		NETVIZ			2964 |  | ||||||
| +flexibity		MACH_FLEXIBITY		FLEXIBITY		2965 |  | ||||||
| +wlan_computer		MACH_WLAN_COMPUTER	WLAN_COMPUTER		2966 |  | ||||||
| +lpc24xx			MACH_LPC24XX		LPC24XX			2967 |  | ||||||
| +spica			MACH_SPICA		SPICA			2968 |  | ||||||
| +gpsdisplay		MACH_GPSDISPLAY		GPSDISPLAY		2969 |  | ||||||
| +bipnet			MACH_BIPNET		BIPNET			2970 |  | ||||||
| +overo_ctu_inertial	MACH_OVERO_CTU_INERTIAL	OVERO_CTU_INERTIAL	2971 |  | ||||||
| +davinci_dm355_mmm	MACH_DAVINCI_DM355_MMM	DAVINCI_DM355_MMM	2972 |  | ||||||
| +pc9260_v2		MACH_PC9260_V2		PC9260_V2		2973 |  | ||||||
| +ptx7545			MACH_PTX7545		PTX7545			2974 |  | ||||||
| +tm_efdc			MACH_TM_EFDC		TM_EFDC			2975 |  | ||||||
| +remove_me		MACH_WALDO1		WALDO1			2976 |  | ||||||
| +omap3_waldo1		MACH_OMAP3_WALDO1	OMAP3_WALDO1		2977 |  | ||||||
| +flyer			MACH_FLYER		FLYER			2978 |  | ||||||
| +tornado3240		MACH_TORNADO3240	TORNADO3240		2979 |  | ||||||
| +soli_01			MACH_SOLI_01		SOLI_01			2980 |  | ||||||
| +omapl138_europalc	MACH_OMAPL138_EUROPALC	OMAPL138_EUROPALC	2981 |  | ||||||
| +helios_v1		MACH_HELIOS_V1		HELIOS_V1		2982 |  | ||||||
| +netspace_lite_v2	MACH_NETSPACE_LITE_V2	NETSPACE_LITE_V2	2983 |  | ||||||
| +ssc			MACH_SSC		SSC			2984 |  | ||||||
| +premierwave_en		MACH_PREMIERWAVE_EN	PREMIERWAVE_EN		2985 |  | ||||||
| +wasabi			MACH_WASABI		WASABI			2986 |  | ||||||
| +vivo_w			MACH_VIVOW		VIVOW			2987 |  | ||||||
| +mx50_rdp		MACH_MX50_RDP		MX50_RDP		2988 |  | ||||||
| +universal_c210		MACH_UNIVERSAL_C210	UNIVERSAL_C210		2989 |  | ||||||
| +real6410		MACH_REAL6410		REAL6410		2990 |  | ||||||
| +spx_sakura		MACH_SPX_SAKURA		SPX_SAKURA		2991 |  | ||||||
| +ij3k_2440		MACH_IJ3K_2440		IJ3K_2440		2992 |  | ||||||
| +omap3_bc10		MACH_OMAP3_BC10		OMAP3_BC10		2993 |  | ||||||
| +thebe			MACH_THEBE		THEBE			2994 |  | ||||||
| +rv082			MACH_RV082		RV082			2995 |  | ||||||
| +armlguest		MACH_ARMLGUEST		ARMLGUEST		2996 |  | ||||||
| +tjinc1000		MACH_TJINC1000		TJINC1000		2997 |  | ||||||
| +dockstar		MACH_DOCKSTAR		DOCKSTAR		2998 |  | ||||||
| +ax8008			MACH_AX8008		AX8008			2999 |  | ||||||
| +gnet_sgce		MACH_GNET_SGCE		GNET_SGCE		3000 |  | ||||||
| +pxwnas_500_1000		MACH_PXWNAS_500_1000	PXWNAS_500_1000		3001 |  | ||||||
| +ea20			MACH_EA20		EA20			3002 |  | ||||||
| +awm2			MACH_AWM2		AWM2			3003 |  | ||||||
| +ti8148evm		MACH_TI8148EVM		TI8148EVM		3004 |  | ||||||
| +seaboard		MACH_SEABOARD		SEABOARD		3005 |  | ||||||
| +linkstation_chlv2	MACH_LINKSTATION_CHLV2	LINKSTATION_CHLV2	3006 |  | ||||||
| +tera_pro2_rack		MACH_TERA_PRO2_RACK	TERA_PRO2_RACK		3007 |  | ||||||
| +rubys			MACH_RUBYS		RUBYS			3008 |  | ||||||
| +aquarius		MACH_AQUARIUS		AQUARIUS		3009 |  | ||||||
| +mx53_ard		MACH_MX53_ARD		MX53_ARD		3010 |  | ||||||
| +mx53_smd		MACH_MX53_SMD		MX53_SMD		3011 |  | ||||||
| +lswxl			MACH_LSWXL		LSWXL			3012 |  | ||||||
| +dove_avng_v3		MACH_DOVE_AVNG_V3	DOVE_AVNG_V3		3013 |  | ||||||
| +sdi_ess_9263		MACH_SDI_ESS_9263	SDI_ESS_9263		3014 |  | ||||||
| +jocpu550		MACH_JOCPU550		JOCPU550		3015 |  | ||||||
| +msm8x60_rumi3		MACH_MSM8X60_RUMI3	MSM8X60_RUMI3		3016 |  | ||||||
| +msm8x60_ffa		MACH_MSM8X60_FFA	MSM8X60_FFA		3017 |  | ||||||
| +yanomami		MACH_YANOMAMI		YANOMAMI		3018 |  | ||||||
| +gta04			MACH_GTA04		GTA04			3019 |  | ||||||
| +cm_a510			MACH_CM_A510		CM_A510			3020 |  | ||||||
| +omap3_rfs200		MACH_OMAP3_RFS200	OMAP3_RFS200		3021 |  | ||||||
| +kx33xx			MACH_KX33XX		KX33XX			3022 |  | ||||||
| +ptx7510			MACH_PTX7510		PTX7510			3023 |  | ||||||
| +top9000			MACH_TOP9000		TOP9000			3024 |  | ||||||
| +teenote			MACH_TEENOTE		TEENOTE			3025 |  | ||||||
| +ts3			MACH_TS3		TS3			3026 |  | ||||||
| +a0			MACH_A0			A0			3027 |  | ||||||
| +fsm9xxx_surf		MACH_FSM9XXX_SURF	FSM9XXX_SURF		3028 |  | ||||||
| +fsm9xxx_ffa		MACH_FSM9XXX_FFA	FSM9XXX_FFA		3029 |  | ||||||
| +frrhwcdma60w		MACH_FRRHWCDMA60W	FRRHWCDMA60W		3030 |  | ||||||
| +remus			MACH_REMUS		REMUS			3031 |  | ||||||
| +at91cap7xdk		MACH_AT91CAP7XDK	AT91CAP7XDK		3032 |  | ||||||
| +at91cap7stk		MACH_AT91CAP7STK	AT91CAP7STK		3033 |  | ||||||
| +kt_sbc_sam9_1		MACH_KT_SBC_SAM9_1	KT_SBC_SAM9_1		3034 |  | ||||||
| +at91sam9263router	MACH_ORATISROUTER	ORATISROUTER		3035 |  | ||||||
| +armada_xp_db		MACH_ARMADA_XP_DB	ARMADA_XP_DB		3036 |  | ||||||
| +spdm			MACH_SPDM		SPDM			3037 |  | ||||||
| +gtib			MACH_GTIB		GTIB			3038 |  | ||||||
| +dgm3240			MACH_DGM3240		DGM3240			3039 |  | ||||||
| +iv_atlas_i_lpe		MACH_ATLAS_I_LPE	ATLAS_I_LPE		3040 |  | ||||||
| +htcmega			MACH_HTCMEGA		HTCMEGA			3041 |  | ||||||
| +tricorder		MACH_TRICORDER		TRICORDER		3042 |  | ||||||
| +tx28			MACH_TX28		TX28			3043 |  | ||||||
| +bstbrd			MACH_BSTBRD		BSTBRD			3044 |  | ||||||
| +pwb3090			MACH_PWB3090		PWB3090			3045 |  | ||||||
| +idea6410		MACH_IDEA6410		IDEA6410		3046 |  | ||||||
| +qbc9263			MACH_QBC9263		QBC9263			3047 |  | ||||||
| +borabora		MACH_BORABORA		BORABORA		3048 |  | ||||||
| +valdez			MACH_VALDEZ		VALDEZ			3049 |  | ||||||
| +ls9g20			MACH_LS9G20		LS9G20			3050 |  | ||||||
| +mios_v1			MACH_MIOS_V1		MIOS_V1			3051 |  | ||||||
| +s5pc110_crespo		MACH_S5PC110_CRESPO	S5PC110_CRESPO		3052 |  | ||||||
| +controltek9g20		MACH_CONTROLTEK9G20	CONTROLTEK9G20		3053 |  | ||||||
| +tin307			MACH_TIN307		TIN307			3054 |  | ||||||
| +tin510			MACH_TIN510		TIN510			3055 |  | ||||||
| +ep3505			MACH_EP3517		EP3517			3056 |  | ||||||
| +bluecheese		MACH_BLUECHEESE		BLUECHEESE		3057 |  | ||||||
| +tem3x30			MACH_TEM3X30		TEM3X30			3058 |  | ||||||
| +harvest_desoto		MACH_HARVEST_DESOTO	HARVEST_DESOTO		3059 |  | ||||||
| +msm8x60_qrdc		MACH_MSM8X60_QRDC	MSM8X60_QRDC		3060 |  | ||||||
| +spear900		MACH_SPEAR900		SPEAR900		3061 |  | ||||||
| +pcontrol_g20		MACH_PCONTROL_G20	PCONTROL_G20		3062 |  | ||||||
| +rdstor			MACH_RDSTOR		RDSTOR			3063 |  | ||||||
| +usdloader		MACH_USDLOADER		USDLOADER		3064 |  | ||||||
| +tsoploader		MACH_TSOPLOADER		TSOPLOADER		3065 |  | ||||||
| +kronos			MACH_KRONOS		KRONOS			3066 |  | ||||||
| +ffcore			MACH_FFCORE		FFCORE			3067 |  | ||||||
| +mone			MACH_MONE		MONE			3068 |  | ||||||
| +unit2s			MACH_UNIT2S		UNIT2S			3069 |  | ||||||
| +acer_a5			MACH_ACER_A5		ACER_A5			3070 |  | ||||||
| +etherpro_isp		MACH_ETHERPRO_ISP	ETHERPRO_ISP		3071 |  | ||||||
| +stretchs7000		MACH_STRETCHS7000	STRETCHS7000		3072 |  | ||||||
| +p87_smartsim		MACH_P87_SMARTSIM	P87_SMARTSIM		3073 |  | ||||||
| +tulip			MACH_TULIP		TULIP			3074 |  | ||||||
| +sunflower		MACH_SUNFLOWER		SUNFLOWER		3075 |  | ||||||
| +rib			MACH_RIB		RIB			3076 |  | ||||||
| +clod			MACH_CLOD		CLOD			3077 |  | ||||||
| +rump			MACH_RUMP		RUMP			3078 |  | ||||||
| +tenderloin		MACH_TENDERLOIN		TENDERLOIN		3079 |  | ||||||
| +shortloin		MACH_SHORTLOIN		SHORTLOIN		3080 |  | ||||||
| +roml1			MACH_CRESPO		CRESPO			3081 |  | ||||||
| +antares			MACH_ANTARES		ANTARES			3082 |  | ||||||
| +wb40n			MACH_WB40N		WB40N			3083 |  | ||||||
| +herring			MACH_HERRING		HERRING			3084 |  | ||||||
| +naxy400			MACH_NAXY400		NAXY400			3085 |  | ||||||
| +naxy1200		MACH_NAXY1200		NAXY1200		3086 |  | ||||||
| +vpr200			MACH_VPR200		VPR200			3087 |  | ||||||
| +bug20			MACH_BUG20		BUG20			3088 |  | ||||||
| +goflexnet		MACH_GOFLEXNET		GOFLEXNET		3089 |  | ||||||
| +torbreck		MACH_TORBRECK		TORBRECK		3090 |  | ||||||
| +saarb_mg1		MACH_SAARB_MG1		SAARB_MG1		3091 |  | ||||||
| +callisto		MACH_CALLISTO		CALLISTO		3092 |  | ||||||
| +multhsu			MACH_MULTHSU		MULTHSU			3093 |  | ||||||
| +saluda			MACH_SALUDA		SALUDA			3094 |  | ||||||
| +pemp_omap3_apollo	MACH_PEMP_OMAP3_APOLLO	PEMP_OMAP3_APOLLO	3095 |  | ||||||
| +vc0718			MACH_VC0718		VC0718			3096 |  | ||||||
| +mvblx			MACH_MVBLX		MVBLX			3097 |  | ||||||
| +inhand_apeiron		MACH_INHAND_APEIRON	INHAND_APEIRON		3098 |  | ||||||
| +inhand_fury		MACH_INHAND_FURY	INHAND_FURY		3099 |  | ||||||
| +inhand_siren		MACH_INHAND_SIREN	INHAND_SIREN		3100 |  | ||||||
| +hdnvp			MACH_HDNVP		HDNVP			3101 |  | ||||||
| +softwinner		MACH_SOFTWINNER		SOFTWINNER		3102 |  | ||||||
| +prima2_evb		MACH_PRIMA2_EVB		PRIMA2_EVB		3103 |  | ||||||
| +nas6210			MACH_NAS6210		NAS6210			3104 |  | ||||||
| +unisdev			MACH_UNISDEV		UNISDEV			3105 |  | ||||||
| +sbca11			MACH_SBCA11		SBCA11			3106 |  | ||||||
| +saga			MACH_SAGA		SAGA			3107 |  | ||||||
| +ns_k330			MACH_NS_K330		NS_K330			3108 |  | ||||||
| +tanna			MACH_TANNA		TANNA			3109 |  | ||||||
| +imate8502		MACH_IMATE8502		IMATE8502		3110 |  | ||||||
| +aspen			MACH_ASPEN		ASPEN			3111 |  | ||||||
| +daintree_cwac		MACH_DAINTREE_CWAC	DAINTREE_CWAC		3112 |  | ||||||
| +zmx25			MACH_ZMX25		ZMX25			3113 |  | ||||||
| +maple1			MACH_MAPLE1		MAPLE1			3114 |  | ||||||
| +qsd8x72_surf		MACH_QSD8X72_SURF	QSD8X72_SURF		3115 |  | ||||||
| +qsd8x72_ffa		MACH_QSD8X72_FFA	QSD8X72_FFA		3116 |  | ||||||
| +abilene			MACH_ABILENE		ABILENE			3117 |  | ||||||
| +eigen_ttr		MACH_EIGEN_TTR		EIGEN_TTR		3118 |  | ||||||
| +iomega_ix2_200		MACH_IOMEGA_IX2_200	IOMEGA_IX2_200		3119 |  | ||||||
| +coretec_vcx7400		MACH_CORETEC_VCX7400	CORETEC_VCX7400		3120 |  | ||||||
| +santiago		MACH_SANTIAGO		SANTIAGO		3121 |  | ||||||
| +mx257sol		MACH_MX257SOL		MX257SOL		3122 |  | ||||||
| +strasbourg		MACH_STRASBOURG		STRASBOURG		3123 |  | ||||||
| +msm8x60_fluid		MACH_MSM8X60_FLUID	MSM8X60_FLUID		3124 |  | ||||||
| +smartqv5		MACH_SMARTQV5		SMARTQV5		3125 |  | ||||||
| +smartqv3		MACH_SMARTQV3		SMARTQV3		3126 |  | ||||||
| +smartqv7		MACH_SMARTQV7		SMARTQV7		3127 |  | ||||||
| +tegra_paz00		MACH_PAZ00		PAZ00			3128 |  | ||||||
| +acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129 |  | ||||||
| +htc_willow		MACH_HTCWILLOW		HTCWILLOW		3130 |  | ||||||
| +fwbd_0404		MACH_FWBD_0404		FWBD_0404		3131 |  | ||||||
| +hdgu			MACH_HDGU		HDGU			3132 |  | ||||||
| +pyramid			MACH_PYRAMID		PYRAMID			3133 |  | ||||||
| +epiphan			MACH_EPIPHAN		EPIPHAN			3134 |  | ||||||
| +omap_bender		MACH_OMAP_BENDER	OMAP_BENDER		3135 |  | ||||||
| +gurnard			MACH_GURNARD		GURNARD			3136 |  | ||||||
| +gtl_it5100		MACH_GTL_IT5100		GTL_IT5100		3137 |  | ||||||
| +bcm2708			MACH_BCM2708		BCM2708			3138 |  | ||||||
| +mx51_ggc		MACH_MX51_GGC		MX51_GGC		3139 |  | ||||||
| +sharespace		MACH_SHARESPACE		SHARESPACE		3140 |  | ||||||
| +haba_knx_explorer	MACH_HABA_KNX_EXPLORER	HABA_KNX_EXPLORER	3141 |  | ||||||
| +simtec_kirkmod		MACH_SIMTEC_KIRKMOD	SIMTEC_KIRKMOD		3142 |  | ||||||
| +crux			MACH_CRUX		CRUX			3143 |  | ||||||
| +mx51_bravo		MACH_MX51_BRAVO		MX51_BRAVO		3144 |  | ||||||
| +charon			MACH_CHARON		CHARON			3145 |  | ||||||
| +picocom3		MACH_PICOCOM3		PICOCOM3		3146 |  | ||||||
| +picocom4		MACH_PICOCOM4		PICOCOM4		3147 |  | ||||||
| +serrano			MACH_SERRANO		SERRANO			3148 |  | ||||||
| +doubleshot		MACH_DOUBLESHOT		DOUBLESHOT		3149 |  | ||||||
| +evsy			MACH_EVSY		EVSY			3150 |  | ||||||
| +huashan			MACH_HUASHAN		HUASHAN			3151 |  | ||||||
| +lausanne		MACH_LAUSANNE		LAUSANNE		3152 |  | ||||||
| +emerald			MACH_EMERALD		EMERALD			3153 |  | ||||||
| +tqma35			MACH_TQMA35		TQMA35			3154 |  | ||||||
| +marvel			MACH_MARVEL		MARVEL			3155 |  | ||||||
| +manuae			MACH_MANUAE		MANUAE			3156 |  | ||||||
| +chacha			MACH_CHACHA		CHACHA			3157 |  | ||||||
| +lemon			MACH_LEMON		LEMON			3158 |  | ||||||
| +csc			MACH_CSC		CSC			3159 |  | ||||||
| +gira_knxip_router	MACH_GIRA_KNXIP_ROUTER	GIRA_KNXIP_ROUTER	3160 |  | ||||||
| +t20			MACH_T20		T20			3161 |  | ||||||
| +hdmini			MACH_HDMINI		HDMINI			3162 |  | ||||||
| +sciphone_g2		MACH_SCIPHONE_G2	SCIPHONE_G2		3163 |  | ||||||
| +express			MACH_EXPRESS		EXPRESS			3164 |  | ||||||
| +express_kt		MACH_EXPRESS_KT		EXPRESS_KT		3165 |  | ||||||
| +maximasp		MACH_MAXIMASP		MAXIMASP		3166 |  | ||||||
| +nitrogen_imx51		MACH_NITROGEN_IMX51	NITROGEN_IMX51		3167 |  | ||||||
| +nitrogen_imx53		MACH_NITROGEN_IMX53	NITROGEN_IMX53		3168 |  | ||||||
| +sunfire			MACH_SUNFIRE		SUNFIRE			3169 |  | ||||||
| +arowana			MACH_AROWANA		AROWANA			3170 |  | ||||||
| +tegra_daytona		MACH_TEGRA_DAYTONA	TEGRA_DAYTONA		3171 |  | ||||||
| +tegra_swordfish		MACH_TEGRA_SWORDFISH	TEGRA_SWORDFISH		3172 |  | ||||||
| +edison			MACH_EDISON		EDISON			3173 |  | ||||||
| +svp8500v1		MACH_SVP8500V1		SVP8500V1		3174 |  | ||||||
| +svp8500v2		MACH_SVP8500V2		SVP8500V2		3175 |  | ||||||
| +svp5500			MACH_SVP5500		SVP5500			3176 |  | ||||||
| +b5500			MACH_B5500		B5500			3177 |  | ||||||
| +s5500			MACH_S5500		S5500			3178 |  | ||||||
| +icon			MACH_ICON		ICON			3179 |  | ||||||
| +elephant		MACH_ELEPHANT		ELEPHANT		3180 |  | ||||||
| +msm8x60_charm_surf	MACH_MSM8X60_FUSION	MSM8X60_FUSION		3181 |  | ||||||
| +shooter			MACH_SHOOTER		SHOOTER			3182 |  | ||||||
| +spade_lte		MACH_SPADE_LTE		SPADE_LTE		3183 |  | ||||||
| +philhwani		MACH_PHILHWANI		PHILHWANI		3184 |  | ||||||
| +gsncomm			MACH_GSNCOMM		GSNCOMM			3185 |  | ||||||
| +strasbourg_a2		MACH_STRASBOURG_A2	STRASBOURG_A2		3186 |  | ||||||
| +mmm			MACH_MMM		MMM			3187 |  | ||||||
| +davinci_dm365_bv	MACH_DAVINCI_DM365_BV	DAVINCI_DM365_BV	3188 |  | ||||||
| +ag5evm			MACH_AG5EVM		AG5EVM			3189 |  | ||||||
| +sc575plc		MACH_SC575PLC		SC575PLC		3190 |  | ||||||
| +sc575hmi		MACH_SC575IPC		SC575IPC		3191 |  | ||||||
| +omap3_tdm3730		MACH_OMAP3_TDM3730	OMAP3_TDM3730		3192 |  | ||||||
| +rover_g7		MACH_G7			G7			3193 |  | ||||||
| +top9000_eval		MACH_TOP9000_EVAL	TOP9000_EVAL		3194 |  | ||||||
| +top9000_su		MACH_TOP9000_SU		TOP9000_SU		3195 |  | ||||||
| +utm300			MACH_UTM300		UTM300			3196 |  | ||||||
| +tsunagi			MACH_TSUNAGI		TSUNAGI			3197 |  | ||||||
| +ts75xx			MACH_TS75XX		TS75XX			3198 |  | ||||||
| +msm8x60_charm_ffa	MACH_MSM8X60_FUSN_FFA	MSM8X60_FUSN_FFA	3199 |  | ||||||
| +ts47xx			MACH_TS47XX		TS47XX			3200 |  | ||||||
| +da850_k5		MACH_DA850_K5		DA850_K5		3201 |  | ||||||
| +ax502			MACH_AX502		AX502			3202 |  | ||||||
| +igep0032		MACH_IGEP0032		IGEP0032		3203 |  | ||||||
| +antero			MACH_ANTERO		ANTERO			3204 |  | ||||||
| +synergy			MACH_SYNERGY		SYNERGY			3205 |  | ||||||
| +ics_if_voip		MACH_ICS_IF_VOIP	ICS_IF_VOIP		3206 |  | ||||||
| +wlf_cragg_6410		MACH_WLF_CRAGG_6410	WLF_CRAGG_6410		3207 |  | ||||||
| +punica			MACH_PUNICA		PUNICA			3208 |  | ||||||
| +trimslice		MACH_SBC_NT250		SBC_NT250		3209 |  | ||||||
| +mx27_wmultra		MACH_MX27_WMULTRA	MX27_WMULTRA		3210 |  | ||||||
| +mackerel		MACH_MACKEREL		MACKEREL		3211 |  | ||||||
| +pvd_imx27		MACH_MACH_PVD_IMX27	MACH_PVD_IMX27		3212 |  | ||||||
| +fa9x27			MACH_FA9X27		FA9X27			3213 |  | ||||||
| +ns2816tb		MACH_NS2816TB		NS2816TB		3214 |  | ||||||
| +ns2816_ntpad		MACH_NS2816_NTPAD	NS2816_NTPAD		3215 |  | ||||||
| +ns2816_ntnb		MACH_NS2816_NTNB	NS2816_NTNB		3216 |  | ||||||
| +kaen			MACH_KAEN		KAEN			3217 |  | ||||||
| +nv1000			MACH_NV1000		NV1000			3218 |  | ||||||
| +nuc950ts		MACH_NUC950TS		NUC950TS		3219 |  | ||||||
| +nokia_rm680		MACH_NOKIA_RM680	NOKIA_RM680		3220 |  | ||||||
| +ast2200			MACH_AST2200		AST2200			3221 |  | ||||||
| +lead			MACH_LEAD		LEAD			3222 |  | ||||||
| +unino1			MACH_UNINO1		UNINO1			3223 |  | ||||||
| +greeco			MACH_GREECO		GREECO			3224 |  | ||||||
| +verdi			MACH_VERDI		VERDI			3225 |  | ||||||
| +dm6446_adbox		MACH_DM6446_ADBOX	DM6446_ADBOX		3226 |  | ||||||
| +quad_salsa		MACH_QUAD_SALSA		QUAD_SALSA		3227 |  | ||||||
| +abb_gma_1_1		MACH_ABB_GMA_1_1	ABB_GMA_1_1		3228 |  | ||||||
| +svcid			MACH_SVCID		SVCID			3229 |  | ||||||
| +msm8960_sim		MACH_MSM8960_SIM	MSM8960_SIM		3230 |  | ||||||
| +msm8960_rumi3		MACH_MSM8960_RUMI3	MSM8960_RUMI3		3231 |  | ||||||
| +icon_g			MACH_ICON_G		ICON_G			3232 |  | ||||||
| +mb3			MACH_MB3		MB3			3233 |  | ||||||
| +gsia18s			MACH_GSIA18S		GSIA18S			3234 |  | ||||||
| +pivicc			MACH_PIVICC		PIVICC			3235 |  | ||||||
| +pcm048			MACH_PCM048		PCM048			3236 |  | ||||||
| +dds			MACH_DDS		DDS			3237 |  | ||||||
| +chalten_xa1		MACH_CHALTEN_XA1	CHALTEN_XA1		3238 |  | ||||||
| +ts48xx			MACH_TS48XX		TS48XX			3239 |  | ||||||
| +tonga2_tfttimer		MACH_TONGA2_TFTTIMER	TONGA2_TFTTIMER		3240 |  | ||||||
| +whistler		MACH_WHISTLER		WHISTLER		3241 |  | ||||||
| +asl_phoenix		MACH_ASL_PHOENIX	ASL_PHOENIX		3242 |  | ||||||
| +at91sam9263otlite	MACH_AT91SAM9263OTLITE	AT91SAM9263OTLITE	3243 |  | ||||||
| +ddplug			MACH_DDPLUG		DDPLUG			3244 |  | ||||||
| +d2plug			MACH_D2PLUG		D2PLUG			3245 |  | ||||||
| +kzm9d			MACH_KZM9D		KZM9D			3246 |  | ||||||
| +verdi_lte		MACH_VERDI_LTE		VERDI_LTE		3247 |  | ||||||
| +nanozoom		MACH_NANOZOOM		NANOZOOM		3248 |  | ||||||
| +dm3730_som_lv		MACH_DM3730_SOM_LV	DM3730_SOM_LV		3249 |  | ||||||
| +dm3730_torpedo		MACH_DM3730_TORPEDO	DM3730_TORPEDO		3250 |  | ||||||
| +anchovy			MACH_ANCHOVY		ANCHOVY			3251 |  | ||||||
| +linux			MACH_LINUX		LINUX			3252 |  | ||||||
| +re2rev20		MACH_RE2REV20		RE2REV20		3253 |  | ||||||
| +re2rev21		MACH_RE2REV21		RE2REV21		3254 |  | ||||||
| +cns21xx			MACH_CNS21XX		CNS21XX			3255 |  | ||||||
| +rider			MACH_RIDER		RIDER			3257 |  | ||||||
| +nsk330			MACH_NSK330		NSK330			3258 |  | ||||||
| +cns2133evb		MACH_CNS2133EVB		CNS2133EVB		3259 |  | ||||||
| +z3_816x_mod		MACH_Z3_816X_MOD	Z3_816X_MOD		3260 |  | ||||||
| +z3_814x_mod		MACH_Z3_814X_MOD	Z3_814X_MOD		3261 |  | ||||||
| +beect			MACH_BEECT		BEECT			3262 |  | ||||||
| +dma_thunderbug		MACH_DMA_THUNDERBUG	DMA_THUNDERBUG		3263 |  | ||||||
| +omn_at91sam9g20		MACH_OMN_AT91SAM9G20	OMN_AT91SAM9G20		3264 |  | ||||||
| +mx25_e2s_uc		MACH_MX25_E2S_UC	MX25_E2S_UC		3265 |  | ||||||
| +mione			MACH_MIONE		MIONE			3266 |  | ||||||
| +top9000_tcu		MACH_TOP9000_TCU	TOP9000_TCU		3267 |  | ||||||
| +top9000_bsl		MACH_TOP9000_BSL	TOP9000_BSL		3268 |  | ||||||
| +kingdom			MACH_KINGDOM		KINGDOM			3269 |  | ||||||
| +armadillo460		MACH_ARMADILLO460	ARMADILLO460		3270 |  | ||||||
| +lq2			MACH_LQ2		LQ2			3271 |  | ||||||
| +sweda_tms2		MACH_SWEDA_TMS2		SWEDA_TMS2		3272 |  | ||||||
| +mx53_loco		MACH_MX53_LOCO		MX53_LOCO		3273 |  | ||||||
| +acer_a7			MACH_MACH_ACER_A7	MACH_ACER_A7		3274 |  | ||||||
| +acer_a8			MACH_ACER_A8		ACER_A8			3275 |  | ||||||
| +acer_gauguin		MACH_ACER_GAUGUIN	ACER_GAUGUIN		3276 |  | ||||||
| +guppy			MACH_GUPPY		GUPPY			3277 |  | ||||||
| +mx61_ard		MACH_MX61_ARD		MX61_ARD		3278 |  | ||||||
| +tx53			MACH_TX53		TX53			3279 |  | ||||||
| +omapl138_case_a3	MACH_OMAPL138_CASE_A3	OMAPL138_CASE_A3	3280 |  | ||||||
| +uemd			MACH_UEMD		UEMD			3281 |  | ||||||
| +ccwmx51mut		MACH_CCWMX51MUT		CCWMX51MUT		3282 |  | ||||||
| +rockhopper		MACH_ROCKHOPPER		ROCKHOPPER		3283 |  | ||||||
| +nookcolor		MACH_NOOKCOLOR		NOOKCOLOR		3284 |  | ||||||
| +hkdkc100		MACH_HKDKC100		HKDKC100		3285 |  | ||||||
| +ts42xx			MACH_TS42XX		TS42XX			3286 |  | ||||||
| +aebl			MACH_AEBL		AEBL			3287 |  | ||||||
| +wario			MACH_WARIO		WARIO			3288 |  | ||||||
| +gfs_spm			MACH_GFS_SPM		GFS_SPM			3289 |  | ||||||
| +cm_t3730		MACH_CM_T3730		CM_T3730		3290 |  | ||||||
| +isc3			MACH_ISC3		ISC3			3291 |  | ||||||
| +rascal			MACH_RASCAL		RASCAL			3292 |  | ||||||
| +hrefv60			MACH_HREFV60		HREFV60			3293 |  | ||||||
| +tpt_2_0			MACH_TPT_2_0		TPT_2_0			3294 |  | ||||||
| +pyramid_td		MACH_PYRAMID_TD		PYRAMID_TD		3295 |  | ||||||
| +splendor		MACH_SPLENDOR		SPLENDOR		3296 |  | ||||||
| +guf_planet		MACH_GUF_PLANET		GUF_PLANET		3297 |  | ||||||
| +msm8x60_qt		MACH_MSM8X60_QT		MSM8X60_QT		3298 |  | ||||||
| +htc_hd_mini		MACH_HTC_HD_MINI	HTC_HD_MINI		3299 |  | ||||||
| +athene			MACH_ATHENE		ATHENE			3300 |  | ||||||
| +deep_r_ek_1		MACH_DEEP_R_EK_1	DEEP_R_EK_1		3301 |  | ||||||
| +vivow_ct		MACH_VIVOW_CT		VIVOW_CT		3302 |  | ||||||
| +nery_1000		MACH_NERY_1000		NERY_1000		3303 |  | ||||||
| +rfl109145_ssrv		MACH_RFL109145_SSRV	RFL109145_SSRV		3304 |  | ||||||
| +nmh			MACH_NMH		NMH			3305 |  | ||||||
| +wn802t			MACH_WN802T		WN802T			3306 |  | ||||||
| +dragonet		MACH_DRAGONET		DRAGONET		3307 |  | ||||||
| +geneva_b		MACH_GENEVA_B		GENEVA_B		3308 |  | ||||||
| +at91sam9263desk16l	MACH_AT91SAM9263DESK16L	AT91SAM9263DESK16L	3309 |  | ||||||
| +bcmhana_sv		MACH_BCMHANA_SV		BCMHANA_SV		3310 |  | ||||||
| +bcmhana_tablet		MACH_BCMHANA_TABLET	BCMHANA_TABLET		3311 |  | ||||||
| +koi			MACH_KOI		KOI			3312 |  | ||||||
| +ts4800			MACH_TS4800		TS4800			3313 |  | ||||||
| +tqma9263		MACH_TQMA9263		TQMA9263		3314 |  | ||||||
| +holiday			MACH_HOLIDAY		HOLIDAY			3315 |  | ||||||
| +dma_6410		MACH_DMA6410		DMA6410			3316 |  | ||||||
| +pcats_overlay		MACH_PCATS_OVERLAY	PCATS_OVERLAY		3317 |  | ||||||
| +hwgw6410		MACH_HWGW6410		HWGW6410		3318 |  | ||||||
| +shenzhou		MACH_SHENZHOU		SHENZHOU		3319 |  | ||||||
| +cwme9210		MACH_CWME9210		CWME9210		3320 |  | ||||||
| +cwme9210js		MACH_CWME9210JS		CWME9210JS		3321 |  | ||||||
| +pgs_v1			MACH_PGS_SITARA		PGS_SITARA		3322 |  | ||||||
| +colibri_tegra2		MACH_COLIBRI_TEGRA2	COLIBRI_TEGRA2		3323 |  | ||||||
| +w21			MACH_W21		W21			3324 |  | ||||||
| +polysat1		MACH_POLYSAT1		POLYSAT1		3325 |  | ||||||
| +dataway			MACH_DATAWAY		DATAWAY			3326 |  | ||||||
| +cobral138		MACH_COBRAL138		COBRAL138		3327 |  | ||||||
| +roverpcs8		MACH_ROVERPCS8		ROVERPCS8		3328 |  | ||||||
| +marvelc			MACH_MARVELC		MARVELC			3329 |  | ||||||
| +navefihid		MACH_NAVEFIHID		NAVEFIHID		3330 |  | ||||||
| +dm365_cv100		MACH_DM365_CV100	DM365_CV100		3331 |  | ||||||
| +able			MACH_ABLE		ABLE			3332 |  | ||||||
| +legacy			MACH_LEGACY		LEGACY			3333 |  | ||||||
| +icong			MACH_ICONG		ICONG			3334 |  | ||||||
| +rover_g8		MACH_ROVER_G8		ROVER_G8		3335 |  | ||||||
| +t5388p			MACH_T5388P		T5388P			3336 |  | ||||||
| @@ -1,123 +0,0 @@ | |||||||
| From 24b584240a0006ea7436cd35f5e8983eb76f1e6f Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Theodore Ts'o <tytso@mit.edu> |  | ||||||
| Date: Mon, 7 Dec 2009 14:08:51 -0500 |  | ||||||
| Subject: [PATCH] ext4: Use ext4 file system driver for ext2/ext3 file system mounts |  | ||||||
|  |  | ||||||
| Add a new config option, CONFIG_EXT4_USE_FOR_EXT23 which if enabled, |  | ||||||
| will cause ext4 to be used for either ext2 or ext3 file system mounts |  | ||||||
| when ext2 or ext3 is not enabled in the configuration. |  | ||||||
|  |  | ||||||
| This allows minimalist kernel fanatics to drop to file system drivers |  | ||||||
| from their compiled kernel with out losing functionality. |  | ||||||
|  |  | ||||||
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |  | ||||||
| --- |  | ||||||
|  fs/ext4/Kconfig |   10 +++++++++ |  | ||||||
|  fs/ext4/super.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  2 files changed, 68 insertions(+), 0 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/ext4/Kconfig |  | ||||||
| +++ b/fs/ext4/Kconfig |  | ||||||
| @@ -26,6 +26,16 @@ config EXT4_FS |  | ||||||
|   |  | ||||||
|  	  If unsure, say N. |  | ||||||
|   |  | ||||||
| +config EXT4_USE_FOR_EXT23 |  | ||||||
| +	bool "Use ext4 for ext2/ext3 file systems" |  | ||||||
| +	depends on !EXT3_FS || !EXT2_FS |  | ||||||
| +	default y |  | ||||||
| +	help |  | ||||||
| +	  Allow the ext4 file system driver code to be used for ext2 or |  | ||||||
| +	  ext3 file system mounts.  This allows users to reduce their |  | ||||||
| +	  compiled kernel size by using one file system driver for |  | ||||||
| +	  ext2, ext3, and ext4 file systems. |  | ||||||
| + |  | ||||||
|  config EXT4_FS_XATTR |  | ||||||
|  	bool "Ext4 extended attributes" |  | ||||||
|  	depends on EXT4_FS |  | ||||||
| --- a/fs/ext4/super.c |  | ||||||
| +++ b/fs/ext4/super.c |  | ||||||
| @@ -3994,6 +3994,58 @@ static int ext4_get_sb(struct file_syste |  | ||||||
|  	return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +#if !defined(CONTIG_EXT2_FS) && defined(CONFIG_EXT4_USE_FOR_EXT23) |  | ||||||
| +static struct file_system_type ext2_fs_type = { |  | ||||||
| +	.owner		= THIS_MODULE, |  | ||||||
| +	.name		= "ext2", |  | ||||||
| +	.get_sb		= ext4_get_sb, |  | ||||||
| +	.kill_sb	= kill_block_super, |  | ||||||
| +	.fs_flags	= FS_REQUIRES_DEV, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static inline void register_as_ext2(void) |  | ||||||
| +{ |  | ||||||
| +	int err = register_filesystem(&ext2_fs_type); |  | ||||||
| +	if (err) |  | ||||||
| +		printk(KERN_WARNING |  | ||||||
| +		       "EXT4-fs: Unable to register as ext2 (%d)\n", err); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void unregister_as_ext2(void) |  | ||||||
| +{ |  | ||||||
| +	unregister_filesystem(&ext2_fs_type); |  | ||||||
| +} |  | ||||||
| +#else |  | ||||||
| +static inline void register_as_ext2(void) { } |  | ||||||
| +static inline void unregister_as_ext2(void) { } |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#if !defined(CONTIG_EXT3_FS) && defined(CONFIG_EXT4_USE_FOR_EXT23) |  | ||||||
| +static struct file_system_type ext3_fs_type = { |  | ||||||
| +	.owner		= THIS_MODULE, |  | ||||||
| +	.name		= "ext3", |  | ||||||
| +	.get_sb		= ext4_get_sb, |  | ||||||
| +	.kill_sb	= kill_block_super, |  | ||||||
| +	.fs_flags	= FS_REQUIRES_DEV, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static inline void register_as_ext3(void) |  | ||||||
| +{ |  | ||||||
| +	int err = register_filesystem(&ext3_fs_type); |  | ||||||
| +	if (err) |  | ||||||
| +		printk(KERN_WARNING |  | ||||||
| +		       "EXT4-fs: Unable to register as ext3 (%d)\n", err); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void unregister_as_ext3(void) |  | ||||||
| +{ |  | ||||||
| +	unregister_filesystem(&ext3_fs_type); |  | ||||||
| +} |  | ||||||
| +#else |  | ||||||
| +static inline void register_as_ext3(void) { } |  | ||||||
| +static inline void unregister_as_ext3(void) { } |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  static struct file_system_type ext4_fs_type = { |  | ||||||
|  	.owner		= THIS_MODULE, |  | ||||||
|  	.name		= "ext4", |  | ||||||
| @@ -4024,11 +4076,15 @@ static int __init init_ext4_fs(void) |  | ||||||
|  	err = init_inodecache(); |  | ||||||
|  	if (err) |  | ||||||
|  		goto out1; |  | ||||||
| +	register_as_ext2(); |  | ||||||
| +	register_as_ext3(); |  | ||||||
|  	err = register_filesystem(&ext4_fs_type); |  | ||||||
|  	if (err) |  | ||||||
|  		goto out; |  | ||||||
|  	return 0; |  | ||||||
|  out: |  | ||||||
| +	unregister_as_ext2(); |  | ||||||
| +	unregister_as_ext3(); |  | ||||||
|  	destroy_inodecache(); |  | ||||||
|  out1: |  | ||||||
|  	exit_ext4_xattr(); |  | ||||||
| @@ -4044,6 +4100,8 @@ out4: |  | ||||||
|   |  | ||||||
|  static void __exit exit_ext4_fs(void) |  | ||||||
|  { |  | ||||||
| +	unregister_as_ext2(); |  | ||||||
| +	unregister_as_ext3(); |  | ||||||
|  	unregister_filesystem(&ext4_fs_type); |  | ||||||
|  	destroy_inodecache(); |  | ||||||
|  	exit_ext4_xattr(); |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| From a214238d3bb03723f820b0a398928d8e1637c987 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Theodore Ts'o <tytso@mit.edu> |  | ||||||
| Date: Wed, 9 Dec 2009 21:09:58 -0500 |  | ||||||
| Subject: [PATCH] ext4: Do not override ext2 or ext3 if built they are built as modules |  | ||||||
|  |  | ||||||
| The CONFIG_EXT4_USE_FOR_EXT23 option must not try to take over the |  | ||||||
| ext2 or ext3 file systems if the those file system drivers are |  | ||||||
| configured to be built as mdoules. |  | ||||||
|  |  | ||||||
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |  | ||||||
| --- |  | ||||||
|  fs/ext4/Kconfig |    2 +- |  | ||||||
|  fs/ext4/super.c |    4 ++-- |  | ||||||
|  2 files changed, 3 insertions(+), 3 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/ext4/Kconfig |  | ||||||
| +++ b/fs/ext4/Kconfig |  | ||||||
| @@ -28,7 +28,7 @@ config EXT4_FS |  | ||||||
|   |  | ||||||
|  config EXT4_USE_FOR_EXT23 |  | ||||||
|  	bool "Use ext4 for ext2/ext3 file systems" |  | ||||||
| -	depends on !EXT3_FS || !EXT2_FS |  | ||||||
| +	depends on EXT3_FS=n || EXT2_FS=n |  | ||||||
|  	default y |  | ||||||
|  	help |  | ||||||
|  	  Allow the ext4 file system driver code to be used for ext2 or |  | ||||||
| --- a/fs/ext4/super.c |  | ||||||
| +++ b/fs/ext4/super.c |  | ||||||
| @@ -3994,7 +3994,7 @@ static int ext4_get_sb(struct file_syste |  | ||||||
|  	return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#if !defined(CONTIG_EXT2_FS) && defined(CONFIG_EXT4_USE_FOR_EXT23) |  | ||||||
| +#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |  | ||||||
|  static struct file_system_type ext2_fs_type = { |  | ||||||
|  	.owner		= THIS_MODULE, |  | ||||||
|  	.name		= "ext2", |  | ||||||
| @@ -4020,7 +4020,7 @@ static inline void register_as_ext2(void |  | ||||||
|  static inline void unregister_as_ext2(void) { } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -#if !defined(CONTIG_EXT3_FS) && defined(CONFIG_EXT4_USE_FOR_EXT23) |  | ||||||
| +#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) |  | ||||||
|  static struct file_system_type ext3_fs_type = { |  | ||||||
|  	.owner		= THIS_MODULE, |  | ||||||
|  	.name		= "ext3", |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| From 51b7e3c9fbe7d22d4e355101e9a73b44fc5c9feb Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Theodore Ts'o <tytso@mit.edu> |  | ||||||
| Date: Mon, 21 Dec 2009 10:56:09 -0500 |  | ||||||
| Subject: [PATCH] ext4: add module aliases for ext2 and ext3 |  | ||||||
|  |  | ||||||
| Add module aliases for ext2 and ext3 when CONFIG_EXT4_USE_FOR_EXT23 is |  | ||||||
| set.  This makes the existing user-space stuff like mkinitrd working |  | ||||||
| as is. |  | ||||||
|  |  | ||||||
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |  | ||||||
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |  | ||||||
| --- |  | ||||||
|  fs/ext4/super.c |    2 ++ |  | ||||||
|  1 files changed, 2 insertions(+), 0 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/fs/ext4/super.c |  | ||||||
| +++ b/fs/ext4/super.c |  | ||||||
| @@ -4015,6 +4015,7 @@ static inline void unregister_as_ext2(vo |  | ||||||
|  { |  | ||||||
|  	unregister_filesystem(&ext2_fs_type); |  | ||||||
|  } |  | ||||||
| +MODULE_ALIAS("ext2"); |  | ||||||
|  #else |  | ||||||
|  static inline void register_as_ext2(void) { } |  | ||||||
|  static inline void unregister_as_ext2(void) { } |  | ||||||
| @@ -4041,6 +4042,7 @@ static inline void unregister_as_ext3(vo |  | ||||||
|  { |  | ||||||
|  	unregister_filesystem(&ext3_fs_type); |  | ||||||
|  } |  | ||||||
| +MODULE_ALIAS("ext3"); |  | ||||||
|  #else |  | ||||||
|  static inline void register_as_ext3(void) { } |  | ||||||
|  static inline void unregister_as_ext3(void) { } |  | ||||||
| @@ -1,309 +0,0 @@ | |||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/decompress/unlzo.h |  | ||||||
| @@ -0,0 +1,10 @@ |  | ||||||
| +#ifndef DECOMPRESS_UNLZO_H |  | ||||||
| +#define DECOMPRESS_UNLZO_H |  | ||||||
| + |  | ||||||
| +int unlzo(unsigned char *inbuf, int len, |  | ||||||
| +	int(*fill)(void*, unsigned int), |  | ||||||
| +	int(*flush)(void*, unsigned int), |  | ||||||
| +	unsigned char *output, |  | ||||||
| +	int *pos, |  | ||||||
| +	void(*error)(char *x)); |  | ||||||
| +#endif |  | ||||||
| --- a/init/Kconfig |  | ||||||
| +++ b/init/Kconfig |  | ||||||
| @@ -115,10 +115,13 @@ config HAVE_KERNEL_BZIP2 |  | ||||||
|  config HAVE_KERNEL_LZMA |  | ||||||
|  	bool |  | ||||||
|   |  | ||||||
| +config HAVE_KERNEL_LZO |  | ||||||
| +	bool |  | ||||||
| + |  | ||||||
|  choice |  | ||||||
|  	prompt "Kernel compression mode" |  | ||||||
|  	default KERNEL_GZIP |  | ||||||
| -	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA |  | ||||||
| +	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_LZO |  | ||||||
|  	help |  | ||||||
|  	  The linux kernel is a kind of self-extracting executable. |  | ||||||
|  	  Several compression algorithms are available, which differ |  | ||||||
| @@ -141,9 +144,8 @@ config KERNEL_GZIP |  | ||||||
|  	bool "Gzip" |  | ||||||
|  	depends on HAVE_KERNEL_GZIP |  | ||||||
|  	help |  | ||||||
| -	  The old and tried gzip compression. Its compression ratio is |  | ||||||
| -	  the poorest among the 3 choices; however its speed (both |  | ||||||
| -	  compression and decompression) is the fastest. |  | ||||||
| +	  The old and tried gzip compression. It provides a good balance |  | ||||||
| +	  between compression ratio and decompression speed. |  | ||||||
|   |  | ||||||
|  config KERNEL_BZIP2 |  | ||||||
|  	bool "Bzip2" |  | ||||||
| @@ -164,6 +166,14 @@ config KERNEL_LZMA |  | ||||||
|  	  two. Compression is slowest.	The kernel size is about 33% |  | ||||||
|  	  smaller with LZMA in comparison to gzip. |  | ||||||
|   |  | ||||||
| +config KERNEL_LZO |  | ||||||
| +	bool "LZO" |  | ||||||
| +	depends on HAVE_KERNEL_LZO |  | ||||||
| +	help |  | ||||||
| +	  Its compression ratio is the poorest among the 4. The kernel |  | ||||||
| +	  size is about about 10% bigger than gzip; however its speed |  | ||||||
| +	  (both compression and decompression) is the fastest. |  | ||||||
| + |  | ||||||
|  endchoice |  | ||||||
|   |  | ||||||
|  config SWAP |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/lib/decompress_unlzo.c |  | ||||||
| @@ -0,0 +1,208 @@ |  | ||||||
| +/* |  | ||||||
| + * LZO decompressor for the Linux kernel. Code borrowed from the lzo |  | ||||||
| + * implementation by Markus Franz Xaver Johannes Oberhumer. |  | ||||||
| + * |  | ||||||
| + * Linux kernel adaptation: |  | ||||||
| + * Copyright (C) 2009 |  | ||||||
| + * Albin Tonnerre, Free Electrons <albin.tonnerre@free-electrons.com> |  | ||||||
| + * |  | ||||||
| + * Original code: |  | ||||||
| + * Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer |  | ||||||
| + * All Rights Reserved. |  | ||||||
| + * |  | ||||||
| + * lzop and the LZO library are free software; you can redistribute them |  | ||||||
| + * and/or modify them under the terms of the GNU General Public License as |  | ||||||
| + * published by the Free Software Foundation; either version 2 of |  | ||||||
| + * the License, or (at your option) any later version. |  | ||||||
| + * |  | ||||||
| + * This program is distributed in the hope that it will be useful, |  | ||||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| + * GNU General Public License for more details. |  | ||||||
| + * |  | ||||||
| + * You should have received a copy of the GNU General Public License |  | ||||||
| + * along with this program; see the file COPYING. |  | ||||||
| + * If not, write to the Free Software Foundation, Inc., |  | ||||||
| + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |  | ||||||
| + * |  | ||||||
| + * Markus F.X.J. Oberhumer |  | ||||||
| + * <markus@oberhumer.com> |  | ||||||
| + * http://www.oberhumer.com/opensource/lzop/ |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#ifdef STATIC |  | ||||||
| +#include "lzo/lzo1x_decompress.c" |  | ||||||
| +#else |  | ||||||
| +#include <linux/slab.h> |  | ||||||
| +#include <linux/decompress/unlzo.h> |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#include <linux/types.h> |  | ||||||
| +#include <linux/lzo.h> |  | ||||||
| +#include <linux/decompress/mm.h> |  | ||||||
| + |  | ||||||
| +#include <linux/compiler.h> |  | ||||||
| +#include <asm/unaligned.h> |  | ||||||
| + |  | ||||||
| +static const unsigned char lzop_magic[] = |  | ||||||
| +	{ 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a }; |  | ||||||
| + |  | ||||||
| +#define LZO_BLOCK_SIZE        (256*1024l) |  | ||||||
| +#define HEADER_HAS_FILTER      0x00000800L |  | ||||||
| + |  | ||||||
| +STATIC inline int INIT parse_header(u8 *input, u8 *skip) |  | ||||||
| +{ |  | ||||||
| +	int l; |  | ||||||
| +	u8 *parse = input; |  | ||||||
| +	u8 level = 0; |  | ||||||
| +	u16 version; |  | ||||||
| + |  | ||||||
| +	/* read magic: 9 first bits */ |  | ||||||
| +	for (l = 0; l < 9; l++) { |  | ||||||
| +		if (*parse++ != lzop_magic[l]) |  | ||||||
| +			return 0; |  | ||||||
| +	} |  | ||||||
| +	/* get version (2bytes), skip library version (2), |  | ||||||
| +	 * 'need to be extracted' version (2) and |  | ||||||
| +	 * method (1) */ |  | ||||||
| +	version = get_unaligned_be16(parse); |  | ||||||
| +	parse += 7; |  | ||||||
| +	if (version >= 0x0940) |  | ||||||
| +		level = *parse++; |  | ||||||
| +	if (get_unaligned_be32(parse) & HEADER_HAS_FILTER) |  | ||||||
| +		parse += 8; /* flags + filter info */ |  | ||||||
| +	else |  | ||||||
| +		parse += 4; /* flags */ |  | ||||||
| + |  | ||||||
| +	/* skip mode and mtime_low */ |  | ||||||
| +	parse += 8; |  | ||||||
| +	if (version >= 0x0940) |  | ||||||
| +		parse += 4;	/* skip mtime_high */ |  | ||||||
| + |  | ||||||
| +	l = *parse++; |  | ||||||
| +	/* don't care about the file name, and skip checksum */ |  | ||||||
| +	parse += l + 4; |  | ||||||
| + |  | ||||||
| +	*skip = parse - input; |  | ||||||
| +	return 1; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +STATIC inline int INIT unlzo(u8 *input, int in_len, |  | ||||||
| +				int (*fill) (void *, unsigned int), |  | ||||||
| +				int (*flush) (void *, unsigned int), |  | ||||||
| +				u8 *output, int *posp, |  | ||||||
| +				void (*error_fn) (char *x)) |  | ||||||
| +{ |  | ||||||
| +	u8 skip = 0, r = 0; |  | ||||||
| +	u32 src_len, dst_len; |  | ||||||
| +	size_t tmp; |  | ||||||
| +	u8 *in_buf, *in_buf_save, *out_buf; |  | ||||||
| +	int obytes_processed = 0; |  | ||||||
| + |  | ||||||
| +	set_error_fn(error_fn); |  | ||||||
| + |  | ||||||
| +	if (output) |  | ||||||
| +		out_buf = output; |  | ||||||
| +	else if (!flush) { |  | ||||||
| +		error("NULL output pointer and no flush function provided"); |  | ||||||
| +		goto exit; |  | ||||||
| +	} else { |  | ||||||
| +		out_buf = malloc(LZO_BLOCK_SIZE); |  | ||||||
| +		if (!out_buf) { |  | ||||||
| +			error("Could not allocate output buffer"); |  | ||||||
| +			goto exit; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (input && fill) { |  | ||||||
| +		error("Both input pointer and fill function provided, don't know what to do"); |  | ||||||
| +		goto exit_1; |  | ||||||
| +	} else if (input) |  | ||||||
| +		in_buf = input; |  | ||||||
| +	else if (!fill || !posp) { |  | ||||||
| +		error("NULL input pointer and missing position pointer or fill function"); |  | ||||||
| +		goto exit_1; |  | ||||||
| +	} else { |  | ||||||
| +		in_buf = malloc(lzo1x_worst_compress(LZO_BLOCK_SIZE)); |  | ||||||
| +		if (!in_buf) { |  | ||||||
| +			error("Could not allocate input buffer"); |  | ||||||
| +			goto exit_1; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| +	in_buf_save = in_buf; |  | ||||||
| + |  | ||||||
| +	if (posp) |  | ||||||
| +		*posp = 0; |  | ||||||
| + |  | ||||||
| +	if (fill) |  | ||||||
| +		fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE)); |  | ||||||
| + |  | ||||||
| +	if (!parse_header(input, &skip)) { |  | ||||||
| +		error("invalid header"); |  | ||||||
| +		goto exit_2; |  | ||||||
| +	} |  | ||||||
| +	in_buf += skip; |  | ||||||
| + |  | ||||||
| +	if (posp) |  | ||||||
| +		*posp = skip; |  | ||||||
| + |  | ||||||
| +	for (;;) { |  | ||||||
| +		/* read uncompressed block size */ |  | ||||||
| +		dst_len = get_unaligned_be32(in_buf); |  | ||||||
| +		in_buf += 4; |  | ||||||
| + |  | ||||||
| +		/* exit if last block */ |  | ||||||
| +		if (dst_len == 0) { |  | ||||||
| +			if (posp) |  | ||||||
| +				*posp += 4; |  | ||||||
| +			break; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		if (dst_len > LZO_BLOCK_SIZE) { |  | ||||||
| +			error("dest len longer than block size"); |  | ||||||
| +			goto exit_2; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		/* read compressed block size, and skip block checksum info */ |  | ||||||
| +		src_len = get_unaligned_be32(in_buf); |  | ||||||
| +		in_buf += 8; |  | ||||||
| + |  | ||||||
| +		if (src_len <= 0 || src_len > dst_len) { |  | ||||||
| +			error("file corrupted"); |  | ||||||
| +			goto exit_2; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		/* decompress */ |  | ||||||
| +		tmp = dst_len; |  | ||||||
| +		r = lzo1x_decompress_safe((u8 *) in_buf, src_len, out_buf, &tmp); |  | ||||||
| + |  | ||||||
| +		if (r != LZO_E_OK || dst_len != tmp) { |  | ||||||
| +			error("Compressed data violation"); |  | ||||||
| +			goto exit_2; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		obytes_processed += dst_len; |  | ||||||
| +		if (flush) |  | ||||||
| +			flush(out_buf, dst_len); |  | ||||||
| +		if (output) |  | ||||||
| +			out_buf += dst_len; |  | ||||||
| +		if (posp) |  | ||||||
| +			*posp += src_len + 12; |  | ||||||
| +		if (fill) { |  | ||||||
| +			in_buf = in_buf_save; |  | ||||||
| +			fill(in_buf, lzo1x_worst_compress(LZO_BLOCK_SIZE)); |  | ||||||
| +		} else |  | ||||||
| +			in_buf += src_len; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +exit_2: |  | ||||||
| +	if (!input) |  | ||||||
| +		free(in_buf); |  | ||||||
| +exit_1: |  | ||||||
| +	if (!output) |  | ||||||
| +		free(out_buf); |  | ||||||
| +exit: |  | ||||||
| +	return obytes_processed; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +#define decompress unlzo |  | ||||||
| --- a/lib/lzo/lzo1x_decompress.c |  | ||||||
| +++ b/lib/lzo/lzo1x_decompress.c |  | ||||||
| @@ -11,11 +11,13 @@ |  | ||||||
|   *  Richard Purdie <rpurdie@openedhand.com> |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
| +#ifndef STATIC |  | ||||||
|  #include <linux/module.h> |  | ||||||
|  #include <linux/kernel.h> |  | ||||||
| -#include <linux/lzo.h> |  | ||||||
| -#include <asm/byteorder.h> |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  #include <asm/unaligned.h> |  | ||||||
| +#include <linux/lzo.h> |  | ||||||
|  #include "lzodefs.h" |  | ||||||
|   |  | ||||||
|  #define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x)) |  | ||||||
| @@ -244,9 +246,10 @@ lookbehind_overrun: |  | ||||||
|  	*out_len = op - out; |  | ||||||
|  	return LZO_E_LOOKBEHIND_OVERRUN; |  | ||||||
|  } |  | ||||||
| - |  | ||||||
| +#ifndef STATIC |  | ||||||
|  EXPORT_SYMBOL_GPL(lzo1x_decompress_safe); |  | ||||||
|   |  | ||||||
|  MODULE_LICENSE("GPL"); |  | ||||||
|  MODULE_DESCRIPTION("LZO1X Decompressor"); |  | ||||||
|   |  | ||||||
| +#endif |  | ||||||
| --- a/scripts/Makefile.lib |  | ||||||
| +++ b/scripts/Makefile.lib |  | ||||||
| @@ -230,3 +230,8 @@ quiet_cmd_lzma = LZMA    $@ |  | ||||||
|  cmd_lzma = (cat $(filter-out FORCE,$^) | \ |  | ||||||
|  	lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ |  | ||||||
|  	(rm -f $@ ; false) |  | ||||||
| + |  | ||||||
| +quiet_cmd_lzo = LZO    $@ |  | ||||||
| +cmd_lzo = (cat $(filter-out FORCE,$^) | \ |  | ||||||
| +	lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ |  | ||||||
| +	(rm -f $@ ; false) |  | ||||||
| @@ -1,283 +0,0 @@ | |||||||
| --- a/arch/arm/Kconfig |  | ||||||
| +++ b/arch/arm/Kconfig |  | ||||||
| @@ -18,6 +18,8 @@ config ARM |  | ||||||
|  	select HAVE_KRETPROBES if (HAVE_KPROBES) |  | ||||||
|  	select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) |  | ||||||
|  	select HAVE_GENERIC_DMA_COHERENT |  | ||||||
| +	select HAVE_KERNEL_GZIP |  | ||||||
| +	select HAVE_KERNEL_LZO |  | ||||||
|  	help |  | ||||||
|  	  The ARM series is a line of low-power-consumption RISC chip designs |  | ||||||
|  	  licensed by ARM Ltd and targeted at embedded applications and |  | ||||||
| --- a/arch/arm/boot/compressed/Makefile |  | ||||||
| +++ b/arch/arm/boot/compressed/Makefile |  | ||||||
| @@ -63,8 +63,12 @@ endif |  | ||||||
|   |  | ||||||
|  SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ |  | ||||||
|   |  | ||||||
| -targets       := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ |  | ||||||
| -		 head.o misc.o $(OBJS) |  | ||||||
| +suffix_$(CONFIG_KERNEL_GZIP) = gzip |  | ||||||
| +suffix_$(CONFIG_KERNEL_LZO)  = lzo |  | ||||||
| + |  | ||||||
| +targets       := vmlinux vmlinux.lds \ |  | ||||||
| +		 piggy.$(suffix_y) piggy.$(suffix_y).o \ |  | ||||||
| +		 font.o font.c head.o misc.o $(OBJS) |  | ||||||
|   |  | ||||||
|  ifeq ($(CONFIG_FUNCTION_TRACER),y) |  | ||||||
|  ORIG_CFLAGS := $(KBUILD_CFLAGS) |  | ||||||
| @@ -87,22 +91,31 @@ endif |  | ||||||
|  ifneq ($(PARAMS_PHYS),) |  | ||||||
|  LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS) |  | ||||||
|  endif |  | ||||||
| -LDFLAGS_vmlinux += -p --no-undefined -X \ |  | ||||||
| -	$(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T |  | ||||||
| +# ? |  | ||||||
| +LDFLAGS_vmlinux += -p |  | ||||||
| +# Report unresolved symbol references |  | ||||||
| +LDFLAGS_vmlinux += --no-undefined |  | ||||||
| +# Delete all temporary local symbols |  | ||||||
| +LDFLAGS_vmlinux += -X |  | ||||||
| +# Next argument is a linker script |  | ||||||
| +LDFLAGS_vmlinux += -T |  | ||||||
| + |  | ||||||
| +# For __aeabi_uidivmod |  | ||||||
| +lib1funcs = $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.o |  | ||||||
|   |  | ||||||
|  # Don't allow any static data in misc.o, which |  | ||||||
|  # would otherwise mess up our GOT table |  | ||||||
|  CFLAGS_misc.o := -Dstatic= |  | ||||||
|   |  | ||||||
| -$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ |  | ||||||
| -	 	$(addprefix $(obj)/, $(OBJS)) FORCE |  | ||||||
| +$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ |  | ||||||
| +	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE |  | ||||||
|  	$(call if_changed,ld) |  | ||||||
|  	@: |  | ||||||
|   |  | ||||||
| -$(obj)/piggy.gz: $(obj)/../Image FORCE |  | ||||||
| -	$(call if_changed,gzip) |  | ||||||
| +$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE |  | ||||||
| +	$(call if_changed,$(suffix_y)) |  | ||||||
|   |  | ||||||
| -$(obj)/piggy.o:  $(obj)/piggy.gz FORCE |  | ||||||
| +$(obj)/piggy.$(suffix_y).o:  $(obj)/piggy.$(suffix_y) FORCE |  | ||||||
|   |  | ||||||
|  CFLAGS_font.o := -Dstatic= |  | ||||||
|   |  | ||||||
| --- a/arch/arm/boot/compressed/misc.c |  | ||||||
| +++ b/arch/arm/boot/compressed/misc.c |  | ||||||
| @@ -18,10 +18,15 @@ |  | ||||||
|   |  | ||||||
|  unsigned int __machine_arch_type; |  | ||||||
|   |  | ||||||
| +#define _LINUX_STRING_H_ |  | ||||||
| + |  | ||||||
|  #include <linux/compiler.h>	/* for inline */ |  | ||||||
|  #include <linux/types.h>	/* for size_t */ |  | ||||||
|  #include <linux/stddef.h>	/* for NULL */ |  | ||||||
|  #include <asm/string.h> |  | ||||||
| +#include <linux/linkage.h> |  | ||||||
| + |  | ||||||
| +#include <asm/unaligned.h> |  | ||||||
|   |  | ||||||
|  #ifdef STANDALONE_DEBUG |  | ||||||
|  #define putstr printf |  | ||||||
| @@ -188,34 +193,8 @@ static inline __ptr_t memcpy(__ptr_t __d |  | ||||||
|  /* |  | ||||||
|   * gzip delarations |  | ||||||
|   */ |  | ||||||
| -#define OF(args)  args |  | ||||||
|  #define STATIC static |  | ||||||
|   |  | ||||||
| -typedef unsigned char  uch; |  | ||||||
| -typedef unsigned short ush; |  | ||||||
| -typedef unsigned long  ulg; |  | ||||||
| - |  | ||||||
| -#define WSIZE 0x8000		/* Window size must be at least 32k, */ |  | ||||||
| -				/* and a power of two */ |  | ||||||
| - |  | ||||||
| -static uch *inbuf;		/* input buffer */ |  | ||||||
| -static uch window[WSIZE];	/* Sliding window buffer */ |  | ||||||
| - |  | ||||||
| -static unsigned insize;		/* valid bytes in inbuf */ |  | ||||||
| -static unsigned inptr;		/* index of next byte to be processed in inbuf */ |  | ||||||
| -static unsigned outcnt;		/* bytes in output buffer */ |  | ||||||
| - |  | ||||||
| -/* gzip flag byte */ |  | ||||||
| -#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */ |  | ||||||
| -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ |  | ||||||
| -#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */ |  | ||||||
| -#define ORIG_NAME    0x08 /* bit 3 set: original file name present */ |  | ||||||
| -#define COMMENT      0x10 /* bit 4 set: file comment present */ |  | ||||||
| -#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */ |  | ||||||
| -#define RESERVED     0xC0 /* bit 6,7:   reserved */ |  | ||||||
| - |  | ||||||
| -#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf()) |  | ||||||
| - |  | ||||||
|  /* Diagnostic functions */ |  | ||||||
|  #ifdef DEBUG |  | ||||||
|  #  define Assert(cond,msg) {if(!(cond)) error(msg);} |  | ||||||
| @@ -233,24 +212,20 @@ static unsigned outcnt;		/* bytes in out |  | ||||||
|  #  define Tracecv(c,x) |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -static int  fill_inbuf(void); |  | ||||||
| -static void flush_window(void); |  | ||||||
|  static void error(char *m); |  | ||||||
|   |  | ||||||
|  extern char input_data[]; |  | ||||||
|  extern char input_data_end[]; |  | ||||||
|   |  | ||||||
| -static uch *output_data; |  | ||||||
| -static ulg output_ptr; |  | ||||||
| -static ulg bytes_out; |  | ||||||
| +static unsigned char *output_data; |  | ||||||
| +static unsigned long output_ptr; |  | ||||||
|   |  | ||||||
|  static void error(char *m); |  | ||||||
|   |  | ||||||
|  static void putstr(const char *); |  | ||||||
|   |  | ||||||
| -extern int end; |  | ||||||
| -static ulg free_mem_ptr; |  | ||||||
| -static ulg free_mem_end_ptr; |  | ||||||
| +static unsigned long free_mem_ptr; |  | ||||||
| +static unsigned long free_mem_end_ptr; |  | ||||||
|   |  | ||||||
|  #ifdef STANDALONE_DEBUG |  | ||||||
|  #define NO_INFLATE_MALLOC |  | ||||||
| @@ -258,46 +233,13 @@ static ulg free_mem_end_ptr; |  | ||||||
|   |  | ||||||
|  #define ARCH_HAS_DECOMP_WDOG |  | ||||||
|   |  | ||||||
| -#include "../../../../lib/inflate.c" |  | ||||||
| - |  | ||||||
| -/* =========================================================================== |  | ||||||
| - * Fill the input buffer. This is called only when the buffer is empty |  | ||||||
| - * and at least one byte is really needed. |  | ||||||
| - */ |  | ||||||
| -int fill_inbuf(void) |  | ||||||
| -{ |  | ||||||
| -	if (insize != 0) |  | ||||||
| -		error("ran out of input data"); |  | ||||||
| - |  | ||||||
| -	inbuf = input_data; |  | ||||||
| -	insize = &input_data_end[0] - &input_data[0]; |  | ||||||
| - |  | ||||||
| -	inptr = 1; |  | ||||||
| -	return inbuf[0]; |  | ||||||
| -} |  | ||||||
| +#ifdef CONFIG_KERNEL_GZIP |  | ||||||
| +#include "../../../../lib/decompress_inflate.c" |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
| -/* =========================================================================== |  | ||||||
| - * Write the output window window[0..outcnt-1] and update crc and bytes_out. |  | ||||||
| - * (Used for the decompressed data only.) |  | ||||||
| - */ |  | ||||||
| -void flush_window(void) |  | ||||||
| -{ |  | ||||||
| -	ulg c = crc; |  | ||||||
| -	unsigned n; |  | ||||||
| -	uch *in, *out, ch; |  | ||||||
| - |  | ||||||
| -	in = window; |  | ||||||
| -	out = &output_data[output_ptr]; |  | ||||||
| -	for (n = 0; n < outcnt; n++) { |  | ||||||
| -		ch = *out++ = *in++; |  | ||||||
| -		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); |  | ||||||
| -	} |  | ||||||
| -	crc = c; |  | ||||||
| -	bytes_out += (ulg)outcnt; |  | ||||||
| -	output_ptr += (ulg)outcnt; |  | ||||||
| -	outcnt = 0; |  | ||||||
| -	putstr("."); |  | ||||||
| -} |  | ||||||
| +#ifdef CONFIG_KERNEL_LZO |  | ||||||
| +#include "../../../../lib/decompress_unlzo.c" |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
|  #ifndef arch_error |  | ||||||
|  #define arch_error(x) |  | ||||||
| @@ -314,22 +256,33 @@ static void error(char *x) |  | ||||||
|  	while(1);	/* Halt */ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +asmlinkage void __div0(void) |  | ||||||
| +{ |  | ||||||
| +	error("Attempting division by 0!"); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  #ifndef STANDALONE_DEBUG |  | ||||||
|   |  | ||||||
| -ulg |  | ||||||
| -decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, |  | ||||||
| -		  int arch_id) |  | ||||||
| +unsigned long |  | ||||||
| +decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, |  | ||||||
| +		unsigned long free_mem_ptr_end_p, |  | ||||||
| +		int arch_id) |  | ||||||
|  { |  | ||||||
| -	output_data		= (uch *)output_start;	/* Points to kernel start */ |  | ||||||
| +	unsigned char *tmp; |  | ||||||
| + |  | ||||||
| +	output_data		= (unsigned char *)output_start; |  | ||||||
|  	free_mem_ptr		= free_mem_ptr_p; |  | ||||||
|  	free_mem_end_ptr	= free_mem_ptr_end_p; |  | ||||||
|  	__machine_arch_type	= arch_id; |  | ||||||
|   |  | ||||||
|  	arch_decomp_setup(); |  | ||||||
|   |  | ||||||
| -	makecrc(); |  | ||||||
| +	tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); |  | ||||||
| +	output_ptr = get_unaligned_le32(tmp); |  | ||||||
| + |  | ||||||
|  	putstr("Uncompressing Linux..."); |  | ||||||
| -	gunzip(); |  | ||||||
| +	decompress(input_data, input_data_end - input_data, |  | ||||||
| +			NULL, NULL, output_data, NULL, error); |  | ||||||
|  	putstr(" done, booting the kernel.\n"); |  | ||||||
|  	return output_ptr; |  | ||||||
|  } |  | ||||||
| @@ -341,11 +294,10 @@ int main() |  | ||||||
|  { |  | ||||||
|  	output_data = output_buffer; |  | ||||||
|   |  | ||||||
| -	makecrc(); |  | ||||||
|  	putstr("Uncompressing Linux..."); |  | ||||||
| -	gunzip(); |  | ||||||
| +	decompress(input_data, input_data_end - input_data, |  | ||||||
| +			NULL, NULL, output_data, NULL, error); |  | ||||||
|  	putstr("done.\n"); |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|  #endif |  | ||||||
| -	 |  | ||||||
| --- a/arch/arm/boot/compressed/piggy.S |  | ||||||
| +++ /dev/null |  | ||||||
| @@ -1,6 +0,0 @@ |  | ||||||
| -	.section .piggydata,#alloc |  | ||||||
| -	.globl	input_data |  | ||||||
| -input_data: |  | ||||||
| -	.incbin	"arch/arm/boot/compressed/piggy.gz" |  | ||||||
| -	.globl	input_data_end |  | ||||||
| -input_data_end: |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/arch/arm/boot/compressed/piggy.gzip.S |  | ||||||
| @@ -0,0 +1,6 @@ |  | ||||||
| +	.section .piggydata,#alloc |  | ||||||
| +	.globl	input_data |  | ||||||
| +input_data: |  | ||||||
| +	.incbin	"arch/arm/boot/compressed/piggy.gzip" |  | ||||||
| +	.globl	input_data_end |  | ||||||
| +input_data_end: |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/arch/arm/boot/compressed/piggy.lzo.S |  | ||||||
| @@ -0,0 +1,6 @@ |  | ||||||
| +	.section .piggydata,#alloc |  | ||||||
| +	.globl	input_data |  | ||||||
| +input_data: |  | ||||||
| +	.incbin	"arch/arm/boot/compressed/piggy.lzo" |  | ||||||
| +	.globl	input_data_end |  | ||||||
| +input_data_end: |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| --- a/arch/x86/Kconfig |  | ||||||
| +++ b/arch/x86/Kconfig |  | ||||||
| @@ -49,6 +49,7 @@ config X86 |  | ||||||
|  	select HAVE_KERNEL_GZIP |  | ||||||
|  	select HAVE_KERNEL_BZIP2 |  | ||||||
|  	select HAVE_KERNEL_LZMA |  | ||||||
| +	select HAVE_KERNEL_LZO |  | ||||||
|  	select HAVE_ARCH_KMEMCHECK |  | ||||||
|   |  | ||||||
|  config OUTPUT_FORMAT |  | ||||||
| --- a/arch/x86/boot/compressed/Makefile |  | ||||||
| +++ b/arch/x86/boot/compressed/Makefile |  | ||||||
| @@ -4,7 +4,7 @@ |  | ||||||
|  # create a compressed vmlinux image from the original vmlinux |  | ||||||
|  # |  | ||||||
|   |  | ||||||
| -targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o |  | ||||||
| +targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o |  | ||||||
|   |  | ||||||
|  KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 |  | ||||||
|  KBUILD_CFLAGS += -fno-strict-aliasing -fPIC |  | ||||||
| @@ -48,10 +48,13 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.al |  | ||||||
|  	$(call if_changed,bzip2) |  | ||||||
|  $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE |  | ||||||
|  	$(call if_changed,lzma) |  | ||||||
| +$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE |  | ||||||
| +	$(call if_changed,lzo) |  | ||||||
|   |  | ||||||
|  suffix-$(CONFIG_KERNEL_GZIP)	:= gz |  | ||||||
|  suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2 |  | ||||||
|  suffix-$(CONFIG_KERNEL_LZMA)	:= lzma |  | ||||||
| +suffix-$(CONFIG_KERNEL_LZO) 	:= lzo |  | ||||||
|   |  | ||||||
|  quiet_cmd_mkpiggy = MKPIGGY $@ |  | ||||||
|        cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false ) |  | ||||||
| --- a/arch/x86/boot/compressed/misc.c |  | ||||||
| +++ b/arch/x86/boot/compressed/misc.c |  | ||||||
| @@ -162,6 +162,10 @@ static int lines, cols; |  | ||||||
|  #include "../../../../lib/decompress_unlzma.c" |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifdef CONFIG_KERNEL_LZO |  | ||||||
| +#include "../../../../lib/decompress_unlzo.c" |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  static void scroll(void) |  | ||||||
|  { |  | ||||||
|  	int i; |  | ||||||
| @@ -1,106 +0,0 @@ | |||||||
| --- a/lib/Kconfig |  | ||||||
| +++ b/lib/Kconfig |  | ||||||
| @@ -126,6 +126,10 @@ config DECOMPRESS_LZMA |  | ||||||
|  config DECOMPRESS_LZMA_NEEDED |  | ||||||
|  	 boolean |  | ||||||
|   |  | ||||||
| +config DECOMPRESS_LZO |  | ||||||
| +	select LZO_DECOMPRESS |  | ||||||
| +	tristate |  | ||||||
| + |  | ||||||
|  # |  | ||||||
|  # Generic allocator support is selected if needed |  | ||||||
|  # |  | ||||||
| --- a/lib/Makefile |  | ||||||
| +++ b/lib/Makefile |  | ||||||
| @@ -81,6 +81,7 @@ obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ |  | ||||||
|  lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o |  | ||||||
|  lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o |  | ||||||
|  lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o |  | ||||||
| +lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o |  | ||||||
|   |  | ||||||
|  obj-$(CONFIG_TEXTSEARCH) += textsearch.o |  | ||||||
|  obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o |  | ||||||
| --- a/lib/decompress.c |  | ||||||
| +++ b/lib/decompress.c |  | ||||||
| @@ -9,6 +9,7 @@ |  | ||||||
|  #include <linux/decompress/bunzip2.h> |  | ||||||
|  #include <linux/decompress/unlzma.h> |  | ||||||
|  #include <linux/decompress/inflate.h> |  | ||||||
| +#include <linux/decompress/unlzo.h> |  | ||||||
|   |  | ||||||
|  #include <linux/types.h> |  | ||||||
|  #include <linux/string.h> |  | ||||||
| @@ -22,6 +23,9 @@ |  | ||||||
|  #ifndef CONFIG_DECOMPRESS_LZMA |  | ||||||
|  # define unlzma NULL |  | ||||||
|  #endif |  | ||||||
| +#ifndef CONFIG_DECOMPRESS_LZO |  | ||||||
| +# define unlzo NULL |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
|  static const struct compress_format { |  | ||||||
|  	unsigned char magic[2]; |  | ||||||
| @@ -32,6 +36,7 @@ static const struct compress_format { |  | ||||||
|  	{ {037, 0236}, "gzip", gunzip }, |  | ||||||
|  	{ {0x42, 0x5a}, "bzip2", bunzip2 }, |  | ||||||
|  	{ {0x5d, 0x00}, "lzma", unlzma }, |  | ||||||
| +	{ {0x89, 0x4c}, "lzo", unlzo }, |  | ||||||
|  	{ {0, 0}, NULL, NULL } |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| --- a/usr/Kconfig |  | ||||||
| +++ b/usr/Kconfig |  | ||||||
| @@ -72,6 +72,15 @@ config RD_LZMA |  | ||||||
|  	  Support loading of a LZMA encoded initial ramdisk or cpio buffer |  | ||||||
|  	  If unsure, say N. |  | ||||||
|   |  | ||||||
| +config RD_LZO |  | ||||||
| +	bool "Support initial ramdisks compressed using LZO" if EMBEDDED |  | ||||||
| +	default !EMBEDDED |  | ||||||
| +	depends on BLK_DEV_INITRD && HAVE_KERNEL_LZO |  | ||||||
| +	select DECOMPRESS_LZO |  | ||||||
| +	help |  | ||||||
| +	  Support loading of a LZO encoded initial ramdisk or cpio buffer |  | ||||||
| +	  If unsure, say N. |  | ||||||
| + |  | ||||||
|  choice |  | ||||||
|  	prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!="" |  | ||||||
|  	help |  | ||||||
| @@ -108,16 +117,15 @@ config INITRAMFS_COMPRESSION_GZIP |  | ||||||
|  	bool "Gzip" |  | ||||||
|  	depends on RD_GZIP |  | ||||||
|  	help |  | ||||||
| -	  The old and tried gzip compression. Its compression ratio is |  | ||||||
| -	  the poorest among the 3 choices; however its speed (both |  | ||||||
| -	  compression and decompression) is the fastest. |  | ||||||
| +	  The old and tried gzip compression. It provides a good balance |  | ||||||
| +	  between compression ratio and decompression speed. |  | ||||||
|   |  | ||||||
|  config INITRAMFS_COMPRESSION_BZIP2 |  | ||||||
|  	bool "Bzip2" |  | ||||||
|  	depends on RD_BZIP2 |  | ||||||
|  	help |  | ||||||
|  	  Its compression ratio and speed is intermediate. |  | ||||||
| -	  Decompression speed is slowest among the three.  The initramfs |  | ||||||
| +	  Decompression speed is slowest among the four.  The initramfs |  | ||||||
|  	  size is about 10% smaller with bzip2, in comparison to gzip. |  | ||||||
|  	  Bzip2 uses a large amount of memory. For modern kernels you |  | ||||||
|  	  will need at least 8MB RAM or more for booting. |  | ||||||
| @@ -128,7 +136,15 @@ config INITRAMFS_COMPRESSION_LZMA |  | ||||||
|  	help |  | ||||||
|  	  The most recent compression algorithm. |  | ||||||
|  	  Its ratio is best, decompression speed is between the other |  | ||||||
| -	  two. Compression is slowest.	The initramfs size is about 33% |  | ||||||
| +	  three. Compression is slowest. The initramfs size is about 33% |  | ||||||
|  	  smaller with LZMA in comparison to gzip. |  | ||||||
|   |  | ||||||
| +config INITRAMFS_COMPRESSION_LZO |  | ||||||
| +	bool "LZO" |  | ||||||
| +	depends on RD_LZO |  | ||||||
| +	help |  | ||||||
| +	  Its compression ratio is the poorest among the four. The kernel |  | ||||||
| +	  size is about about 10% bigger than gzip; however its speed |  | ||||||
| +	  (both compression and decompression) is the fastest. |  | ||||||
| + |  | ||||||
|  endchoice |  | ||||||
| @@ -1,57 +0,0 @@ | |||||||
| From d0f226a0f104c7d1da1d215b8013359273e39e18 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Albin Tonnerre <albin.tonnerre@free-electrons.com> |  | ||||||
| Date: Fri, 16 Oct 2009 16:17:22 +0200 |  | ||||||
| Subject: [PATCH] Add LZMA decompression on ARM |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Signed-off-by: Albin Tonnerre <albin.tonnerre@free-electrons.com> |  | ||||||
| --- |  | ||||||
|  arch/arm/Kconfig                      |    1 + |  | ||||||
|  arch/arm/boot/compressed/Makefile     |    1 + |  | ||||||
|  arch/arm/boot/compressed/misc.c       |    4 ++++ |  | ||||||
|  arch/arm/boot/compressed/piggy.lzma.S |    6 ++++++ |  | ||||||
|  4 files changed, 12 insertions(+), 0 deletions(-) |  | ||||||
|  create mode 100644 arch/arm/boot/compressed/piggy.lzma.S |  | ||||||
|  |  | ||||||
| --- a/arch/arm/Kconfig |  | ||||||
| +++ b/arch/arm/Kconfig |  | ||||||
| @@ -20,6 +20,7 @@ config ARM |  | ||||||
|  	select HAVE_GENERIC_DMA_COHERENT |  | ||||||
|  	select HAVE_KERNEL_GZIP |  | ||||||
|  	select HAVE_KERNEL_LZO |  | ||||||
| +	select HAVE_KERNEL_LZMA |  | ||||||
|  	help |  | ||||||
|  	  The ARM series is a line of low-power-consumption RISC chip designs |  | ||||||
|  	  licensed by ARM Ltd and targeted at embedded applications and |  | ||||||
| --- a/arch/arm/boot/compressed/Makefile |  | ||||||
| +++ b/arch/arm/boot/compressed/Makefile |  | ||||||
| @@ -65,6 +65,7 @@ SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/ |  | ||||||
|   |  | ||||||
|  suffix_$(CONFIG_KERNEL_GZIP) = gzip |  | ||||||
|  suffix_$(CONFIG_KERNEL_LZO)  = lzo |  | ||||||
| +suffix_$(CONFIG_KERNEL_LZMA)  = lzma |  | ||||||
|   |  | ||||||
|  targets       := vmlinux vmlinux.lds \ |  | ||||||
|  		 piggy.$(suffix_y) piggy.$(suffix_y).o \ |  | ||||||
| --- a/arch/arm/boot/compressed/misc.c |  | ||||||
| +++ b/arch/arm/boot/compressed/misc.c |  | ||||||
| @@ -237,6 +237,10 @@ static unsigned long free_mem_end_ptr; |  | ||||||
|  #include "../../../../lib/decompress_inflate.c" |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifdef CONFIG_KERNEL_LZMA |  | ||||||
| +#include "../../../../lib/decompress_unlzma.c" |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  #ifdef CONFIG_KERNEL_LZO |  | ||||||
|  #include "../../../../lib/decompress_unlzo.c" |  | ||||||
|  #endif |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/arch/arm/boot/compressed/piggy.lzma.S |  | ||||||
| @@ -0,0 +1,6 @@ |  | ||||||
| +	.section .piggydata,#alloc |  | ||||||
| +	.globl	input_data |  | ||||||
| +input_data: |  | ||||||
| +	.incbin	"arch/arm/boot/compressed/piggy.lzma" |  | ||||||
| +	.globl	input_data_end |  | ||||||
| +input_data_end: |  | ||||||
| @@ -1,63 +0,0 @@ | |||||||
| From b53e9b5ebd5c6e718f54bcacd4e97b71533ca681 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Tony Lindgren <tony@atomide.com> |  | ||||||
| Date: Thu, 14 Jan 2010 20:36:55 +0100 |  | ||||||
| Subject: [PATCH] ARM: 5882/1: ARM: Fix uncompress code compile for different defines of flush(void) |  | ||||||
|  |  | ||||||
| Because of the include of the decompress_inflate.c file from |  | ||||||
| boot/compress/misc.c, there are different flush() defines: |  | ||||||
|  |  | ||||||
| In file included from arch/arm/boot/compressed/misc.c:249: |  | ||||||
| arch/arm/boot/compressed/../../../../lib/decompress_inflate.c:138:29: error: macro "flush" passed 2 arguments, but takes just 0 |  | ||||||
|  |  | ||||||
| Fix this by removing the define of flush() in misc.c for |  | ||||||
| CONFIG_DEBUG_ICEDCC as it's already defined in mach/uncompress.h, |  | ||||||
| and that is being included unconditionally. |  | ||||||
|  |  | ||||||
| Also use a static inline function instead of define |  | ||||||
| for mach-mxc and mach-gemini to avoid similar bug |  | ||||||
| for those platforms. |  | ||||||
|  |  | ||||||
| Signed-off-by: Tony Lindgren <tony@atomide.com> |  | ||||||
| Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> |  | ||||||
| --- |  | ||||||
|  arch/arm/boot/compressed/misc.c                |    1 - |  | ||||||
|  arch/arm/mach-gemini/include/mach/uncompress.h |    4 +++- |  | ||||||
|  arch/arm/plat-mxc/include/mach/uncompress.h    |    4 +++- |  | ||||||
|  3 files changed, 6 insertions(+), 3 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/arch/arm/boot/compressed/misc.c |  | ||||||
| +++ b/arch/arm/boot/compressed/misc.c |  | ||||||
| @@ -88,7 +88,6 @@ static void icedcc_putc(int ch) |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  #define putc(ch)	icedcc_putc(ch) |  | ||||||
| -#define flush()	do { } while (0) |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  static void putstr(const char *ptr) |  | ||||||
| --- a/arch/arm/mach-gemini/include/mach/uncompress.h |  | ||||||
| +++ b/arch/arm/mach-gemini/include/mach/uncompress.h |  | ||||||
| @@ -30,7 +30,9 @@ static inline void putc(char c) |  | ||||||
|  	UART[UART_TX] = c; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#define flush() do { } while (0) |  | ||||||
| +static inline void flush(void) |  | ||||||
| +{ |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * nothing to do |  | ||||||
| --- a/arch/arm/plat-mxc/include/mach/uncompress.h |  | ||||||
| +++ b/arch/arm/plat-mxc/include/mach/uncompress.h |  | ||||||
| @@ -60,7 +60,9 @@ static void putc(int ch) |  | ||||||
|  	UART(TXR) = ch; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#define flush() do { } while (0) |  | ||||||
| +static inline void flush(void) |  | ||||||
| +{ |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  #define MX1_UART1_BASE_ADDR	0x00206000 |  | ||||||
|  #define MX25_UART1_BASE_ADDR	0x43f90000 |  | ||||||
| @@ -1,120 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/block2mtd.c |  | ||||||
| +++ b/drivers/mtd/devices/block2mtd.c |  | ||||||
| @@ -14,6 +14,7 @@ |  | ||||||
|  #include <linux/list.h> |  | ||||||
|  #include <linux/init.h> |  | ||||||
|  #include <linux/mtd/mtd.h> |  | ||||||
| +#include <linux/mtd/partitions.h> |  | ||||||
|  #include <linux/buffer_head.h> |  | ||||||
|  #include <linux/mutex.h> |  | ||||||
|  #include <linux/mount.h> |  | ||||||
| @@ -232,10 +233,11 @@ static void block2mtd_free_device(struct |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  /* FIXME: ensure that mtd->size % erase_size == 0 */ |  | ||||||
| -static struct block2mtd_dev *add_device(char *devname, int erase_size) |  | ||||||
| +static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname) |  | ||||||
|  { |  | ||||||
|  	struct block_device *bdev; |  | ||||||
|  	struct block2mtd_dev *dev; |  | ||||||
| +	struct mtd_partition *part; |  | ||||||
|  	char *name; |  | ||||||
|   |  | ||||||
|  	if (!devname) |  | ||||||
| @@ -273,17 +275,17 @@ static struct block2mtd_dev *add_device( |  | ||||||
|   |  | ||||||
|  	mutex_init(&dev->write_mutex); |  | ||||||
|   |  | ||||||
| -	/* Setup the MTD structure */ |  | ||||||
| -	/* make the name contain the block device in */ |  | ||||||
| -	name = kmalloc(sizeof("block2mtd: ") + strlen(devname) + 1, |  | ||||||
| -			GFP_KERNEL); |  | ||||||
| +	if (!mtdname) |  | ||||||
| +		mtdname = devname; |  | ||||||
| + |  | ||||||
| +	name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL); |  | ||||||
|  	if (!name) |  | ||||||
|  		goto devinit_err; |  | ||||||
|   |  | ||||||
| -	sprintf(name, "block2mtd: %s", devname); |  | ||||||
| +	strcpy(name, mtdname); |  | ||||||
|  	dev->mtd.name = name; |  | ||||||
|   |  | ||||||
| -	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; |  | ||||||
| +	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1); |  | ||||||
|  	dev->mtd.erasesize = erase_size; |  | ||||||
|  	dev->mtd.writesize = 1; |  | ||||||
|  	dev->mtd.type = MTD_RAM; |  | ||||||
| @@ -296,14 +298,17 @@ static struct block2mtd_dev *add_device( |  | ||||||
|  	dev->mtd.priv = dev; |  | ||||||
|  	dev->mtd.owner = THIS_MODULE; |  | ||||||
|   |  | ||||||
| -	if (add_mtd_device(&dev->mtd)) { |  | ||||||
| +	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); |  | ||||||
| +	part->name = dev->mtd.name; |  | ||||||
| +	part->offset = 0; |  | ||||||
| +	part->size = dev->mtd.size; |  | ||||||
| +	if (add_mtd_partitions(&dev->mtd, part, 1)) { |  | ||||||
|  		/* Device didnt get added, so free the entry */ |  | ||||||
|  		goto devinit_err; |  | ||||||
|  	} |  | ||||||
|  	list_add(&dev->list, &blkmtd_device_list); |  | ||||||
|  	INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index, |  | ||||||
| -			dev->mtd.name + strlen("block2mtd: "), |  | ||||||
| -			dev->mtd.erasesize >> 10, dev->mtd.erasesize); |  | ||||||
| +			mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize); |  | ||||||
|  	return dev; |  | ||||||
|   |  | ||||||
|  devinit_err: |  | ||||||
| @@ -376,9 +381,9 @@ static char block2mtd_paramline[80 + 12] |  | ||||||
|   |  | ||||||
|  static int block2mtd_setup2(const char *val) |  | ||||||
|  { |  | ||||||
| -	char buf[80 + 12]; /* 80 for device, 12 for erase size */ |  | ||||||
| +	char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */ |  | ||||||
|  	char *str = buf; |  | ||||||
| -	char *token[2]; |  | ||||||
| +	char *token[3]; |  | ||||||
|  	char *name; |  | ||||||
|  	size_t erase_size = PAGE_SIZE; |  | ||||||
|  	int i, ret; |  | ||||||
| @@ -389,7 +394,7 @@ static int block2mtd_setup2(const char * |  | ||||||
|  	strcpy(str, val); |  | ||||||
|  	kill_final_newline(str); |  | ||||||
|   |  | ||||||
| -	for (i = 0; i < 2; i++) |  | ||||||
| +	for (i = 0; i < 3; i++) |  | ||||||
|  		token[i] = strsep(&str, ","); |  | ||||||
|   |  | ||||||
|  	if (str) |  | ||||||
| @@ -408,8 +413,10 @@ static int block2mtd_setup2(const char * |  | ||||||
|  			parse_err("illegal erase size"); |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
| +	if (token[2] && (strlen(token[2]) + 1 > 80)) |  | ||||||
| +		parse_err("mtd device name too long"); |  | ||||||
|   |  | ||||||
| -	add_device(name, erase_size); |  | ||||||
| +	add_device(name, erase_size, token[2]); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| @@ -443,7 +450,7 @@ static int block2mtd_setup(const char *v |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); |  | ||||||
| -MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); |  | ||||||
| +MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\""); |  | ||||||
|   |  | ||||||
|  static int __init block2mtd_init(void) |  | ||||||
|  { |  | ||||||
| --- a/fs/partitions/check.c |  | ||||||
| +++ b/fs/partitions/check.c |  | ||||||
| @@ -625,6 +625,7 @@ try_scan: |  | ||||||
|  	kfree(state); |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| +EXPORT_SYMBOL(rescan_partitions); |  | ||||||
|   |  | ||||||
|  unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) |  | ||||||
|  { |  | ||||||
| @@ -1,627 +0,0 @@ | |||||||
| --- a/drivers/mtd/Kconfig |  | ||||||
| +++ b/drivers/mtd/Kconfig |  | ||||||
| @@ -53,6 +53,16 @@ config MTD_PARTITIONS |  | ||||||
|  	  devices. Partitioning on NFTL 'devices' is a different - that's the |  | ||||||
|  	  'normal' form of partitioning used on a block device. |  | ||||||
|   |  | ||||||
| +config MTD_ROOTFS_ROOT_DEV |  | ||||||
| +	bool "Automatically set 'rootfs' partition to be root filesystem" |  | ||||||
| +	depends on MTD_PARTITIONS |  | ||||||
| +	default y |  | ||||||
| + |  | ||||||
| +config MTD_ROOTFS_SPLIT |  | ||||||
| +	bool "Automatically split 'rootfs' partition for squashfs" |  | ||||||
| +	depends on MTD_PARTITIONS |  | ||||||
| +	default y |  | ||||||
| + |  | ||||||
|  config MTD_REDBOOT_PARTS |  | ||||||
|  	tristate "RedBoot partition table parsing" |  | ||||||
|  	depends on MTD_PARTITIONS |  | ||||||
| --- a/drivers/mtd/mtdpart.c |  | ||||||
| +++ b/drivers/mtd/mtdpart.c |  | ||||||
| @@ -18,6 +18,8 @@ |  | ||||||
|  #include <linux/mtd/mtd.h> |  | ||||||
|  #include <linux/mtd/partitions.h> |  | ||||||
|  #include <linux/mtd/compatmac.h> |  | ||||||
| +#include <linux/root_dev.h> |  | ||||||
| +#include <linux/magic.h> |  | ||||||
|   |  | ||||||
|  /* Our partition linked list */ |  | ||||||
|  static LIST_HEAD(mtd_partitions); |  | ||||||
| @@ -35,7 +37,7 @@ struct mtd_part { |  | ||||||
|   * the pointer to that structure with this macro. |  | ||||||
|   */ |  | ||||||
|  #define PART(x)  ((struct mtd_part *)(x)) |  | ||||||
| - |  | ||||||
| +#define IS_PART(mtd) (mtd->read == part_read) |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * MTD methods which simply translate the effective address and pass through |  | ||||||
| @@ -503,6 +505,152 @@ out_register: |  | ||||||
|  	return slave; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +#ifdef CONFIG_MTD_ROOTFS_SPLIT |  | ||||||
| +#define ROOTFS_SPLIT_NAME "rootfs_data" |  | ||||||
| +#define ROOTFS_REMOVED_NAME "<removed>" |  | ||||||
| + |  | ||||||
| +struct squashfs_super_block { |  | ||||||
| +	__le32 s_magic; |  | ||||||
| +	__le32 pad0[9]; |  | ||||||
| +	__le64 bytes_used; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) |  | ||||||
| +{ |  | ||||||
| +	struct squashfs_super_block sb; |  | ||||||
| +	int len, ret; |  | ||||||
| + |  | ||||||
| +	ret = master->read(master, offset, sizeof(sb), &len, (void *) &sb); |  | ||||||
| +	if (ret || (len != sizeof(sb))) { |  | ||||||
| +		printk(KERN_ALERT "split_squashfs: error occured while reading " |  | ||||||
| +			"from \"%s\"\n", master->name); |  | ||||||
| +		return -EINVAL; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) { |  | ||||||
| +		printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n", |  | ||||||
| +			master->name); |  | ||||||
| +		*split_offset = 0; |  | ||||||
| +		return 0; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (le64_to_cpu((sb.bytes_used)) <= 0) { |  | ||||||
| +		printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n", |  | ||||||
| +			master->name); |  | ||||||
| +		*split_offset = 0; |  | ||||||
| +		return 0; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	len = (u32) le64_to_cpu(sb.bytes_used); |  | ||||||
| +	len += (offset & 0x000fffff); |  | ||||||
| +	len +=  (master->erasesize - 1); |  | ||||||
| +	len &= ~(master->erasesize - 1); |  | ||||||
| +	len -= (offset & 0x000fffff); |  | ||||||
| +	*split_offset = offset + len; |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int split_rootfs_data(struct mtd_info *master, struct mtd_info *rpart, const struct mtd_partition *part) |  | ||||||
| +{ |  | ||||||
| +	struct mtd_partition *dpart; |  | ||||||
| +	struct mtd_part *slave = NULL; |  | ||||||
| +	struct mtd_part *spart; |  | ||||||
| +	int split_offset = 0; |  | ||||||
| +	int ret; |  | ||||||
| + |  | ||||||
| +	spart = PART(rpart); |  | ||||||
| +	ret = split_squashfs(master, spart->offset, &split_offset); |  | ||||||
| +	if (ret) |  | ||||||
| +		return ret; |  | ||||||
| + |  | ||||||
| +	if (split_offset <= 0) |  | ||||||
| +		return 0; |  | ||||||
| + |  | ||||||
| +	dpart = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL); |  | ||||||
| +	if (dpart == NULL) { |  | ||||||
| +		printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n", |  | ||||||
| +			ROOTFS_SPLIT_NAME); |  | ||||||
| +		return -ENOMEM; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	memcpy(dpart, part, sizeof(*part)); |  | ||||||
| +	dpart->name = (unsigned char *)&dpart[1]; |  | ||||||
| +	strcpy(dpart->name, ROOTFS_SPLIT_NAME); |  | ||||||
| + |  | ||||||
| +	dpart->size = rpart->size - (split_offset - spart->offset); |  | ||||||
| +	dpart->offset = split_offset; |  | ||||||
| + |  | ||||||
| +	if (dpart == NULL) |  | ||||||
| +		return 1; |  | ||||||
| + |  | ||||||
| +	printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%llX, len=%llX \n", |  | ||||||
| +		ROOTFS_SPLIT_NAME, dpart->offset, dpart->size); |  | ||||||
| + |  | ||||||
| +	slave = add_one_partition(master, dpart, 0, split_offset); |  | ||||||
| +	if (!slave) { |  | ||||||
| +		kfree(dpart); |  | ||||||
| +		return -ENOMEM; |  | ||||||
| +	} |  | ||||||
| +	rpart->split = &slave->mtd; |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int refresh_rootfs_split(struct mtd_info *mtd) |  | ||||||
| +{ |  | ||||||
| +	struct mtd_partition tpart; |  | ||||||
| +	struct mtd_part *part; |  | ||||||
| +	char *name; |  | ||||||
| +	//int index = 0; |  | ||||||
| +	int offset, size; |  | ||||||
| +	int ret; |  | ||||||
| + |  | ||||||
| +	part = PART(mtd); |  | ||||||
| + |  | ||||||
| +	/* check for the new squashfs offset first */ |  | ||||||
| +	ret = split_squashfs(part->master, part->offset, &offset); |  | ||||||
| +	if (ret) |  | ||||||
| +		return ret; |  | ||||||
| + |  | ||||||
| +	if ((offset > 0) && !mtd->split) { |  | ||||||
| +		printk(KERN_INFO "%s: creating new split partition for \"%s\"\n", __func__, mtd->name); |  | ||||||
| +		/* if we don't have a rootfs split partition, create a new one */ |  | ||||||
| +		tpart.name = (char *) mtd->name; |  | ||||||
| +		tpart.size = mtd->size; |  | ||||||
| +		tpart.offset = part->offset; |  | ||||||
| + |  | ||||||
| +		return split_rootfs_data(part->master, &part->mtd, &tpart); |  | ||||||
| +	} else if ((offset > 0) && mtd->split) { |  | ||||||
| +		/* update the offsets of the existing partition */ |  | ||||||
| +		size = mtd->size + part->offset - offset; |  | ||||||
| + |  | ||||||
| +		part = PART(mtd->split); |  | ||||||
| +		part->offset = offset; |  | ||||||
| +		part->mtd.size = size; |  | ||||||
| +		printk(KERN_INFO "%s: %s partition \"" ROOTFS_SPLIT_NAME "\", offset: 0x%06x (0x%06x)\n", |  | ||||||
| +			__func__, (!strcmp(part->mtd.name, ROOTFS_SPLIT_NAME) ? "updating" : "creating"), |  | ||||||
| +			(u32) part->offset, (u32) part->mtd.size); |  | ||||||
| +		name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL); |  | ||||||
| +		strcpy(name, ROOTFS_SPLIT_NAME); |  | ||||||
| +		part->mtd.name = name; |  | ||||||
| +	} else if ((offset <= 0) && mtd->split) { |  | ||||||
| +		printk(KERN_INFO "%s: removing partition \"%s\"\n", __func__, mtd->split->name); |  | ||||||
| + |  | ||||||
| +		/* mark existing partition as removed */ |  | ||||||
| +		part = PART(mtd->split); |  | ||||||
| +		name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL); |  | ||||||
| +		strcpy(name, ROOTFS_REMOVED_NAME); |  | ||||||
| +		part->mtd.name = name; |  | ||||||
| +		part->offset = 0; |  | ||||||
| +		part->mtd.size = 0; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| +#endif /* CONFIG_MTD_ROOTFS_SPLIT */ |  | ||||||
| + |  | ||||||
|  /* |  | ||||||
|   * This function, given a master MTD object and a partition table, creates |  | ||||||
|   * and registers slave MTD objects which are bound to the master according to |  | ||||||
| @@ -518,7 +666,7 @@ int add_mtd_partitions(struct mtd_info * |  | ||||||
|  { |  | ||||||
|  	struct mtd_part *slave; |  | ||||||
|  	uint64_t cur_offset = 0; |  | ||||||
| -	int i; |  | ||||||
| +	int i, ret; |  | ||||||
|   |  | ||||||
|  	printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); |  | ||||||
|   |  | ||||||
| @@ -526,6 +674,21 @@ int add_mtd_partitions(struct mtd_info * |  | ||||||
|  		slave = add_one_partition(master, parts + i, i, cur_offset); |  | ||||||
|  		if (!slave) |  | ||||||
|  			return -ENOMEM; |  | ||||||
| + |  | ||||||
| +		if (!strcmp(parts[i].name, "rootfs")) { |  | ||||||
| +#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV |  | ||||||
| +			if (ROOT_DEV == 0) { |  | ||||||
| +				printk(KERN_NOTICE "mtd: partition \"rootfs\" " |  | ||||||
| +					"set to be root filesystem\n"); |  | ||||||
| +				ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index); |  | ||||||
| +			} |  | ||||||
| +#endif |  | ||||||
| +#ifdef CONFIG_MTD_ROOTFS_SPLIT |  | ||||||
| +			ret = split_rootfs_data(master, &slave->mtd, &parts[i]); |  | ||||||
| +			/* if (ret == 0) |  | ||||||
| +				j++; */ |  | ||||||
| +#endif |  | ||||||
| +		} |  | ||||||
|  		cur_offset = slave->offset + slave->mtd.size; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -533,6 +696,32 @@ int add_mtd_partitions(struct mtd_info * |  | ||||||
|  } |  | ||||||
|  EXPORT_SYMBOL(add_mtd_partitions); |  | ||||||
|   |  | ||||||
| +int refresh_mtd_partitions(struct mtd_info *mtd) |  | ||||||
| +{ |  | ||||||
| +	int ret = 0; |  | ||||||
| + |  | ||||||
| +	if (IS_PART(mtd)) { |  | ||||||
| +		struct mtd_part *part; |  | ||||||
| +		struct mtd_info *master; |  | ||||||
| + |  | ||||||
| +		part = PART(mtd); |  | ||||||
| +		master = part->master; |  | ||||||
| +		if (master->refresh_device) |  | ||||||
| +			ret = master->refresh_device(master); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (!ret && mtd->refresh_device) |  | ||||||
| +		ret = mtd->refresh_device(mtd); |  | ||||||
| + |  | ||||||
| +#ifdef CONFIG_MTD_ROOTFS_SPLIT |  | ||||||
| +	if (!ret && IS_PART(mtd) && !strcmp(mtd->name, "rootfs")) |  | ||||||
| +		refresh_rootfs_split(mtd); |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL_GPL(refresh_mtd_partitions); |  | ||||||
| + |  | ||||||
|  static DEFINE_SPINLOCK(part_parser_lock); |  | ||||||
|  static LIST_HEAD(part_parsers); |  | ||||||
|   |  | ||||||
| --- a/drivers/mtd/devices/block2mtd.c |  | ||||||
| +++ b/drivers/mtd/devices/block2mtd.c |  | ||||||
| @@ -29,6 +29,8 @@ struct block2mtd_dev { |  | ||||||
|  	struct block_device *blkdev; |  | ||||||
|  	struct mtd_info mtd; |  | ||||||
|  	struct mutex write_mutex; |  | ||||||
| +	rwlock_t bdev_mutex; |  | ||||||
| +	char devname[0]; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -81,6 +83,12 @@ static int block2mtd_erase(struct mtd_in |  | ||||||
|  	size_t len = instr->len; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
| +	read_lock(&dev->bdev_mutex); |  | ||||||
| +	if (!dev->blkdev) { |  | ||||||
| +		err = -EINVAL; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	instr->state = MTD_ERASING; |  | ||||||
|  	mutex_lock(&dev->write_mutex); |  | ||||||
|  	err = _block2mtd_erase(dev, from, len); |  | ||||||
| @@ -93,6 +101,10 @@ static int block2mtd_erase(struct mtd_in |  | ||||||
|   |  | ||||||
|  	instr->state = MTD_ERASE_DONE; |  | ||||||
|  	mtd_erase_callback(instr); |  | ||||||
| + |  | ||||||
| +done: |  | ||||||
| +	read_unlock(&dev->bdev_mutex); |  | ||||||
| + |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -104,10 +116,14 @@ static int block2mtd_read(struct mtd_inf |  | ||||||
|  	struct page *page; |  | ||||||
|  	int index = from >> PAGE_SHIFT; |  | ||||||
|  	int offset = from & (PAGE_SIZE-1); |  | ||||||
| -	int cpylen; |  | ||||||
| +	int cpylen, err = 0; |  | ||||||
| + |  | ||||||
| +	read_lock(&dev->bdev_mutex); |  | ||||||
| +	if (!dev->blkdev || (from > mtd->size)) { |  | ||||||
| +		err = -EINVAL; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
| -	if (from > mtd->size) |  | ||||||
| -		return -EINVAL; |  | ||||||
|  	if (from + len > mtd->size) |  | ||||||
|  		len = mtd->size - from; |  | ||||||
|   |  | ||||||
| @@ -122,10 +138,14 @@ static int block2mtd_read(struct mtd_inf |  | ||||||
|  		len = len - cpylen; |  | ||||||
|   |  | ||||||
|  		page = page_read(dev->blkdev->bd_inode->i_mapping, index); |  | ||||||
| -		if (!page) |  | ||||||
| -			return -ENOMEM; |  | ||||||
| -		if (IS_ERR(page)) |  | ||||||
| -			return PTR_ERR(page); |  | ||||||
| +		if (!page) { |  | ||||||
| +			err = -ENOMEM; |  | ||||||
| +			goto done; |  | ||||||
| +		} |  | ||||||
| +		if (IS_ERR(page)) { |  | ||||||
| +			err = PTR_ERR(page); |  | ||||||
| +			goto done; |  | ||||||
| +		} |  | ||||||
|   |  | ||||||
|  		memcpy(buf, page_address(page) + offset, cpylen); |  | ||||||
|  		page_cache_release(page); |  | ||||||
| @@ -136,7 +156,10 @@ static int block2mtd_read(struct mtd_inf |  | ||||||
|  		offset = 0; |  | ||||||
|  		index++; |  | ||||||
|  	} |  | ||||||
| -	return 0; |  | ||||||
| + |  | ||||||
| +done: |  | ||||||
| +	read_unlock(&dev->bdev_mutex); |  | ||||||
| +	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -188,12 +211,22 @@ static int block2mtd_write(struct mtd_in |  | ||||||
|  		size_t *retlen, const u_char *buf) |  | ||||||
|  { |  | ||||||
|  	struct block2mtd_dev *dev = mtd->priv; |  | ||||||
| -	int err; |  | ||||||
| +	int err = 0; |  | ||||||
| + |  | ||||||
| +	read_lock(&dev->bdev_mutex); |  | ||||||
| +	if (!dev->blkdev) { |  | ||||||
| +		err = -EINVAL; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	if (!len) |  | ||||||
| -		return 0; |  | ||||||
| -	if (to >= mtd->size) |  | ||||||
| -		return -ENOSPC; |  | ||||||
| +		goto done; |  | ||||||
| + |  | ||||||
| +	if (to >= mtd->size) { |  | ||||||
| +		err = -ENOSPC; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	if (to + len > mtd->size) |  | ||||||
|  		len = mtd->size - to; |  | ||||||
|   |  | ||||||
| @@ -202,6 +235,9 @@ static int block2mtd_write(struct mtd_in |  | ||||||
|  	mutex_unlock(&dev->write_mutex); |  | ||||||
|  	if (err > 0) |  | ||||||
|  		err = 0; |  | ||||||
| + |  | ||||||
| +done: |  | ||||||
| +	read_unlock(&dev->bdev_mutex); |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -210,52 +246,29 @@ static int block2mtd_write(struct mtd_in |  | ||||||
|  static void block2mtd_sync(struct mtd_info *mtd) |  | ||||||
|  { |  | ||||||
|  	struct block2mtd_dev *dev = mtd->priv; |  | ||||||
| -	sync_blockdev(dev->blkdev); |  | ||||||
| -	return; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| - |  | ||||||
| -static void block2mtd_free_device(struct block2mtd_dev *dev) |  | ||||||
| -{ |  | ||||||
| -	if (!dev) |  | ||||||
| -		return; |  | ||||||
| - |  | ||||||
| -	kfree(dev->mtd.name); |  | ||||||
|   |  | ||||||
| -	if (dev->blkdev) { |  | ||||||
| -		invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, |  | ||||||
| -					0, -1); |  | ||||||
| -		close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); |  | ||||||
| -	} |  | ||||||
| +	read_lock(&dev->bdev_mutex); |  | ||||||
| +	if (dev->blkdev) |  | ||||||
| +		sync_blockdev(dev->blkdev); |  | ||||||
| +	read_unlock(&dev->bdev_mutex); |  | ||||||
|   |  | ||||||
| -	kfree(dev); |  | ||||||
| +	return; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -/* FIXME: ensure that mtd->size % erase_size == 0 */ |  | ||||||
| -static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname) |  | ||||||
| +static int _open_bdev(struct block2mtd_dev *dev) |  | ||||||
|  { |  | ||||||
|  	struct block_device *bdev; |  | ||||||
| -	struct block2mtd_dev *dev; |  | ||||||
| -	struct mtd_partition *part; |  | ||||||
| -	char *name; |  | ||||||
| - |  | ||||||
| -	if (!devname) |  | ||||||
| -		return NULL; |  | ||||||
| - |  | ||||||
| -	dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL); |  | ||||||
| -	if (!dev) |  | ||||||
| -		return NULL; |  | ||||||
|   |  | ||||||
|  	/* Get a handle on the device */ |  | ||||||
| -	bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL); |  | ||||||
| +	bdev = open_bdev_exclusive(dev->devname, FMODE_READ|FMODE_WRITE, NULL); |  | ||||||
|  #ifndef MODULE |  | ||||||
|  	if (IS_ERR(bdev)) { |  | ||||||
|   |  | ||||||
|  		/* We might not have rootfs mounted at this point. Try |  | ||||||
|  		   to resolve the device name by other means. */ |  | ||||||
|   |  | ||||||
| -		dev_t devt = name_to_dev_t(devname); |  | ||||||
| +		dev_t devt = name_to_dev_t(dev->devname); |  | ||||||
|  		if (devt) { |  | ||||||
|  			bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); |  | ||||||
|  		} |  | ||||||
| @@ -263,17 +276,98 @@ static struct block2mtd_dev *add_device( |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  	if (IS_ERR(bdev)) { |  | ||||||
| -		ERROR("error: cannot open device %s", devname); |  | ||||||
| -		goto devinit_err; |  | ||||||
| +		ERROR("error: cannot open device %s", dev->devname); |  | ||||||
| +		return 1; |  | ||||||
|  	} |  | ||||||
|  	dev->blkdev = bdev; |  | ||||||
|   |  | ||||||
|  	if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { |  | ||||||
|  		ERROR("attempting to use an MTD device as a block device"); |  | ||||||
| -		goto devinit_err; |  | ||||||
| +		return 1; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void _close_bdev(struct block2mtd_dev *dev) |  | ||||||
| +{ |  | ||||||
| +	struct block_device *bdev; |  | ||||||
| + |  | ||||||
| +	if (!dev->blkdev) |  | ||||||
| +		return; |  | ||||||
| + |  | ||||||
| +	bdev = dev->blkdev; |  | ||||||
| +	invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1); |  | ||||||
| +	close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); |  | ||||||
| +	dev->blkdev = NULL; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void block2mtd_free_device(struct block2mtd_dev *dev) |  | ||||||
| +{ |  | ||||||
| +	if (!dev) |  | ||||||
| +		return; |  | ||||||
| + |  | ||||||
| +	kfree(dev->mtd.name); |  | ||||||
| +	_close_bdev(dev); |  | ||||||
| +	kfree(dev); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static int block2mtd_refresh(struct mtd_info *mtd) |  | ||||||
| +{ |  | ||||||
| +	struct block2mtd_dev *dev = mtd->priv; |  | ||||||
| +	struct block_device *bdev; |  | ||||||
| +	dev_t devt; |  | ||||||
| +	int err = 0; |  | ||||||
| + |  | ||||||
| +	/* no other mtd function can run at this point */ |  | ||||||
| +	write_lock(&dev->bdev_mutex); |  | ||||||
| + |  | ||||||
| +	/* get the device number for the whole disk */ |  | ||||||
| +	devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0); |  | ||||||
| + |  | ||||||
| +	/* close the old block device */ |  | ||||||
| +	_close_bdev(dev); |  | ||||||
| + |  | ||||||
| +	/* open the whole disk, issue a partition rescan, then */ |  | ||||||
| +	bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); |  | ||||||
| +	if (!bdev || !bdev->bd_disk) |  | ||||||
| +		err = -EINVAL; |  | ||||||
| +#ifndef CONFIG_MTD_BLOCK2MTD_MODULE |  | ||||||
| +	else |  | ||||||
| +		err = rescan_partitions(bdev->bd_disk, bdev); |  | ||||||
| +#endif |  | ||||||
| +	if (bdev) |  | ||||||
| +		close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); |  | ||||||
| + |  | ||||||
| +	/* try to open the partition block device again */ |  | ||||||
| +	_open_bdev(dev); |  | ||||||
| +	write_unlock(&dev->bdev_mutex); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +/* FIXME: ensure that mtd->size % erase_size == 0 */ |  | ||||||
| +static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname) |  | ||||||
| +{ |  | ||||||
| +	struct block2mtd_dev *dev; |  | ||||||
| +	struct mtd_partition *part; |  | ||||||
| +	char *name; |  | ||||||
| + |  | ||||||
| +	if (!devname) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL); |  | ||||||
| +	if (!dev) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	strcpy(dev->devname, devname); |  | ||||||
| + |  | ||||||
| +	if (_open_bdev(dev)) |  | ||||||
| +		goto devinit_err; |  | ||||||
| + |  | ||||||
|  	mutex_init(&dev->write_mutex); |  | ||||||
| +	rwlock_init(&dev->bdev_mutex); |  | ||||||
|   |  | ||||||
|  	if (!mtdname) |  | ||||||
|  		mtdname = devname; |  | ||||||
| @@ -297,6 +391,7 @@ static struct block2mtd_dev *add_device( |  | ||||||
|  	dev->mtd.read = block2mtd_read; |  | ||||||
|  	dev->mtd.priv = dev; |  | ||||||
|  	dev->mtd.owner = THIS_MODULE; |  | ||||||
| +	dev->mtd.refresh_device = block2mtd_refresh; |  | ||||||
|   |  | ||||||
|  	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); |  | ||||||
|  	part->name = dev->mtd.name; |  | ||||||
| --- a/drivers/mtd/mtdchar.c |  | ||||||
| +++ b/drivers/mtd/mtdchar.c |  | ||||||
| @@ -18,6 +18,7 @@ |  | ||||||
|   |  | ||||||
|  #include <linux/mtd/mtd.h> |  | ||||||
|  #include <linux/mtd/compatmac.h> |  | ||||||
| +#include <linux/mtd/partitions.h> |  | ||||||
|   |  | ||||||
|  #include <asm/uaccess.h> |  | ||||||
|   |  | ||||||
| @@ -814,6 +815,13 @@ static int mtd_ioctl(struct inode *inode |  | ||||||
|  		file->f_pos = 0; |  | ||||||
|  		break; |  | ||||||
|  	} |  | ||||||
| +#ifdef CONFIG_MTD_PARTITIONS |  | ||||||
| +	case MTDREFRESH: |  | ||||||
| +	{ |  | ||||||
| +		ret = refresh_mtd_partitions(mtd); |  | ||||||
| +		break; |  | ||||||
| +	} |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
|  	default: |  | ||||||
|  		ret = -ENOTTY; |  | ||||||
| --- a/include/linux/mtd/mtd.h |  | ||||||
| +++ b/include/linux/mtd/mtd.h |  | ||||||
| @@ -101,6 +101,7 @@ struct mtd_oob_ops { |  | ||||||
|  	uint8_t		*oobbuf; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +struct mtd_info; |  | ||||||
|  struct mtd_info { |  | ||||||
|  	u_char type; |  | ||||||
|  	uint32_t flags; |  | ||||||
| @@ -241,6 +242,9 @@ struct mtd_info { |  | ||||||
|  	struct device dev; |  | ||||||
|  	int usecount; |  | ||||||
|   |  | ||||||
| +	int (*refresh_device)(struct mtd_info *mtd); |  | ||||||
| +	struct mtd_info *split; |  | ||||||
| + |  | ||||||
|  	/* If the driver is something smart, like UBI, it may need to maintain |  | ||||||
|  	 * its own reference counting. The below functions are only for driver. |  | ||||||
|  	 * The driver may register its callbacks. These callbacks are not |  | ||||||
| --- a/include/linux/mtd/partitions.h |  | ||||||
| +++ b/include/linux/mtd/partitions.h |  | ||||||
| @@ -34,12 +34,14 @@ |  | ||||||
|   * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
| +struct mtd_partition; |  | ||||||
|  struct mtd_partition { |  | ||||||
|  	char *name;			/* identifier string */ |  | ||||||
|  	uint64_t size;			/* partition size */ |  | ||||||
|  	uint64_t offset;		/* offset within the master MTD space */ |  | ||||||
|  	uint32_t mask_flags;		/* master MTD flags to mask out for this partition */ |  | ||||||
|  	struct nand_ecclayout *ecclayout;	/* out of band layout for this partition (NAND only)*/ |  | ||||||
| +	int (*refresh_partition)(struct mtd_info *); |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  #define MTDPART_OFS_NXTBLK	(-2) |  | ||||||
| @@ -51,6 +53,7 @@ struct mtd_info; |  | ||||||
|   |  | ||||||
|  int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); |  | ||||||
|  int del_mtd_partitions(struct mtd_info *); |  | ||||||
| +int refresh_mtd_partitions(struct mtd_info *); |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * Functions dealing with the various ways of partitioning the space |  | ||||||
| --- a/include/mtd/mtd-abi.h |  | ||||||
| +++ b/include/mtd/mtd-abi.h |  | ||||||
| @@ -110,6 +110,7 @@ struct otp_info { |  | ||||||
|  #define MEMERASE64		_IOW('M', 20, struct erase_info_user64) |  | ||||||
|  #define MEMWRITEOOB64		_IOWR('M', 21, struct mtd_oob_buf64) |  | ||||||
|  #define MEMREADOOB64		_IOWR('M', 22, struct mtd_oob_buf64) |  | ||||||
| +#define MTDREFRESH		_IO('M', 50) |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * Obsolete legacy interface. Keep it in order not to break userspace |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/block2mtd.c |  | ||||||
| +++ b/drivers/mtd/devices/block2mtd.c |  | ||||||
| @@ -264,11 +264,13 @@ static int _open_bdev(struct block2mtd_d |  | ||||||
|  	bdev = open_bdev_exclusive(dev->devname, FMODE_READ|FMODE_WRITE, NULL); |  | ||||||
|  #ifndef MODULE |  | ||||||
|  	if (IS_ERR(bdev)) { |  | ||||||
| +		dev_t devt; |  | ||||||
|   |  | ||||||
|  		/* We might not have rootfs mounted at this point. Try |  | ||||||
|  		   to resolve the device name by other means. */ |  | ||||||
|   |  | ||||||
| -		dev_t devt = name_to_dev_t(dev->devname); |  | ||||||
| +		wait_for_device_probe(); |  | ||||||
| +		devt = name_to_dev_t(dev->devname); |  | ||||||
|  		if (devt) { |  | ||||||
|  			bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); |  | ||||||
|  		} |  | ||||||
| @@ -1,30 +0,0 @@ | |||||||
| --- a/drivers/mtd/redboot.c |  | ||||||
| +++ b/drivers/mtd/redboot.c |  | ||||||
| @@ -249,14 +249,21 @@ static int parse_redboot_partitions(stru |  | ||||||
|  #endif |  | ||||||
|  		names += strlen(names)+1; |  | ||||||
|   |  | ||||||
| -#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED |  | ||||||
|  		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { |  | ||||||
| -			i++; |  | ||||||
| -			parts[i].offset = parts[i-1].size + parts[i-1].offset; |  | ||||||
| -			parts[i].size = fl->next->img->flash_base - parts[i].offset; |  | ||||||
| -			parts[i].name = nullname; |  | ||||||
| -		} |  | ||||||
| +			if (!strcmp(parts[i].name, "rootfs")) { |  | ||||||
| +				parts[i].size = fl->next->img->flash_base; |  | ||||||
| +				parts[i].size &= ~(master->erasesize - 1); |  | ||||||
| +				parts[i].size -= parts[i].offset; |  | ||||||
| +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED |  | ||||||
| +				nrparts--; |  | ||||||
| +			} else { |  | ||||||
| +				i++; |  | ||||||
| +				parts[i].offset = parts[i-1].size + parts[i-1].offset; |  | ||||||
| +				parts[i].size = fl->next->img->flash_base - parts[i].offset; |  | ||||||
| +				parts[i].name = nullname; |  | ||||||
|  #endif |  | ||||||
| +			} |  | ||||||
| +		} |  | ||||||
|  		tmp_fl = fl; |  | ||||||
|  		fl = fl->next; |  | ||||||
|  		kfree(tmp_fl); |  | ||||||
| @@ -1,60 +0,0 @@ | |||||||
| --- a/drivers/mtd/redboot.c |  | ||||||
| +++ b/drivers/mtd/redboot.c |  | ||||||
| @@ -11,6 +11,8 @@ |  | ||||||
|  #include <linux/mtd/mtd.h> |  | ||||||
|  #include <linux/mtd/partitions.h> |  | ||||||
|   |  | ||||||
| +#define BOARD_CONFIG_PART		"boardconfig" |  | ||||||
| + |  | ||||||
|  struct fis_image_desc { |  | ||||||
|      unsigned char name[16];      // Null terminated name |  | ||||||
|      uint32_t	  flash_base;    // Address within FLASH of image |  | ||||||
| @@ -41,6 +43,7 @@ static int parse_redboot_partitions(stru |  | ||||||
|                               struct mtd_partition **pparts, |  | ||||||
|                               unsigned long fis_origin) |  | ||||||
|  { |  | ||||||
| +	unsigned long max_offset = 0; |  | ||||||
|  	int nrparts = 0; |  | ||||||
|  	struct fis_image_desc *buf; |  | ||||||
|  	struct mtd_partition *parts; |  | ||||||
| @@ -209,14 +212,14 @@ static int parse_redboot_partitions(stru |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
|  #endif |  | ||||||
| -	parts = kzalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL); |  | ||||||
| +	parts = kzalloc(sizeof(*parts) * (nrparts + 1) + nulllen + namelen + sizeof(BOARD_CONFIG_PART), GFP_KERNEL); |  | ||||||
|   |  | ||||||
|  	if (!parts) { |  | ||||||
|  		ret = -ENOMEM; |  | ||||||
|  		goto out; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	nullname = (char *)&parts[nrparts]; |  | ||||||
| +	nullname = (char *)&parts[nrparts + 1]; |  | ||||||
|  #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED |  | ||||||
|  	if (nulllen > 0) { |  | ||||||
|  		strcpy(nullname, nullstring); |  | ||||||
| @@ -235,6 +238,8 @@ static int parse_redboot_partitions(stru |  | ||||||
|  	} |  | ||||||
|  #endif |  | ||||||
|  	for ( ; i<nrparts; i++) { |  | ||||||
| +		if(max_offset < buf[i].flash_base + buf[i].size) |  | ||||||
| +			max_offset = buf[i].flash_base + buf[i].size; |  | ||||||
|  		parts[i].size = fl->img->size; |  | ||||||
|  		parts[i].offset = fl->img->flash_base; |  | ||||||
|  		parts[i].name = names; |  | ||||||
| @@ -268,6 +273,14 @@ static int parse_redboot_partitions(stru |  | ||||||
|  		fl = fl->next; |  | ||||||
|  		kfree(tmp_fl); |  | ||||||
|  	} |  | ||||||
| +	if(master->size - max_offset >= master->erasesize) |  | ||||||
| +	{ |  | ||||||
| +		parts[nrparts].size = master->size - max_offset; |  | ||||||
| +		parts[nrparts].offset = max_offset; |  | ||||||
| +		parts[nrparts].name = names; |  | ||||||
| +		strcpy(names, BOARD_CONFIG_PART); |  | ||||||
| +		nrparts++; |  | ||||||
| +	} |  | ||||||
|  	ret = nrparts; |  | ||||||
|  	*pparts = parts; |  | ||||||
|   out: |  | ||||||
| @@ -1,32 +0,0 @@ | |||||||
| --- a/include/linux/mtd/nand.h |  | ||||||
| +++ b/include/linux/mtd/nand.h |  | ||||||
| @@ -576,6 +576,7 @@ struct platform_nand_chip { |  | ||||||
|  	int			chip_delay; |  | ||||||
|  	unsigned int		options; |  | ||||||
|  	const char		**part_probe_types; |  | ||||||
| +	int			(*chip_fixup)(struct mtd_info *mtd); |  | ||||||
|  	void			(*set_parts)(uint64_t size, |  | ||||||
|  					struct platform_nand_chip *chip); |  | ||||||
|  	void			*priv; |  | ||||||
| --- a/drivers/mtd/nand/plat_nand.c |  | ||||||
| +++ b/drivers/mtd/nand/plat_nand.c |  | ||||||
| @@ -80,7 +80,18 @@ static int __devinit plat_nand_probe(str |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* Scan to find existance of the device */ |  | ||||||
| -	if (nand_scan(&data->mtd, 1)) { |  | ||||||
| +	if (nand_scan_ident(&data->mtd, 1)) { |  | ||||||
| +		res = -ENXIO; |  | ||||||
| +		goto out; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (pdata->chip.chip_fixup) { |  | ||||||
| +		res = pdata->chip.chip_fixup(&data->mtd); |  | ||||||
| +		if (res) |  | ||||||
| +			goto out; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (nand_scan_tail(&data->mtd)) { |  | ||||||
|  		res = -ENXIO; |  | ||||||
|  		goto out; |  | ||||||
|  	} |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| --- a/drivers/mtd/Kconfig |  | ||||||
| +++ b/drivers/mtd/Kconfig |  | ||||||
| @@ -181,6 +181,22 @@ config MTD_AR7_PARTS |  | ||||||
|  	---help--- |  | ||||||
|  	  TI AR7 partitioning support |  | ||||||
|   |  | ||||||
| +config MTD_MYLOADER_PARTS |  | ||||||
| +	tristate "MyLoader partition parsing" |  | ||||||
| +	depends on MTD_PARTITIONS && (ADM5120 || ATHEROS_AR231X || ATHEROS_AR71XX) |  | ||||||
| +	---help--- |  | ||||||
| +	  MyLoader is a bootloader which allows the user to define partitions |  | ||||||
| +	  in flash devices, by putting a table in the second erase block |  | ||||||
| +	  on the device, similar to a partition table. This table gives the  |  | ||||||
| +	  offsets and lengths of the user defined partitions. |  | ||||||
| + |  | ||||||
| +	  If you need code which can detect and parse these tables, and |  | ||||||
| +	  register MTD 'partitions' corresponding to each image detected, |  | ||||||
| +	  enable this option. |  | ||||||
| + |  | ||||||
| +	  You will still need the parsing functions to be called by the driver |  | ||||||
| +	  for your particular device. It won't happen automatically. |  | ||||||
| + |  | ||||||
|  comment "User Modules And Translation Layers" |  | ||||||
|   |  | ||||||
|  config MTD_CHAR |  | ||||||
| --- a/drivers/mtd/Makefile |  | ||||||
| +++ b/drivers/mtd/Makefile |  | ||||||
| @@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdli |  | ||||||
|  obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o |  | ||||||
|  obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o |  | ||||||
|  obj-$(CONFIG_MTD_OF_PARTS)      += ofpart.o |  | ||||||
| +obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o |  | ||||||
|   |  | ||||||
|  # 'Users' - code which presents functionality to userspace. |  | ||||||
|  obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| --- a/include/linux/mtd/partitions.h |  | ||||||
| +++ b/include/linux/mtd/partitions.h |  | ||||||
| @@ -33,6 +33,7 @@ |  | ||||||
|   * Note: writeable partitions require their size and offset be |  | ||||||
|   * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). |  | ||||||
|   */ |  | ||||||
| +struct mtd_info; |  | ||||||
|   |  | ||||||
|  struct mtd_partition; |  | ||||||
|  struct mtd_partition { |  | ||||||
| @@ -49,7 +50,6 @@ struct mtd_partition { |  | ||||||
|  #define MTDPART_SIZ_FULL	(0) |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -struct mtd_info; |  | ||||||
|   |  | ||||||
|  int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); |  | ||||||
|  int del_mtd_partitions(struct mtd_info *); |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| --- a/drivers/mtd/nand/nand_ecc.c |  | ||||||
| +++ b/drivers/mtd/nand/nand_ecc.c |  | ||||||
| @@ -492,8 +492,7 @@ int __nand_correct_data(unsigned char *b |  | ||||||
|  	if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1) |  | ||||||
|  		return 1;	/* error in ecc data; no action needed */ |  | ||||||
|   |  | ||||||
| -	printk(KERN_ERR "uncorrectable error : "); |  | ||||||
| -	return -1; |  | ||||||
| +	return -EBADMSG; |  | ||||||
|  } |  | ||||||
|  EXPORT_SYMBOL(__nand_correct_data); |  | ||||||
|   |  | ||||||
| @@ -1,39 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/m25p80.c |  | ||||||
| +++ b/drivers/mtd/devices/m25p80.c |  | ||||||
| @@ -42,6 +42,7 @@ |  | ||||||
|  #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */ |  | ||||||
|  #define	OPCODE_BE_32K		0x52	/* Erase 32KiB block */ |  | ||||||
|  #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */ |  | ||||||
| +#define	OPCODE_BE_4K_ALT	0xd7	/* Erase 4KiB block */ |  | ||||||
|  #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */ |  | ||||||
|  #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */ |  | ||||||
|   |  | ||||||
| @@ -599,6 +600,7 @@ struct flash_info { |  | ||||||
|   |  | ||||||
|  	u16		flags; |  | ||||||
|  #define	SECT_4K		0x01		/* OPCODE_BE_4K works uniformly */ |  | ||||||
| +#define	SECT_4K_ALT	0x02		/* OPCODE_BE_4K_ALT works uniformly */ |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -626,6 +628,10 @@ static struct flash_info __devinitdata m |  | ||||||
|  	{ "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, }, |  | ||||||
|  	{ "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, }, |  | ||||||
|   |  | ||||||
| +	/* PMC -- pm25x "blocks" are 32K, sectors are 4K */ |  | ||||||
| +	{ "pm25lv512", 0, 0, 32 * 1024, 2, SECT_4K_ALT }, |  | ||||||
| +	{ "pm25lv010", 0, 0, 32 * 1024, 4, SECT_4K_ALT }, |  | ||||||
| + |  | ||||||
|  	/* Spansion -- single (large) sector size only, at least |  | ||||||
|  	 * for the chips listed here (without boot sectors). |  | ||||||
|  	 */ |  | ||||||
| @@ -807,6 +813,9 @@ static int __devinit m25p_probe(struct s |  | ||||||
|  	if (info->flags & SECT_4K) { |  | ||||||
|  		flash->erase_opcode = OPCODE_BE_4K; |  | ||||||
|  		flash->mtd.erasesize = 4096; |  | ||||||
| +	} else if (info->flags & SECT_4K_ALT) { |  | ||||||
| +		flash->erase_opcode = OPCODE_BE_4K_ALT; |  | ||||||
| +		flash->mtd.erasesize = 4096; |  | ||||||
|  	} else { |  | ||||||
|  		flash->erase_opcode = OPCODE_SE; |  | ||||||
|  		flash->mtd.erasesize = info->sector_size; |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/m25p80.c |  | ||||||
| +++ b/drivers/mtd/devices/m25p80.c |  | ||||||
| @@ -628,6 +628,10 @@ static struct flash_info __devinitdata m |  | ||||||
|  	{ "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, }, |  | ||||||
|  	{ "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, }, |  | ||||||
|   |  | ||||||
| +	/* EON -- en25pxx */ |  | ||||||
| +	{ "en25p32", 0x1c2016, 0, 64 * 1024,  64, }, |  | ||||||
| +	{ "en25p64", 0x1c2017, 0, 64 * 1024, 128, }, |  | ||||||
| + |  | ||||||
|  	/* PMC -- pm25x "blocks" are 32K, sectors are 4K */ |  | ||||||
|  	{ "pm25lv512", 0, 0, 32 * 1024, 2, SECT_4K_ALT }, |  | ||||||
|  	{ "pm25lv010", 0, 0, 32 * 1024, 4, SECT_4K_ALT }, |  | ||||||
| @@ -1,29 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/m25p80.c |  | ||||||
| +++ b/drivers/mtd/devices/m25p80.c |  | ||||||
| @@ -632,6 +632,11 @@ static struct flash_info __devinitdata m |  | ||||||
|  	{ "en25p32", 0x1c2016, 0, 64 * 1024,  64, }, |  | ||||||
|  	{ "en25p64", 0x1c2017, 0, 64 * 1024, 128, }, |  | ||||||
|   |  | ||||||
| +	/* Numonyx -- xxxs33b */ |  | ||||||
| +	{ "160s33b",  0x898911, 0, 64 * 1024,  32, }, |  | ||||||
| +	{ "320s33b",  0x898912, 0, 64 * 1024,  64, }, |  | ||||||
| +	{ "640s33b",  0x898913, 0, 64 * 1024, 128, }, |  | ||||||
| + |  | ||||||
|  	/* PMC -- pm25x "blocks" are 32K, sectors are 4K */ |  | ||||||
|  	{ "pm25lv512", 0, 0, 32 * 1024, 2, SECT_4K_ALT }, |  | ||||||
|  	{ "pm25lv010", 0, 0, 32 * 1024, 4, SECT_4K_ALT }, |  | ||||||
| @@ -786,11 +791,12 @@ static int __devinit m25p_probe(struct s |  | ||||||
|  	dev_set_drvdata(&spi->dev, flash); |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
| -	 * Atmel serial flash tend to power up |  | ||||||
| +	 * Atmel and Intel/Numonyx serial flash tend to power up |  | ||||||
|  	 * with the software protection bits set |  | ||||||
|  	 */ |  | ||||||
|   |  | ||||||
| -	if (info->jedec_id >> 16 == 0x1f) { |  | ||||||
| +	if (info->jedec_id >> 16 == 0x1f || |  | ||||||
| +	    info->jedec_id >> 16 == 0x89) { |  | ||||||
|  		write_enable(flash); |  | ||||||
|  		write_sr(flash, 0); |  | ||||||
|  	} |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/m25p80.c |  | ||||||
| +++ b/drivers/mtd/devices/m25p80.c |  | ||||||
| @@ -689,6 +689,7 @@ static struct flash_info __devinitdata m |  | ||||||
|  	{ "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, }, |  | ||||||
|  	{ "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, }, |  | ||||||
|  	{ "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, }, |  | ||||||
| +	{ "w25q32", 0xef4016, 0, 64 * 1024, 64, SECT_4K, }, |  | ||||||
|  	{ "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, }, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| --- a/drivers/mtd/chips/gen_probe.c |  | ||||||
| +++ b/drivers/mtd/chips/gen_probe.c |  | ||||||
| @@ -249,6 +249,7 @@ static struct mtd_info *check_cmd_set(st |  | ||||||
|  #endif |  | ||||||
|  #ifdef CONFIG_MTD_CFI_AMDSTD |  | ||||||
|  	case 0x0002: |  | ||||||
| +	case 0x0006: |  | ||||||
|  		return cfi_cmdset_0002(map, primary); |  | ||||||
|  #endif |  | ||||||
|  #ifdef CONFIG_MTD_CFI_STAA |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| --- a/drivers/mtd/chips/cfi_cmdset_0002.c |  | ||||||
| +++ b/drivers/mtd/chips/cfi_cmdset_0002.c |  | ||||||
| @@ -327,9 +327,32 @@ static void cfi_fixup_major_minor(struct |  | ||||||
|  { |  | ||||||
|  	// manufacturers defined in include/linux/mtd/cfi.h |  | ||||||
|   |  | ||||||
| -	if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e && |  | ||||||
| -	    extp->MajorVersion == '0') |  | ||||||
| +	if (cfi->mfr == CFI_MFR_SAMSUNG && |  | ||||||
| +	    extp->MajorVersion == '0') { |  | ||||||
| +		printk("  Fixed Samsung's Amd/Fujitsu Extended Query version from %c.%c", |  | ||||||
| +		       extp->MajorVersion, extp->MinorVersion); |  | ||||||
| + |  | ||||||
|  		extp->MajorVersion = '1'; |  | ||||||
| +		extp->MinorVersion = '0'; |  | ||||||
| + |  | ||||||
| +		printk(" to %c.%c.\n", |  | ||||||
| +		       extp->MajorVersion, extp->MinorVersion); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (cfi->mfr == CFI_MFR_SAMSUNG && |  | ||||||
| +	    extp->MajorVersion == '3' && extp->MinorVersion == '3') { |  | ||||||
| +		printk(KERN_NOTICE "  Newer Samsung flash detected, " |  | ||||||
| +		       "should be compatibile with Amd/Fujitsu.\n"); |  | ||||||
| + |  | ||||||
| +		printk("  Fixed Samsung's Amd/Fujitsu Extended Query version from %c.%c", |  | ||||||
| +		       extp->MajorVersion, extp->MinorVersion); |  | ||||||
| + |  | ||||||
| +		extp->MajorVersion = '1';	// set to 1.3 (last defined version) |  | ||||||
| +		extp->MinorVersion = '3'; |  | ||||||
| + |  | ||||||
| +		printk(" to %c.%c.\n", |  | ||||||
| +		       extp->MajorVersion, extp->MinorVersion); |  | ||||||
| +	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| --- a/drivers/mtd/devices/m25p80.c |  | ||||||
| +++ b/drivers/mtd/devices/m25p80.c |  | ||||||
| @@ -628,7 +628,8 @@ static struct flash_info __devinitdata m |  | ||||||
|  	{ "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, }, |  | ||||||
|  	{ "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, }, |  | ||||||
|   |  | ||||||
| -	/* EON -- en25pxx */ |  | ||||||
| +	/* EON -- en25xxx */ |  | ||||||
| +	{ "en25f32", 0x1c3116, 0, 64 * 1024,  64, SECT_4K }, |  | ||||||
|  	{ "en25p32", 0x1c2016, 0, 64 * 1024,  64, }, |  | ||||||
|  	{ "en25p64", 0x1c2017, 0, 64 * 1024, 128, }, |  | ||||||
|   |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,108 +0,0 @@ | |||||||
| --- a/include/linux/netfilter/xt_layer7.h |  | ||||||
| +++ b/include/linux/netfilter/xt_layer7.h |  | ||||||
| @@ -8,6 +8,7 @@ struct xt_layer7_info { |  | ||||||
|      char protocol[MAX_PROTOCOL_LEN]; |  | ||||||
|      char pattern[MAX_PATTERN_LEN]; |  | ||||||
|      u_int8_t invert; |  | ||||||
| +    u_int8_t pkt; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  #endif /* _XT_LAYER7_H */ |  | ||||||
| --- a/net/netfilter/xt_layer7.c |  | ||||||
| +++ b/net/netfilter/xt_layer7.c |  | ||||||
| @@ -314,33 +314,35 @@ static int match_no_append(struct nf_con |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* add the new app data to the conntrack.  Return number of bytes added. */ |  | ||||||
| -static int add_data(struct nf_conn * master_conntrack, |  | ||||||
| -                    char * app_data, int appdatalen) |  | ||||||
| +static int add_datastr(char *target, int offset, char *app_data, int len) |  | ||||||
|  { |  | ||||||
|  	int length = 0, i; |  | ||||||
| -	int oldlength = master_conntrack->layer7.app_data_len; |  | ||||||
| - |  | ||||||
| -	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  |  | ||||||
| -	   clear on whether the race condition exists or whether this really  |  | ||||||
| -	   fixes it.  I might just be being dense... Anyway, if it's not really  |  | ||||||
| -	   a fix, all it does is waste a very small amount of time. */ |  | ||||||
| -	if(!master_conntrack->layer7.app_data) return 0; |  | ||||||
| +	if (!target) return 0; |  | ||||||
|   |  | ||||||
|  	/* Strip nulls. Make everything lower case (our regex lib doesn't |  | ||||||
|  	do case insensitivity).  Add it to the end of the current data. */ |  | ||||||
| -	for(i = 0; i < maxdatalen-oldlength-1 && |  | ||||||
| -		   i < appdatalen; i++) { |  | ||||||
| + 	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { |  | ||||||
|  		if(app_data[i] != '\0') { |  | ||||||
|  			/* the kernel version of tolower mungs 'upper ascii' */ |  | ||||||
| -			master_conntrack->layer7.app_data[length+oldlength] = |  | ||||||
| +			target[length+offset] = |  | ||||||
|  				isascii(app_data[i])?  |  | ||||||
|  					tolower(app_data[i]) : app_data[i]; |  | ||||||
|  			length++; |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
| +	target[length+offset] = '\0'; |  | ||||||
| + |  | ||||||
| +	return length; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +/* add the new app data to the conntrack.  Return number of bytes added. */ |  | ||||||
| +static int add_data(struct nf_conn * master_conntrack, |  | ||||||
| +                    char * app_data, int appdatalen) |  | ||||||
| +{ |  | ||||||
| +	int length; |  | ||||||
|   |  | ||||||
| -	master_conntrack->layer7.app_data[length+oldlength] = '\0'; |  | ||||||
| -	master_conntrack->layer7.app_data_len = length + oldlength; |  | ||||||
| +	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); |  | ||||||
| +	master_conntrack->layer7.app_data_len += length; |  | ||||||
|   |  | ||||||
|  	return length; |  | ||||||
|  } |  | ||||||
| @@ -438,7 +440,7 @@ match(const struct sk_buff *skbin, |  | ||||||
|   |  | ||||||
|  	enum ip_conntrack_info master_ctinfo, ctinfo; |  | ||||||
|  	struct nf_conn *master_conntrack, *conntrack; |  | ||||||
| -	unsigned char * app_data; |  | ||||||
| +	unsigned char *app_data, *tmp_data; |  | ||||||
|  	unsigned int pattern_result, appdatalen; |  | ||||||
|  	regexp * comppattern; |  | ||||||
|   |  | ||||||
| @@ -466,8 +468,8 @@ match(const struct sk_buff *skbin, |  | ||||||
|  		master_conntrack = master_ct(master_conntrack); |  | ||||||
|   |  | ||||||
|  	/* if we've classified it or seen too many packets */ |  | ||||||
| -	if(total_acct_packets(master_conntrack) > num_packets || |  | ||||||
| -	   master_conntrack->layer7.app_proto) { |  | ||||||
| +	if(!info->pkt && (total_acct_packets(master_conntrack) > num_packets || |  | ||||||
| +	   master_conntrack->layer7.app_proto)) { |  | ||||||
|   |  | ||||||
|  		pattern_result = match_no_append(conntrack, master_conntrack,  |  | ||||||
|  						 ctinfo, master_ctinfo, info); |  | ||||||
| @@ -500,6 +502,25 @@ match(const struct sk_buff *skbin, |  | ||||||
|  	/* the return value gets checked later, when we're ready to use it */ |  | ||||||
|  	comppattern = compile_and_cache(info->pattern, info->protocol); |  | ||||||
|   |  | ||||||
| +	if (info->pkt) { |  | ||||||
| +		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); |  | ||||||
| +		if(!tmp_data){ |  | ||||||
| +			if (net_ratelimit()) |  | ||||||
| +				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); |  | ||||||
| +			return info->invert; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		tmp_data[0] = '\0'; |  | ||||||
| +		add_datastr(tmp_data, 0, app_data, appdatalen); |  | ||||||
| +		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); |  | ||||||
| + |  | ||||||
| +		kfree(tmp_data); |  | ||||||
| +		tmp_data = NULL; |  | ||||||
| +		spin_unlock_bh(&l7_lock); |  | ||||||
| + |  | ||||||
| +		return (pattern_result ^ info->invert); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* On the first packet of a connection, allocate space for app data */ |  | ||||||
|  	if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] &&  |  | ||||||
|  	   !master_conntrack->layer7.app_data){ |  | ||||||
| @@ -1,144 +0,0 @@ | |||||||
| --- a/include/linux/netfilter_ipv4/ip_tables.h |  | ||||||
| +++ b/include/linux/netfilter_ipv4/ip_tables.h |  | ||||||
| @@ -62,6 +62,7 @@ struct ipt_ip { |  | ||||||
|  #define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */ |  | ||||||
|  #define IPT_F_GOTO		0x02	/* Set if jump is a goto */ |  | ||||||
|  #define IPT_F_MASK		0x03	/* All possible flag bits mask. */ |  | ||||||
| +#define IPT_F_NO_DEF_MATCH	0x80	/* Internal: no default match rules present */ |  | ||||||
|   |  | ||||||
|  /* Values for "inv" field in struct ipt_ip. */ |  | ||||||
|  #define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */ |  | ||||||
| --- a/net/ipv4/netfilter/ip_tables.c |  | ||||||
| +++ b/net/ipv4/netfilter/ip_tables.c |  | ||||||
| @@ -88,6 +88,9 @@ ip_packet_match(const struct iphdr *ip, |  | ||||||
|   |  | ||||||
|  #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg))) |  | ||||||
|   |  | ||||||
| +	if (ipinfo->flags & IPT_F_NO_DEF_MATCH) |  | ||||||
| +		return true; |  | ||||||
| + |  | ||||||
|  	if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr, |  | ||||||
|  		  IPT_INV_SRCIP) |  | ||||||
|  	    || FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr, |  | ||||||
| @@ -138,13 +141,35 @@ ip_packet_match(const struct iphdr *ip, |  | ||||||
|  		return false; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +#undef FWINV |  | ||||||
|  	return true; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static bool |  | ||||||
| -ip_checkentry(const struct ipt_ip *ip) |  | ||||||
| +ip_checkentry(struct ipt_ip *ip) |  | ||||||
|  { |  | ||||||
| -	if (ip->flags & ~IPT_F_MASK) { |  | ||||||
| +#define FWINV(bool, invflg) ((bool) || (ip->invflags & (invflg))) |  | ||||||
| + |  | ||||||
| +	if (FWINV(ip->smsk.s_addr, IPT_INV_SRCIP) || |  | ||||||
| +		FWINV(ip->dmsk.s_addr, IPT_INV_DSTIP)) |  | ||||||
| +		goto has_match_rules; |  | ||||||
| + |  | ||||||
| +	if (FWINV(!!((const unsigned long *)ip->iniface_mask)[0], |  | ||||||
| +		IPT_INV_VIA_IN) || |  | ||||||
| +	    FWINV(!!((const unsigned long *)ip->outiface_mask)[0], |  | ||||||
| +		IPT_INV_VIA_OUT)) |  | ||||||
| +		goto has_match_rules; |  | ||||||
| + |  | ||||||
| +	if (FWINV(ip->proto, IPT_INV_PROTO)) |  | ||||||
| +		goto has_match_rules; |  | ||||||
| + |  | ||||||
| +	if (FWINV(ip->flags&IPT_F_FRAG, IPT_INV_FRAG)) |  | ||||||
| +		goto has_match_rules; |  | ||||||
| + |  | ||||||
| +	ip->flags |= IPT_F_NO_DEF_MATCH; |  | ||||||
| + |  | ||||||
| +has_match_rules: |  | ||||||
| +	if (ip->flags & ~(IPT_F_MASK|IPT_F_NO_DEF_MATCH)) { |  | ||||||
|  		duprintf("Unknown flag bits set: %08X\n", |  | ||||||
|  			 ip->flags & ~IPT_F_MASK); |  | ||||||
|  		return false; |  | ||||||
| @@ -154,6 +179,8 @@ ip_checkentry(const struct ipt_ip *ip) |  | ||||||
|  			 ip->invflags & ~IPT_INV_MASK); |  | ||||||
|  		return false; |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +#undef FWINV |  | ||||||
|  	return true; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -196,7 +223,6 @@ static inline bool unconditional(const s |  | ||||||
|  	static const struct ipt_ip uncond; |  | ||||||
|   |  | ||||||
|  	return memcmp(ip, &uncond, sizeof(uncond)) == 0; |  | ||||||
| -#undef FWINV |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ |  | ||||||
| @@ -321,8 +347,28 @@ ipt_do_table(struct sk_buff *skb, |  | ||||||
|  	struct xt_match_param mtpar; |  | ||||||
|  	struct xt_target_param tgpar; |  | ||||||
|   |  | ||||||
| -	/* Initialization */ |  | ||||||
|  	ip = ip_hdr(skb); |  | ||||||
| + |  | ||||||
| +	IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |  | ||||||
| +	xt_info_rdlock_bh(); |  | ||||||
| +	private = table->private; |  | ||||||
| +	table_base = private->entries[smp_processor_id()]; |  | ||||||
| +	e = get_entry(table_base, private->hook_entry[hook]); |  | ||||||
| + |  | ||||||
| +	if (e->target_offset <= sizeof(struct ipt_entry) && |  | ||||||
| +		(e->ip.flags & IPT_F_NO_DEF_MATCH)) { |  | ||||||
| +			struct ipt_entry_target *t = ipt_get_target(e); |  | ||||||
| +			if (!t->u.kernel.target->target) { |  | ||||||
| +				int v = ((struct ipt_standard_target *)t)->verdict; |  | ||||||
| +				if ((v < 0) && (v != IPT_RETURN)) { |  | ||||||
| +					ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |  | ||||||
| +					xt_info_rdunlock_bh(); |  | ||||||
| +					return (unsigned)(-v) - 1; |  | ||||||
| +				} |  | ||||||
| +			} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	/* Initialization */ |  | ||||||
|  	indev = in ? in->name : nulldevname; |  | ||||||
|  	outdev = out ? out->name : nulldevname; |  | ||||||
|  	/* We handle fragments by dealing with the first fragment as |  | ||||||
| @@ -339,13 +385,6 @@ ipt_do_table(struct sk_buff *skb, |  | ||||||
|  	mtpar.family  = tgpar.family = NFPROTO_IPV4; |  | ||||||
|  	mtpar.hooknum = tgpar.hooknum = hook; |  | ||||||
|   |  | ||||||
| -	IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |  | ||||||
| -	xt_info_rdlock_bh(); |  | ||||||
| -	private = table->private; |  | ||||||
| -	table_base = private->entries[smp_processor_id()]; |  | ||||||
| - |  | ||||||
| -	e = get_entry(table_base, private->hook_entry[hook]); |  | ||||||
| - |  | ||||||
|  	/* For return from builtin chain */ |  | ||||||
|  	back = get_entry(table_base, private->underflow[hook]); |  | ||||||
|   |  | ||||||
| @@ -992,6 +1031,7 @@ copy_entries_to_user(unsigned int total_ |  | ||||||
|  		unsigned int i; |  | ||||||
|  		const struct ipt_entry_match *m; |  | ||||||
|  		const struct ipt_entry_target *t; |  | ||||||
| +		u8 flags; |  | ||||||
|   |  | ||||||
|  		e = (struct ipt_entry *)(loc_cpu_entry + off); |  | ||||||
|  		if (copy_to_user(userptr + off |  | ||||||
| @@ -1001,6 +1041,14 @@ copy_entries_to_user(unsigned int total_ |  | ||||||
|  			ret = -EFAULT; |  | ||||||
|  			goto free_counters; |  | ||||||
|  		} |  | ||||||
| + |  | ||||||
| +		flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH; |  | ||||||
| +		if (copy_to_user(userptr + off |  | ||||||
| +				 + offsetof(struct ipt_entry, ip.flags), |  | ||||||
| +				 &flags, sizeof(flags)) != 0) { |  | ||||||
| +			ret = -EFAULT; |  | ||||||
| +			goto free_counters; |  | ||||||
| +		} |  | ||||||
|   |  | ||||||
|  		for (i = sizeof(struct ipt_entry); |  | ||||||
|  		     i < e->target_offset; |  | ||||||
| @@ -1,71 +0,0 @@ | |||||||
| --- a/include/linux/netfilter/xt_recent.h |  | ||||||
| +++ b/include/linux/netfilter/xt_recent.h |  | ||||||
| @@ -9,6 +9,7 @@ enum { |  | ||||||
|  	XT_RECENT_UPDATE   = 1 << 2, |  | ||||||
|  	XT_RECENT_REMOVE   = 1 << 3, |  | ||||||
|  	XT_RECENT_TTL      = 1 << 4, |  | ||||||
| +	XT_RECENT_REAP     = 1 << 5, |  | ||||||
|   |  | ||||||
|  	XT_RECENT_SOURCE   = 0, |  | ||||||
|  	XT_RECENT_DEST     = 1, |  | ||||||
| @@ -16,6 +17,9 @@ enum { |  | ||||||
|  	XT_RECENT_NAME_LEN = 200, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +/* Only allowed with --rcheck and --update */ |  | ||||||
| +#define XT_RECENT_MODIFIERS (XT_RECENT_TTL|XT_RECENT_REAP) |  | ||||||
| + |  | ||||||
|  struct xt_recent_mtinfo { |  | ||||||
|  	__u32 seconds; |  | ||||||
|  	__u32 hit_count; |  | ||||||
| --- a/net/netfilter/xt_recent.c |  | ||||||
| +++ b/net/netfilter/xt_recent.c |  | ||||||
| @@ -142,6 +142,25 @@ static void recent_entry_remove(struct r |  | ||||||
|  	t->entries--; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +/* |  | ||||||
| + * Drop entries with timestamps older then 'time'. |  | ||||||
| + */ |  | ||||||
| +static void recent_entry_reap(struct recent_table *t, unsigned long time) |  | ||||||
| +{ |  | ||||||
| +	struct recent_entry *e; |  | ||||||
| + |  | ||||||
| +	/* |  | ||||||
| +	 * The head of the LRU list is always the oldest entry. |  | ||||||
| +	 */ |  | ||||||
| +	e = list_entry(t->lru_list.next, struct recent_entry, lru_list); |  | ||||||
| + |  | ||||||
| +	/* |  | ||||||
| +	 * The last time stamp is the most recent. |  | ||||||
| +	 */ |  | ||||||
| +	if (time_after(time, e->stamps[e->index-1])) |  | ||||||
| +		recent_entry_remove(t, e); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static struct recent_entry * |  | ||||||
|  recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr, |  | ||||||
|  		  u_int16_t family, u_int8_t ttl) |  | ||||||
| @@ -265,6 +284,10 @@ recent_mt(const struct sk_buff *skb, con |  | ||||||
|  				break; |  | ||||||
|  			} |  | ||||||
|  		} |  | ||||||
| + |  | ||||||
| +		/* info->seconds must be non-zero */ |  | ||||||
| +		if (info->check_set & XT_RECENT_REAP) |  | ||||||
| +			recent_entry_reap(t, time); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (info->check_set & XT_RECENT_SET || |  | ||||||
| @@ -292,7 +315,10 @@ static bool recent_mt_check(const struct |  | ||||||
|  		      XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1) |  | ||||||
|  		return false; |  | ||||||
|  	if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) && |  | ||||||
| -	    (info->seconds || info->hit_count)) |  | ||||||
| +	    (info->seconds || info->hit_count || |  | ||||||
| +	    (info->check_set & XT_RECENT_MODIFIERS))) |  | ||||||
| +		return false; |  | ||||||
| +	if ((info->check_set & XT_RECENT_REAP) && !info->seconds) |  | ||||||
|  		return false; |  | ||||||
|  	if (info->hit_count > ip_pkt_list_tot) |  | ||||||
|  		return false; |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| From: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp> |  | ||||||
| Date: Tue, 10 May 2011 08:00:21 +0000 (+0200) |  | ||||||
| Subject: netfilter: IPv6: fix DSCP mangle code |  | ||||||
| X-Git-Tag: v2.6.39~15^2~13^2~1 |  | ||||||
| X-Git-Url: http://git390.marist.edu/cgi-bin/gitweb.cgi?p=linux-2.6.git;a=commitdiff_plain;h=1ed2f73d90fb49bcf5704aee7e9084adb882bfc5 |  | ||||||
|  |  | ||||||
| netfilter: IPv6: fix DSCP mangle code |  | ||||||
|  |  | ||||||
| The mask indicates the bits one wants to zero out, so it needs to be |  | ||||||
| inverted before applying to the original TOS field. |  | ||||||
|  |  | ||||||
| Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp> |  | ||||||
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/netfilter/xt_DSCP.c |  | ||||||
| +++ b/net/netfilter/xt_DSCP.c |  | ||||||
| @@ -99,7 +99,7 @@ tos_tg6(struct sk_buff *skb, const struc |  | ||||||
|  	u_int8_t orig, nv; |  | ||||||
|   |  | ||||||
|  	orig = ipv6_get_dsfield(iph); |  | ||||||
| -	nv   = (orig & info->tos_mask) ^ info->tos_value; |  | ||||||
| +	nv   = (orig & ~info->tos_mask) ^ info->tos_value; |  | ||||||
|   |  | ||||||
|  	if (orig != nv) { |  | ||||||
|  		if (!skb_make_writable(skb, sizeof(struct iphdr))) |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| --- a/net/netfilter/Kconfig |  | ||||||
| +++ b/net/netfilter/Kconfig |  | ||||||
| @@ -160,7 +160,6 @@ config NF_CONNTRACK_FTP |  | ||||||
|   |  | ||||||
|  config NF_CONNTRACK_H323 |  | ||||||
|  	tristate "H.323 protocol support" |  | ||||||
| -	depends on (IPV6 || IPV6=n) |  | ||||||
|  	depends on NETFILTER_ADVANCED |  | ||||||
|  	help |  | ||||||
|  	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most |  | ||||||
| @@ -493,7 +492,6 @@ config NETFILTER_XT_TARGET_SECMARK |  | ||||||
|   |  | ||||||
|  config NETFILTER_XT_TARGET_TCPMSS |  | ||||||
|  	tristate '"TCPMSS" target support' |  | ||||||
| -	depends on (IPV6 || IPV6=n) |  | ||||||
|  	default m if NETFILTER_ADVANCED=n |  | ||||||
|  	---help--- |  | ||||||
|  	  This option adds a `TCPMSS' target, which allows you to alter the |  | ||||||
| @@ -1,795 +0,0 @@ | |||||||
| --- a/include/linux/pkt_sched.h |  | ||||||
| +++ b/include/linux/pkt_sched.h |  | ||||||
| @@ -182,8 +182,37 @@ struct tc_sfq_xstats |  | ||||||
|   * |  | ||||||
|   *	The only reason for this is efficiency, it is possible |  | ||||||
|   *	to change these parameters in compile time. |  | ||||||
| + * |  | ||||||
| + *	If you need to play with these values, use esfq instead. |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
| +/* ESFQ section */ |  | ||||||
| + |  | ||||||
| +enum |  | ||||||
| +{ |  | ||||||
| +        /* traditional */ |  | ||||||
| +	TCA_SFQ_HASH_CLASSIC, |  | ||||||
| +	TCA_SFQ_HASH_DST, |  | ||||||
| +	TCA_SFQ_HASH_SRC, |  | ||||||
| +	TCA_SFQ_HASH_FWMARK, |  | ||||||
| +	/* conntrack */ |  | ||||||
| +	TCA_SFQ_HASH_CTORIGDST, |  | ||||||
| +	TCA_SFQ_HASH_CTORIGSRC, |  | ||||||
| +	TCA_SFQ_HASH_CTREPLDST, |  | ||||||
| +	TCA_SFQ_HASH_CTREPLSRC, |  | ||||||
| +	TCA_SFQ_HASH_CTNATCHG, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +struct tc_esfq_qopt |  | ||||||
| +{ |  | ||||||
| +	unsigned	quantum;	/* Bytes per round allocated to flow */ |  | ||||||
| +	int		perturb_period;	/* Period of hash perturbation */ |  | ||||||
| +	__u32		limit;		/* Maximal packets in queue */ |  | ||||||
| +	unsigned	divisor;	/* Hash divisor  */ |  | ||||||
| +	unsigned	flows;		/* Maximal number of flows  */ |  | ||||||
| +	unsigned	hash_kind;	/* Hash function to use for flow identification */ |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
|  /* RED section */ |  | ||||||
|   |  | ||||||
|  enum |  | ||||||
| --- a/net/sched/Kconfig |  | ||||||
| +++ b/net/sched/Kconfig |  | ||||||
| @@ -137,6 +137,37 @@ config NET_SCH_SFQ |  | ||||||
|  	  To compile this code as a module, choose M here: the |  | ||||||
|  	  module will be called sch_sfq. |  | ||||||
|   |  | ||||||
| +config NET_SCH_ESFQ |  | ||||||
| +	tristate "Enhanced Stochastic Fairness Queueing (ESFQ)" |  | ||||||
| +	---help--- |  | ||||||
| +	  Say Y here if you want to use the Enhanced Stochastic Fairness |  | ||||||
| +	  Queueing (ESFQ) packet scheduling algorithm for some of your network |  | ||||||
| +	  devices or as a leaf discipline for a classful qdisc such as HTB or |  | ||||||
| +	  CBQ (see the top of <file:net/sched/sch_esfq.c> for details and |  | ||||||
| +	  references to the SFQ algorithm). |  | ||||||
| + |  | ||||||
| +	  This is an enchanced SFQ version which allows you to control some |  | ||||||
| +	  hardcoded values in the SFQ scheduler. |  | ||||||
| + |  | ||||||
| +	  ESFQ also adds control of the hash function used to identify packet |  | ||||||
| +	  flows. The original SFQ discipline hashes by connection; ESFQ add |  | ||||||
| +	  several other hashing methods, such as by src IP or by dst IP, which |  | ||||||
| +	  can be more fair to users in some networking situations. |  | ||||||
| + |  | ||||||
| +	  To compile this code as a module, choose M here: the |  | ||||||
| +	  module will be called sch_esfq. |  | ||||||
| + |  | ||||||
| +config NET_SCH_ESFQ_NFCT |  | ||||||
| +	bool "Connection Tracking Hash Types" |  | ||||||
| +	depends on NET_SCH_ESFQ && NF_CONNTRACK |  | ||||||
| +	---help--- |  | ||||||
| +	  Say Y here to enable support for hashing based on netfilter connection |  | ||||||
| +	  tracking information. This is useful for a router that is also using |  | ||||||
| +	  NAT to connect privately-addressed hosts to the Internet. If you want |  | ||||||
| +	  to provide fair distribution of upstream bandwidth, ESFQ must use |  | ||||||
| +	  connection tracking information, since all outgoing packets will share |  | ||||||
| +	  the same source address. |  | ||||||
| + |  | ||||||
|  config NET_SCH_TEQL |  | ||||||
|  	tristate "True Link Equalizer (TEQL)" |  | ||||||
|  	---help--- |  | ||||||
| --- a/net/sched/Makefile |  | ||||||
| +++ b/net/sched/Makefile |  | ||||||
| @@ -24,6 +24,7 @@ obj-$(CONFIG_NET_SCH_GRED)	+= sch_gred.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_INGRESS)	+= sch_ingress.o  |  | ||||||
|  obj-$(CONFIG_NET_SCH_DSMARK)	+= sch_dsmark.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_SFQ)	+= sch_sfq.o |  | ||||||
| +obj-$(CONFIG_NET_SCH_ESFQ)	+= sch_esfq.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_TBF)	+= sch_tbf.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_TEQL)	+= sch_teql.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_PRIO)	+= sch_prio.o |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/net/sched/sch_esfq.c |  | ||||||
| @@ -0,0 +1,702 @@ |  | ||||||
| +/* |  | ||||||
| + * net/sched/sch_esfq.c	Extended Stochastic Fairness Queueing discipline. |  | ||||||
| + * |  | ||||||
| + *		This program is free software; you can redistribute it and/or |  | ||||||
| + *		modify it under the terms of the GNU General Public License |  | ||||||
| + *		as published by the Free Software Foundation; either version |  | ||||||
| + *		2 of the License, or (at your option) any later version. |  | ||||||
| + * |  | ||||||
| + * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |  | ||||||
| + * |  | ||||||
| + * Changes:	Alexander Atanasov, <alex@ssi.bg> |  | ||||||
| + *		Added dynamic depth,limit,divisor,hash_kind options. |  | ||||||
| + *		Added dst and src hashes. |  | ||||||
| + * |  | ||||||
| + * 		Alexander Clouter, <alex@digriz.org.uk> |  | ||||||
| + *		Ported ESFQ to Linux 2.6. |  | ||||||
| + * |  | ||||||
| + * 		Corey Hickey, <bugfood-c@fatooh.org> |  | ||||||
| + *		Maintenance of the Linux 2.6 port. |  | ||||||
| + *		Added fwmark hash (thanks to Robert Kurjata). |  | ||||||
| + *		Added usage of jhash. |  | ||||||
| + *		Added conntrack support. |  | ||||||
| + *		Added ctnatchg hash (thanks to Ben Pfountz). |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#include <asm/uaccess.h> |  | ||||||
| +#include <asm/system.h> |  | ||||||
| +#include <linux/bitops.h> |  | ||||||
| +#include <linux/types.h> |  | ||||||
| +#include <linux/kernel.h> |  | ||||||
| +#include <linux/jiffies.h> |  | ||||||
| +#include <linux/string.h> |  | ||||||
| +#include <linux/mm.h> |  | ||||||
| +#include <linux/socket.h> |  | ||||||
| +#include <linux/sockios.h> |  | ||||||
| +#include <linux/in.h> |  | ||||||
| +#include <linux/errno.h> |  | ||||||
| +#include <linux/interrupt.h> |  | ||||||
| +#include <linux/if_ether.h> |  | ||||||
| +#include <linux/inet.h> |  | ||||||
| +#include <linux/netdevice.h> |  | ||||||
| +#include <linux/etherdevice.h> |  | ||||||
| +#include <linux/notifier.h> |  | ||||||
| +#include <linux/init.h> |  | ||||||
| +#include <net/ip.h> |  | ||||||
| +#include <net/netlink.h> |  | ||||||
| +#include <linux/ipv6.h> |  | ||||||
| +#include <net/route.h> |  | ||||||
| +#include <linux/skbuff.h> |  | ||||||
| +#include <net/sock.h> |  | ||||||
| +#include <net/pkt_sched.h> |  | ||||||
| +#include <linux/jhash.h> |  | ||||||
| +#ifdef CONFIG_NET_SCH_ESFQ_NFCT |  | ||||||
| +#include <net/netfilter/nf_conntrack.h> |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +/*	Stochastic Fairness Queuing algorithm. |  | ||||||
| +	For more comments look at sch_sfq.c. |  | ||||||
| +	The difference is that you can change limit, depth, |  | ||||||
| +	hash table size and choose alternate hash types. |  | ||||||
| + |  | ||||||
| +	classic:	same as in sch_sfq.c |  | ||||||
| +	dst:		destination IP address |  | ||||||
| +	src:		source IP address |  | ||||||
| +	fwmark:		netfilter mark value |  | ||||||
| +	ctorigdst:	original destination IP address |  | ||||||
| +	ctorigsrc:	original source IP address |  | ||||||
| +	ctrepldst:	reply destination IP address |  | ||||||
| +	ctreplsrc:	reply source IP |  | ||||||
| + |  | ||||||
| +*/ |  | ||||||
| + |  | ||||||
| +#define ESFQ_HEAD 0 |  | ||||||
| +#define ESFQ_TAIL 1 |  | ||||||
| + |  | ||||||
| +/* This type should contain at least SFQ_DEPTH*2 values */ |  | ||||||
| +typedef unsigned int esfq_index; |  | ||||||
| + |  | ||||||
| +struct esfq_head |  | ||||||
| +{ |  | ||||||
| +	esfq_index	next; |  | ||||||
| +	esfq_index	prev; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +struct esfq_sched_data |  | ||||||
| +{ |  | ||||||
| +/* Parameters */ |  | ||||||
| +	int		perturb_period; |  | ||||||
| +	unsigned	quantum;	/* Allotment per round: MUST BE >= MTU */ |  | ||||||
| +	int		limit; |  | ||||||
| +	unsigned	depth; |  | ||||||
| +	unsigned	hash_divisor; |  | ||||||
| +	unsigned	hash_kind; |  | ||||||
| +/* Variables */ |  | ||||||
| +	struct timer_list perturb_timer; |  | ||||||
| +	int		perturbation; |  | ||||||
| +	esfq_index	tail;		/* Index of current slot in round */ |  | ||||||
| +	esfq_index	max_depth;	/* Maximal depth */ |  | ||||||
| + |  | ||||||
| +	esfq_index	*ht;			/* Hash table */ |  | ||||||
| +	esfq_index	*next;			/* Active slots link */ |  | ||||||
| +	short		*allot;			/* Current allotment per slot */ |  | ||||||
| +	unsigned short	*hash;			/* Hash value indexed by slots */ |  | ||||||
| +	struct sk_buff_head	*qs;		/* Slot queue */ |  | ||||||
| +	struct esfq_head	*dep;		/* Linked list of slots, indexed by depth */ |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/* This contains the info we will hash. */ |  | ||||||
| +struct esfq_packet_info |  | ||||||
| +{ |  | ||||||
| +	u32	proto;		/* protocol or port */ |  | ||||||
| +	u32	src;		/* source from packet header */ |  | ||||||
| +	u32	dst;		/* destination from packet header */ |  | ||||||
| +	u32	ctorigsrc;	/* original source from conntrack */ |  | ||||||
| +	u32	ctorigdst;	/* original destination from conntrack */ |  | ||||||
| +	u32	ctreplsrc;	/* reply source from conntrack */ |  | ||||||
| +	u32	ctrepldst;	/* reply destination from conntrack */ |  | ||||||
| +	u32	mark;		/* netfilter mark (fwmark) */ |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a) |  | ||||||
| +{ |  | ||||||
| +	return jhash_1word(a, q->perturbation) & (q->hash_divisor-1); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b) |  | ||||||
| +{ |  | ||||||
| +	return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c) |  | ||||||
| +{ |  | ||||||
| +	return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_packet_info info; |  | ||||||
| +#ifdef CONFIG_NET_SCH_ESFQ_NFCT |  | ||||||
| +	enum ip_conntrack_info ctinfo; |  | ||||||
| +	struct nf_conn *ct = nf_ct_get(skb, &ctinfo); |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +	switch (skb->protocol) { |  | ||||||
| +	case __constant_htons(ETH_P_IP): |  | ||||||
| +	{ |  | ||||||
| +		struct iphdr *iph = ip_hdr(skb); |  | ||||||
| +		info.dst = iph->daddr; |  | ||||||
| +		info.src = iph->saddr; |  | ||||||
| +		if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && |  | ||||||
| +		    (iph->protocol == IPPROTO_TCP || |  | ||||||
| +		     iph->protocol == IPPROTO_UDP || |  | ||||||
| +		     iph->protocol == IPPROTO_SCTP || |  | ||||||
| +		     iph->protocol == IPPROTO_DCCP || |  | ||||||
| +		     iph->protocol == IPPROTO_ESP)) |  | ||||||
| +			info.proto = *(((u32*)iph) + iph->ihl); |  | ||||||
| +		else |  | ||||||
| +			info.proto = iph->protocol; |  | ||||||
| +		break; |  | ||||||
| +	} |  | ||||||
| +	case __constant_htons(ETH_P_IPV6): |  | ||||||
| +	{ |  | ||||||
| +		struct ipv6hdr *iph = ipv6_hdr(skb); |  | ||||||
| +		/* Hash ipv6 addresses into a u32. This isn't ideal, |  | ||||||
| +		 * but the code is simple. */ |  | ||||||
| +		info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation); |  | ||||||
| +		info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation); |  | ||||||
| +		if (iph->nexthdr == IPPROTO_TCP || |  | ||||||
| +		    iph->nexthdr == IPPROTO_UDP || |  | ||||||
| +		    iph->nexthdr == IPPROTO_SCTP || |  | ||||||
| +		    iph->nexthdr == IPPROTO_DCCP || |  | ||||||
| +		    iph->nexthdr == IPPROTO_ESP) |  | ||||||
| +			info.proto = *(u32*)&iph[1]; |  | ||||||
| +		else |  | ||||||
| +			info.proto = iph->nexthdr; |  | ||||||
| +		break; |  | ||||||
| +	} |  | ||||||
| +	default: |  | ||||||
| +		info.dst   = (u32)(unsigned long)skb_dst(skb); |  | ||||||
| +		info.src   = (u32)(unsigned long)skb->sk; |  | ||||||
| +		info.proto = skb->protocol; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	info.mark = skb->mark; |  | ||||||
| + |  | ||||||
| +#ifdef CONFIG_NET_SCH_ESFQ_NFCT |  | ||||||
| +	/* defaults if there is no conntrack info */ |  | ||||||
| +	info.ctorigsrc = info.src; |  | ||||||
| +	info.ctorigdst = info.dst; |  | ||||||
| +	info.ctreplsrc = info.dst; |  | ||||||
| +	info.ctrepldst = info.src; |  | ||||||
| +	/* collect conntrack info */ |  | ||||||
| +	if (ct && ct != &nf_conntrack_untracked) { |  | ||||||
| +		if (skb->protocol == __constant_htons(ETH_P_IP)) { |  | ||||||
| +			info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; |  | ||||||
| +			info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip; |  | ||||||
| +			info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip; |  | ||||||
| +			info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip; |  | ||||||
| +		} |  | ||||||
| +		else if (skb->protocol == __constant_htons(ETH_P_IPV6)) { |  | ||||||
| +			/* Again, hash ipv6 addresses into a single u32. */ |  | ||||||
| +			info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation); |  | ||||||
| +			info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation); |  | ||||||
| +			info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation); |  | ||||||
| +			info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation); |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +	} |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +	switch(q->hash_kind) { |  | ||||||
| +	case TCA_SFQ_HASH_CLASSIC: |  | ||||||
| +		return esfq_jhash_3words(q, info.dst, info.src, info.proto); |  | ||||||
| +	case TCA_SFQ_HASH_DST: |  | ||||||
| +		return esfq_jhash_1word(q, info.dst); |  | ||||||
| +	case TCA_SFQ_HASH_SRC: |  | ||||||
| +		return esfq_jhash_1word(q, info.src); |  | ||||||
| +	case TCA_SFQ_HASH_FWMARK: |  | ||||||
| +		return esfq_jhash_1word(q, info.mark); |  | ||||||
| +#ifdef CONFIG_NET_SCH_ESFQ_NFCT |  | ||||||
| +	case TCA_SFQ_HASH_CTORIGDST: |  | ||||||
| +		return esfq_jhash_1word(q, info.ctorigdst); |  | ||||||
| +	case TCA_SFQ_HASH_CTORIGSRC: |  | ||||||
| +		return esfq_jhash_1word(q, info.ctorigsrc); |  | ||||||
| +	case TCA_SFQ_HASH_CTREPLDST: |  | ||||||
| +		return esfq_jhash_1word(q, info.ctrepldst); |  | ||||||
| +	case TCA_SFQ_HASH_CTREPLSRC: |  | ||||||
| +		return esfq_jhash_1word(q, info.ctreplsrc); |  | ||||||
| +	case TCA_SFQ_HASH_CTNATCHG: |  | ||||||
| +	{ |  | ||||||
| +		if (info.ctorigdst == info.ctreplsrc) |  | ||||||
| +			return esfq_jhash_1word(q, info.ctorigsrc); |  | ||||||
| +		return esfq_jhash_1word(q, info.ctreplsrc); |  | ||||||
| +	} |  | ||||||
| +#endif |  | ||||||
| +	default: |  | ||||||
| +		if (net_ratelimit()) |  | ||||||
| +			printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n"); |  | ||||||
| +	} |  | ||||||
| +	return esfq_jhash_3words(q, info.dst, info.src, info.proto); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void esfq_link(struct esfq_sched_data *q, esfq_index x) |  | ||||||
| +{ |  | ||||||
| +	esfq_index p, n; |  | ||||||
| +	int d = q->qs[x].qlen + q->depth; |  | ||||||
| + |  | ||||||
| +	p = d; |  | ||||||
| +	n = q->dep[d].next; |  | ||||||
| +	q->dep[x].next = n; |  | ||||||
| +	q->dep[x].prev = p; |  | ||||||
| +	q->dep[p].next = q->dep[n].prev = x; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x) |  | ||||||
| +{ |  | ||||||
| +	esfq_index p, n; |  | ||||||
| + |  | ||||||
| +	n = q->dep[x].next; |  | ||||||
| +	p = q->dep[x].prev; |  | ||||||
| +	q->dep[p].next = n; |  | ||||||
| +	q->dep[n].prev = p; |  | ||||||
| + |  | ||||||
| +	if (n == p && q->max_depth == q->qs[x].qlen + 1) |  | ||||||
| +		q->max_depth--; |  | ||||||
| + |  | ||||||
| +	esfq_link(q, x); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x) |  | ||||||
| +{ |  | ||||||
| +	esfq_index p, n; |  | ||||||
| +	int d; |  | ||||||
| + |  | ||||||
| +	n = q->dep[x].next; |  | ||||||
| +	p = q->dep[x].prev; |  | ||||||
| +	q->dep[p].next = n; |  | ||||||
| +	q->dep[n].prev = p; |  | ||||||
| +	d = q->qs[x].qlen; |  | ||||||
| +	if (q->max_depth < d) |  | ||||||
| +		q->max_depth = d; |  | ||||||
| + |  | ||||||
| +	esfq_link(q, x); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static unsigned int esfq_drop(struct Qdisc *sch) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	esfq_index d = q->max_depth; |  | ||||||
| +	struct sk_buff *skb; |  | ||||||
| +	unsigned int len; |  | ||||||
| + |  | ||||||
| +	/* Queue is full! Find the longest slot and |  | ||||||
| +	   drop a packet from it */ |  | ||||||
| + |  | ||||||
| +	if (d > 1) { |  | ||||||
| +		esfq_index x = q->dep[d+q->depth].next; |  | ||||||
| +		skb = q->qs[x].prev; |  | ||||||
| +		len = skb->len; |  | ||||||
| +		__skb_unlink(skb, &q->qs[x]); |  | ||||||
| +		kfree_skb(skb); |  | ||||||
| +		esfq_dec(q, x); |  | ||||||
| +		sch->q.qlen--; |  | ||||||
| +		sch->qstats.drops++; |  | ||||||
| +		sch->qstats.backlog -= len; |  | ||||||
| +		return len; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (d == 1) { |  | ||||||
| +		/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ |  | ||||||
| +		d = q->next[q->tail]; |  | ||||||
| +		q->next[q->tail] = q->next[d]; |  | ||||||
| +		q->allot[q->next[d]] += q->quantum; |  | ||||||
| +		skb = q->qs[d].prev; |  | ||||||
| +		len = skb->len; |  | ||||||
| +		__skb_unlink(skb, &q->qs[d]); |  | ||||||
| +		kfree_skb(skb); |  | ||||||
| +		esfq_dec(q, d); |  | ||||||
| +		sch->q.qlen--; |  | ||||||
| +		q->ht[q->hash[d]] = q->depth; |  | ||||||
| +		sch->qstats.drops++; |  | ||||||
| +		sch->qstats.backlog -= len; |  | ||||||
| +		return len; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void esfq_q_enqueue(struct sk_buff *skb, struct esfq_sched_data *q, unsigned int end) |  | ||||||
| +{ |  | ||||||
| +	unsigned hash = esfq_hash(q, skb); |  | ||||||
| +	unsigned depth = q->depth; |  | ||||||
| +	esfq_index x; |  | ||||||
| + |  | ||||||
| +	x = q->ht[hash]; |  | ||||||
| +	if (x == depth) { |  | ||||||
| +		q->ht[hash] = x = q->dep[depth].next; |  | ||||||
| +		q->hash[x] = hash; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (end == ESFQ_TAIL) |  | ||||||
| +		__skb_queue_tail(&q->qs[x], skb); |  | ||||||
| +	else |  | ||||||
| +		__skb_queue_head(&q->qs[x], skb); |  | ||||||
| + |  | ||||||
| +	esfq_inc(q, x); |  | ||||||
| +	if (q->qs[x].qlen == 1) {		/* The flow is new */ |  | ||||||
| +		if (q->tail == depth) {	/* It is the first flow */ |  | ||||||
| +			q->tail = x; |  | ||||||
| +			q->next[x] = x; |  | ||||||
| +			q->allot[x] = q->quantum; |  | ||||||
| +		} else { |  | ||||||
| +			q->next[x] = q->next[q->tail]; |  | ||||||
| +			q->next[q->tail] = x; |  | ||||||
| +			q->tail = x; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	esfq_q_enqueue(skb, q, ESFQ_TAIL); |  | ||||||
| +	sch->qstats.backlog += skb->len; |  | ||||||
| +	if (++sch->q.qlen < q->limit-1) { |  | ||||||
| +		sch->bstats.bytes += skb->len; |  | ||||||
| +		sch->bstats.packets++; |  | ||||||
| +		return 0; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	sch->qstats.drops++; |  | ||||||
| +	esfq_drop(sch); |  | ||||||
| +	return NET_XMIT_CN; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct sk_buff *esfq_peek(struct Qdisc* sch) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	esfq_index a; |  | ||||||
| + |  | ||||||
| +	/* No active slots */ |  | ||||||
| +	if (q->tail == q->depth) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	a = q->next[q->tail]; |  | ||||||
| +	return skb_peek(&q->qs[a]); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct sk_buff *esfq_q_dequeue(struct esfq_sched_data *q) |  | ||||||
| +{ |  | ||||||
| +	struct sk_buff *skb; |  | ||||||
| +	unsigned depth = q->depth; |  | ||||||
| +	esfq_index a, old_a; |  | ||||||
| + |  | ||||||
| +	/* No active slots */ |  | ||||||
| +	if (q->tail == depth) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	a = old_a = q->next[q->tail]; |  | ||||||
| + |  | ||||||
| +	/* Grab packet */ |  | ||||||
| +	skb = __skb_dequeue(&q->qs[a]); |  | ||||||
| +	esfq_dec(q, a); |  | ||||||
| + |  | ||||||
| +	/* Is the slot empty? */ |  | ||||||
| +	if (q->qs[a].qlen == 0) { |  | ||||||
| +		q->ht[q->hash[a]] = depth; |  | ||||||
| +		a = q->next[a]; |  | ||||||
| +		if (a == old_a) { |  | ||||||
| +			q->tail = depth; |  | ||||||
| +			return skb; |  | ||||||
| +		} |  | ||||||
| +		q->next[q->tail] = a; |  | ||||||
| +		q->allot[a] += q->quantum; |  | ||||||
| +	} else if ((q->allot[a] -= skb->len) <= 0) { |  | ||||||
| +		q->tail = a; |  | ||||||
| +		a = q->next[a]; |  | ||||||
| +		q->allot[a] += q->quantum; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return skb; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct sk_buff *esfq_dequeue(struct Qdisc* sch) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	struct sk_buff *skb; |  | ||||||
| + |  | ||||||
| +	skb = esfq_q_dequeue(q); |  | ||||||
| +	if (skb == NULL) |  | ||||||
| +		return NULL; |  | ||||||
| +	sch->q.qlen--; |  | ||||||
| +	sch->qstats.backlog -= skb->len; |  | ||||||
| +	return skb; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void esfq_q_destroy(struct esfq_sched_data *q) |  | ||||||
| +{ |  | ||||||
| +	del_timer(&q->perturb_timer); |  | ||||||
| +	if(q->ht) |  | ||||||
| +		kfree(q->ht); |  | ||||||
| +	if(q->dep) |  | ||||||
| +		kfree(q->dep); |  | ||||||
| +	if(q->next) |  | ||||||
| +		kfree(q->next); |  | ||||||
| +	if(q->allot) |  | ||||||
| +		kfree(q->allot); |  | ||||||
| +	if(q->hash) |  | ||||||
| +		kfree(q->hash); |  | ||||||
| +	if(q->qs) |  | ||||||
| +		kfree(q->qs); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void esfq_destroy(struct Qdisc *sch) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	esfq_q_destroy(q); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static void esfq_reset(struct Qdisc* sch) |  | ||||||
| +{ |  | ||||||
| +	struct sk_buff *skb; |  | ||||||
| + |  | ||||||
| +	while ((skb = esfq_dequeue(sch)) != NULL) |  | ||||||
| +		kfree_skb(skb); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void esfq_perturbation(unsigned long arg) |  | ||||||
| +{ |  | ||||||
| +	struct Qdisc *sch = (struct Qdisc*)arg; |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| + |  | ||||||
| +	q->perturbation = net_random()&0x1F; |  | ||||||
| + |  | ||||||
| +	if (q->perturb_period) { |  | ||||||
| +		q->perturb_timer.expires = jiffies + q->perturb_period; |  | ||||||
| +		add_timer(&q->perturb_timer); |  | ||||||
| +	} |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static unsigned int esfq_check_hash(unsigned int kind) |  | ||||||
| +{ |  | ||||||
| +	switch (kind) { |  | ||||||
| +	case TCA_SFQ_HASH_CTORIGDST: |  | ||||||
| +	case TCA_SFQ_HASH_CTORIGSRC: |  | ||||||
| +	case TCA_SFQ_HASH_CTREPLDST: |  | ||||||
| +	case TCA_SFQ_HASH_CTREPLSRC: |  | ||||||
| +	case TCA_SFQ_HASH_CTNATCHG: |  | ||||||
| +#ifndef CONFIG_NET_SCH_ESFQ_NFCT |  | ||||||
| +	{ |  | ||||||
| +		if (net_ratelimit()) |  | ||||||
| +			printk(KERN_WARNING "ESFQ: Conntrack hash types disabled in kernel config. Falling back to classic.\n"); |  | ||||||
| +		return TCA_SFQ_HASH_CLASSIC; |  | ||||||
| +	} |  | ||||||
| +#endif |  | ||||||
| +	case TCA_SFQ_HASH_CLASSIC: |  | ||||||
| +	case TCA_SFQ_HASH_DST: |  | ||||||
| +	case TCA_SFQ_HASH_SRC: |  | ||||||
| +	case TCA_SFQ_HASH_FWMARK: |  | ||||||
| +		return kind; |  | ||||||
| +	default: |  | ||||||
| +	{ |  | ||||||
| +		if (net_ratelimit()) |  | ||||||
| +			printk(KERN_WARNING "ESFQ: Unknown hash type. Falling back to classic.\n"); |  | ||||||
| +		return TCA_SFQ_HASH_CLASSIC; |  | ||||||
| +	} |  | ||||||
| +	} |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int esfq_q_init(struct esfq_sched_data *q, struct nlattr *opt) |  | ||||||
| +{ |  | ||||||
| +	struct tc_esfq_qopt *ctl = nla_data(opt); |  | ||||||
| +	esfq_index p = ~0U/2; |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	if (opt && opt->nla_len < nla_attr_size(sizeof(*ctl))) |  | ||||||
| +		return -EINVAL; |  | ||||||
| + |  | ||||||
| +	q->perturbation = 0; |  | ||||||
| +	q->hash_kind = TCA_SFQ_HASH_CLASSIC; |  | ||||||
| +	q->max_depth = 0; |  | ||||||
| +	if (opt == NULL) { |  | ||||||
| +		q->perturb_period = 0; |  | ||||||
| +		q->hash_divisor = 1024; |  | ||||||
| +		q->tail = q->limit = q->depth = 128; |  | ||||||
| + |  | ||||||
| +	} else { |  | ||||||
| +		struct tc_esfq_qopt *ctl = nla_data(opt); |  | ||||||
| +		if (ctl->quantum) |  | ||||||
| +			q->quantum = ctl->quantum; |  | ||||||
| +		q->perturb_period = ctl->perturb_period*HZ; |  | ||||||
| +		q->hash_divisor = ctl->divisor ? : 1024; |  | ||||||
| +		q->tail = q->limit = q->depth = ctl->flows ? : 128; |  | ||||||
| + |  | ||||||
| +		if ( q->depth > p - 1 ) |  | ||||||
| +			return -EINVAL; |  | ||||||
| + |  | ||||||
| +		if (ctl->limit) |  | ||||||
| +			q->limit = min_t(u32, ctl->limit, q->depth); |  | ||||||
| + |  | ||||||
| +		if (ctl->hash_kind) { |  | ||||||
| +			q->hash_kind = esfq_check_hash(ctl->hash_kind); |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL); |  | ||||||
| +	if (!q->ht) |  | ||||||
| +		goto err_case; |  | ||||||
| +	q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL); |  | ||||||
| +	if (!q->dep) |  | ||||||
| +		goto err_case; |  | ||||||
| +	q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL); |  | ||||||
| +	if (!q->next) |  | ||||||
| +		goto err_case; |  | ||||||
| +	q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL); |  | ||||||
| +	if (!q->allot) |  | ||||||
| +		goto err_case; |  | ||||||
| +	q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL); |  | ||||||
| +	if (!q->hash) |  | ||||||
| +		goto err_case; |  | ||||||
| +	q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL); |  | ||||||
| +	if (!q->qs) |  | ||||||
| +		goto err_case; |  | ||||||
| + |  | ||||||
| +	for (i=0; i< q->hash_divisor; i++) |  | ||||||
| +		q->ht[i] = q->depth; |  | ||||||
| +	for (i=0; i<q->depth; i++) { |  | ||||||
| +		skb_queue_head_init(&q->qs[i]); |  | ||||||
| +		q->dep[i+q->depth].next = i+q->depth; |  | ||||||
| +		q->dep[i+q->depth].prev = i+q->depth; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	for (i=0; i<q->depth; i++) |  | ||||||
| +		esfq_link(q, i); |  | ||||||
| +	return 0; |  | ||||||
| +err_case: |  | ||||||
| +	esfq_q_destroy(q); |  | ||||||
| +	return -ENOBUFS; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int esfq_init(struct Qdisc *sch, struct nlattr *opt) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	q->quantum = psched_mtu(qdisc_dev(sch)); /* default */ |  | ||||||
| +	if ((err = esfq_q_init(q, opt))) |  | ||||||
| +		return err; |  | ||||||
| + |  | ||||||
| +	init_timer(&q->perturb_timer); |  | ||||||
| +	q->perturb_timer.data = (unsigned long)sch; |  | ||||||
| +	q->perturb_timer.function = esfq_perturbation; |  | ||||||
| +	if (q->perturb_period) { |  | ||||||
| +		q->perturb_timer.expires = jiffies + q->perturb_period; |  | ||||||
| +		add_timer(&q->perturb_timer); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int esfq_change(struct Qdisc *sch, struct nlattr *opt) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	struct esfq_sched_data new; |  | ||||||
| +	struct sk_buff *skb; |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	/* set up new queue */ |  | ||||||
| +	memset(&new, 0, sizeof(struct esfq_sched_data)); |  | ||||||
| +	new.quantum = psched_mtu(qdisc_dev(sch)); /* default */ |  | ||||||
| +	if ((err = esfq_q_init(&new, opt))) |  | ||||||
| +		return err; |  | ||||||
| + |  | ||||||
| +	/* copy all packets from the old queue to the new queue */ |  | ||||||
| +	sch_tree_lock(sch); |  | ||||||
| +	while ((skb = esfq_q_dequeue(q)) != NULL) |  | ||||||
| +		esfq_q_enqueue(skb, &new, ESFQ_TAIL); |  | ||||||
| + |  | ||||||
| +	/* clean up the old queue */ |  | ||||||
| +	esfq_q_destroy(q); |  | ||||||
| + |  | ||||||
| +	/* copy elements of the new queue into the old queue */ |  | ||||||
| +	q->perturb_period = new.perturb_period; |  | ||||||
| +	q->quantum        = new.quantum; |  | ||||||
| +	q->limit          = new.limit; |  | ||||||
| +	q->depth          = new.depth; |  | ||||||
| +	q->hash_divisor   = new.hash_divisor; |  | ||||||
| +	q->hash_kind      = new.hash_kind; |  | ||||||
| +	q->tail           = new.tail; |  | ||||||
| +	q->max_depth      = new.max_depth; |  | ||||||
| +	q->ht    = new.ht; |  | ||||||
| +	q->dep   = new.dep; |  | ||||||
| +	q->next  = new.next; |  | ||||||
| +	q->allot = new.allot; |  | ||||||
| +	q->hash  = new.hash; |  | ||||||
| +	q->qs    = new.qs; |  | ||||||
| + |  | ||||||
| +	/* finish up */ |  | ||||||
| +	if (q->perturb_period) { |  | ||||||
| +		q->perturb_timer.expires = jiffies + q->perturb_period; |  | ||||||
| +		add_timer(&q->perturb_timer); |  | ||||||
| +	} else { |  | ||||||
| +		q->perturbation = 0; |  | ||||||
| +	} |  | ||||||
| +	sch_tree_unlock(sch); |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb) |  | ||||||
| +{ |  | ||||||
| +	struct esfq_sched_data *q = qdisc_priv(sch); |  | ||||||
| +	unsigned char *b = skb_tail_pointer(skb); |  | ||||||
| +	struct tc_esfq_qopt opt; |  | ||||||
| + |  | ||||||
| +	opt.quantum = q->quantum; |  | ||||||
| +	opt.perturb_period = q->perturb_period/HZ; |  | ||||||
| + |  | ||||||
| +	opt.limit = q->limit; |  | ||||||
| +	opt.divisor = q->hash_divisor; |  | ||||||
| +	opt.flows = q->depth; |  | ||||||
| +	opt.hash_kind = q->hash_kind; |  | ||||||
| + |  | ||||||
| +	NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); |  | ||||||
| + |  | ||||||
| +	return skb->len; |  | ||||||
| + |  | ||||||
| +nla_put_failure: |  | ||||||
| +	nlmsg_trim(skb, b); |  | ||||||
| +	return -1; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct Qdisc_ops esfq_qdisc_ops = |  | ||||||
| +{ |  | ||||||
| +	.next		=	NULL, |  | ||||||
| +	.cl_ops		=	NULL, |  | ||||||
| +	.id		=	"esfq", |  | ||||||
| +	.priv_size	=	sizeof(struct esfq_sched_data), |  | ||||||
| +	.enqueue	=	esfq_enqueue, |  | ||||||
| +	.dequeue	=	esfq_dequeue, |  | ||||||
| +	.peek		=	esfq_peek, |  | ||||||
| +	.drop		=	esfq_drop, |  | ||||||
| +	.init		=	esfq_init, |  | ||||||
| +	.reset		=	esfq_reset, |  | ||||||
| +	.destroy	=	esfq_destroy, |  | ||||||
| +	.change		=	esfq_change, |  | ||||||
| +	.dump		=	esfq_dump, |  | ||||||
| +	.owner		=	THIS_MODULE, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static int __init esfq_module_init(void) |  | ||||||
| +{ |  | ||||||
| +	return register_qdisc(&esfq_qdisc_ops); |  | ||||||
| +} |  | ||||||
| +static void __exit esfq_module_exit(void) |  | ||||||
| +{ |  | ||||||
| +	unregister_qdisc(&esfq_qdisc_ops); |  | ||||||
| +} |  | ||||||
| +module_init(esfq_module_init) |  | ||||||
| +module_exit(esfq_module_exit) |  | ||||||
| +MODULE_LICENSE("GPL"); |  | ||||||
| @@ -1,227 +0,0 @@ | |||||||
| --- a/include/linux/jhash.h |  | ||||||
| +++ b/include/linux/jhash.h |  | ||||||
| @@ -3,80 +3,95 @@ |  | ||||||
|   |  | ||||||
|  /* jhash.h: Jenkins hash support. |  | ||||||
|   * |  | ||||||
| - * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) |  | ||||||
| + * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net) |  | ||||||
|   * |  | ||||||
|   * http://burtleburtle.net/bob/hash/ |  | ||||||
|   * |  | ||||||
|   * These are the credits from Bob's sources: |  | ||||||
|   * |  | ||||||
| - * lookup2.c, by Bob Jenkins, December 1996, Public Domain. |  | ||||||
| - * hash(), hash2(), hash3, and mix() are externally useful functions. |  | ||||||
| - * Routines to test the hash are included if SELF_TEST is defined. |  | ||||||
| - * You can use this free for any purpose.  It has no warranty. |  | ||||||
| + * lookup3.c, by Bob Jenkins, May 2006, Public Domain. |  | ||||||
|   * |  | ||||||
| - * Copyright (C) 2003 David S. Miller (davem@redhat.com) |  | ||||||
| + * These are functions for producing 32-bit hashes for hash table lookup. |  | ||||||
| + * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()  |  | ||||||
| + * are externally useful functions.  Routines to test the hash are included  |  | ||||||
| + * if SELF_TEST is defined.  You can use this free for any purpose.  It's in |  | ||||||
| + * the public domain.  It has no warranty. |  | ||||||
| + * |  | ||||||
| + * Copyright (C) 2009 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) |  | ||||||
|   * |  | ||||||
|   * I've modified Bob's hash to be useful in the Linux kernel, and |  | ||||||
| - * any bugs present are surely my fault.  -DaveM |  | ||||||
| + * any bugs present are my fault.  Jozsef |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
| -/* NOTE: Arguments are modified. */ |  | ||||||
| -#define __jhash_mix(a, b, c) \ |  | ||||||
| +#define __rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) |  | ||||||
| + |  | ||||||
| +/* __jhash_mix - mix 3 32-bit values reversibly. */ |  | ||||||
| +#define __jhash_mix(a,b,c) \ |  | ||||||
| +{ \ |  | ||||||
| +  a -= c;  a ^= __rot(c, 4);  c += b; \ |  | ||||||
| +  b -= a;  b ^= __rot(a, 6);  a += c; \ |  | ||||||
| +  c -= b;  c ^= __rot(b, 8);  b += a; \ |  | ||||||
| +  a -= c;  a ^= __rot(c,16);  c += b; \ |  | ||||||
| +  b -= a;  b ^= __rot(a,19);  a += c; \ |  | ||||||
| +  c -= b;  c ^= __rot(b, 4);  b += a; \ |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */ |  | ||||||
| +#define __jhash_final(a,b,c) \ |  | ||||||
|  { \ |  | ||||||
| -  a -= b; a -= c; a ^= (c>>13); \ |  | ||||||
| -  b -= c; b -= a; b ^= (a<<8); \ |  | ||||||
| -  c -= a; c -= b; c ^= (b>>13); \ |  | ||||||
| -  a -= b; a -= c; a ^= (c>>12);  \ |  | ||||||
| -  b -= c; b -= a; b ^= (a<<16); \ |  | ||||||
| -  c -= a; c -= b; c ^= (b>>5); \ |  | ||||||
| -  a -= b; a -= c; a ^= (c>>3);  \ |  | ||||||
| -  b -= c; b -= a; b ^= (a<<10); \ |  | ||||||
| -  c -= a; c -= b; c ^= (b>>15); \ |  | ||||||
| +  c ^= b; c -= __rot(b,14); \ |  | ||||||
| +  a ^= c; a -= __rot(c,11); \ |  | ||||||
| +  b ^= a; b -= __rot(a,25); \ |  | ||||||
| +  c ^= b; c -= __rot(b,16); \ |  | ||||||
| +  a ^= c; a -= __rot(c,4);  \ |  | ||||||
| +  b ^= a; b -= __rot(a,14); \ |  | ||||||
| +  c ^= b; c -= __rot(b,24); \ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -/* The golden ration: an arbitrary value */ |  | ||||||
| -#define JHASH_GOLDEN_RATIO	0x9e3779b9 |  | ||||||
| +/* An arbitrary initial parameter */ |  | ||||||
| +#define JHASH_GOLDEN_RATIO	0xdeadbeef |  | ||||||
|   |  | ||||||
|  /* The most generic version, hashes an arbitrary sequence |  | ||||||
|   * of bytes.  No alignment or length assumptions are made about |  | ||||||
| - * the input key. |  | ||||||
| + * the input key. The result depends on endianness. |  | ||||||
|   */ |  | ||||||
|  static inline u32 jhash(const void *key, u32 length, u32 initval) |  | ||||||
|  { |  | ||||||
| -	u32 a, b, c, len; |  | ||||||
| +	u32 a,b,c; |  | ||||||
|  	const u8 *k = key; |  | ||||||
|   |  | ||||||
| -	len = length; |  | ||||||
| -	a = b = JHASH_GOLDEN_RATIO; |  | ||||||
| -	c = initval; |  | ||||||
| - |  | ||||||
| -	while (len >= 12) { |  | ||||||
| -		a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24)); |  | ||||||
| -		b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24)); |  | ||||||
| -		c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24)); |  | ||||||
| - |  | ||||||
| -		__jhash_mix(a,b,c); |  | ||||||
| +	/* Set up the internal state */ |  | ||||||
| +	a = b = c = JHASH_GOLDEN_RATIO + length + initval; |  | ||||||
|   |  | ||||||
| +	/* all but the last block: affect some 32 bits of (a,b,c) */ |  | ||||||
| +	while (length > 12) { |  | ||||||
| +    		a += (k[0] + ((u32)k[1]<<8) + ((u32)k[2]<<16) + ((u32)k[3]<<24)); |  | ||||||
| +		b += (k[4] + ((u32)k[5]<<8) + ((u32)k[6]<<16) + ((u32)k[7]<<24)); |  | ||||||
| +		c += (k[8] + ((u32)k[9]<<8) + ((u32)k[10]<<16) + ((u32)k[11]<<24)); |  | ||||||
| +		__jhash_mix(a, b, c); |  | ||||||
| +		length -= 12; |  | ||||||
|  		k += 12; |  | ||||||
| -		len -= 12; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	c += length; |  | ||||||
| -	switch (len) { |  | ||||||
| -	case 11: c += ((u32)k[10]<<24); |  | ||||||
| -	case 10: c += ((u32)k[9]<<16); |  | ||||||
| -	case 9 : c += ((u32)k[8]<<8); |  | ||||||
| -	case 8 : b += ((u32)k[7]<<24); |  | ||||||
| -	case 7 : b += ((u32)k[6]<<16); |  | ||||||
| -	case 6 : b += ((u32)k[5]<<8); |  | ||||||
| +	/* last block: affect all 32 bits of (c) */ |  | ||||||
| +	/* all the case statements fall through */ |  | ||||||
| +	switch (length) { |  | ||||||
| +	case 12: c += (u32)k[11]<<24; |  | ||||||
| +	case 11: c += (u32)k[10]<<16; |  | ||||||
| +	case 10: c += (u32)k[9]<<8; |  | ||||||
| +	case 9 : c += k[8]; |  | ||||||
| +	case 8 : b += (u32)k[7]<<24; |  | ||||||
| +	case 7 : b += (u32)k[6]<<16; |  | ||||||
| +	case 6 : b += (u32)k[5]<<8; |  | ||||||
|  	case 5 : b += k[4]; |  | ||||||
| -	case 4 : a += ((u32)k[3]<<24); |  | ||||||
| -	case 3 : a += ((u32)k[2]<<16); |  | ||||||
| -	case 2 : a += ((u32)k[1]<<8); |  | ||||||
| +	case 4 : a += (u32)k[3]<<24; |  | ||||||
| +	case 3 : a += (u32)k[2]<<16; |  | ||||||
| +	case 2 : a += (u32)k[1]<<8; |  | ||||||
|  	case 1 : a += k[0]; |  | ||||||
| -	}; |  | ||||||
| - |  | ||||||
| -	__jhash_mix(a,b,c); |  | ||||||
| +		__jhash_final(a, b, c); |  | ||||||
| +	case 0 : |  | ||||||
| +		break; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	return c; |  | ||||||
|  } |  | ||||||
| @@ -86,58 +101,57 @@ static inline u32 jhash(const void *key, |  | ||||||
|   */ |  | ||||||
|  static inline u32 jhash2(const u32 *k, u32 length, u32 initval) |  | ||||||
|  { |  | ||||||
| -	u32 a, b, c, len; |  | ||||||
| +	u32 a, b, c; |  | ||||||
|   |  | ||||||
| -	a = b = JHASH_GOLDEN_RATIO; |  | ||||||
| -	c = initval; |  | ||||||
| -	len = length; |  | ||||||
| +	/* Set up the internal state */ |  | ||||||
| +	a = b = c = JHASH_GOLDEN_RATIO + (length<<2) + initval; |  | ||||||
|   |  | ||||||
| -	while (len >= 3) { |  | ||||||
| +	/* handle most of the key */ |  | ||||||
| +	while (length > 3) { |  | ||||||
|  		a += k[0]; |  | ||||||
|  		b += k[1]; |  | ||||||
|  		c += k[2]; |  | ||||||
|  		__jhash_mix(a, b, c); |  | ||||||
| -		k += 3; len -= 3; |  | ||||||
| +		length -= 3; |  | ||||||
| +		k += 3; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	c += length * 4; |  | ||||||
| - |  | ||||||
| -	switch (len) { |  | ||||||
| -	case 2 : b += k[1]; |  | ||||||
| -	case 1 : a += k[0]; |  | ||||||
| -	}; |  | ||||||
| - |  | ||||||
| -	__jhash_mix(a,b,c); |  | ||||||
| +	/* handle the last 3 u32's */ |  | ||||||
| +	/* all the case statements fall through */  |  | ||||||
| +	switch (length) { |  | ||||||
| +	case 3: c += k[2]; |  | ||||||
| +	case 2: b += k[1]; |  | ||||||
| +	case 1: a += k[0]; |  | ||||||
| +		__jhash_final(a, b, c); |  | ||||||
| +	case 0:     /* case 0: nothing left to add */ |  | ||||||
| +		break; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	return c; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| - |  | ||||||
|  /* A special ultra-optimized versions that knows they are hashing exactly |  | ||||||
|   * 3, 2 or 1 word(s). |  | ||||||
| - * |  | ||||||
| - * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally |  | ||||||
| - *       done at the end is not done here. |  | ||||||
|   */ |  | ||||||
|  static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) |  | ||||||
|  { |  | ||||||
| -	a += JHASH_GOLDEN_RATIO; |  | ||||||
| -	b += JHASH_GOLDEN_RATIO; |  | ||||||
| -	c += initval; |  | ||||||
| +	a += JHASH_GOLDEN_RATIO + initval; |  | ||||||
| +	b += JHASH_GOLDEN_RATIO + initval; |  | ||||||
| +	c += JHASH_GOLDEN_RATIO + initval; |  | ||||||
|   |  | ||||||
| -	__jhash_mix(a, b, c); |  | ||||||
| +	__jhash_final(a, b, c); |  | ||||||
|   |  | ||||||
|  	return c; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline u32 jhash_2words(u32 a, u32 b, u32 initval) |  | ||||||
|  { |  | ||||||
| -	return jhash_3words(a, b, 0, initval); |  | ||||||
| +	return jhash_3words(0, a, b, initval); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline u32 jhash_1word(u32 a, u32 initval) |  | ||||||
|  { |  | ||||||
| -	return jhash_3words(a, 0, 0, initval); |  | ||||||
| +	return jhash_3words(0, 0, a, initval); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #endif /* _LINUX_JHASH_H */ |  | ||||||
| @@ -1,83 +0,0 @@ | |||||||
| --- a/arch/mips/include/asm/string.h |  | ||||||
| +++ b/arch/mips/include/asm/string.h |  | ||||||
| @@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__ |  | ||||||
|   |  | ||||||
|  #define __HAVE_ARCH_MEMSET |  | ||||||
|  extern void *memset(void *__s, int __c, size_t __count); |  | ||||||
| +#define memset(__s, __c, len)					\ |  | ||||||
| +({								\ |  | ||||||
| +	size_t __len = (len);					\ |  | ||||||
| +	void *__ret;						\ |  | ||||||
| +	if (__builtin_constant_p(len) && __len >= 64)		\ |  | ||||||
| +		__ret = memset((__s), (__c), __len);		\ |  | ||||||
| +	else							\ |  | ||||||
| +		__ret = __builtin_memset((__s), (__c), __len);	\ |  | ||||||
| +	__ret;							\ |  | ||||||
| +}) |  | ||||||
|   |  | ||||||
|  #define __HAVE_ARCH_MEMCPY |  | ||||||
|  extern void *memcpy(void *__to, __const__ void *__from, size_t __n); |  | ||||||
| +#define memcpy(dst, src, len)					\ |  | ||||||
| +({								\ |  | ||||||
| +	size_t __len = (len);					\ |  | ||||||
| +	void *__ret;						\ |  | ||||||
| +	if (__builtin_constant_p(len) && __len >= 64)		\ |  | ||||||
| +		__ret = memcpy((dst), (src), __len);		\ |  | ||||||
| +	else							\ |  | ||||||
| +		__ret = __builtin_memcpy((dst), (src), __len);	\ |  | ||||||
| +	__ret;							\ |  | ||||||
| +}) |  | ||||||
|   |  | ||||||
|  #define __HAVE_ARCH_MEMMOVE |  | ||||||
|  extern void *memmove(void *__dest, __const__ void *__src, size_t __n); |  | ||||||
| +#define memmove(dst, src, len)					\ |  | ||||||
| +({								\ |  | ||||||
| +	size_t __len = (len);					\ |  | ||||||
| +	void *__ret;						\ |  | ||||||
| +	if (__builtin_constant_p(len) && __len >= 64)		\ |  | ||||||
| +		__ret = memmove((dst), (src), __len);		\ |  | ||||||
| +	else							\ |  | ||||||
| +		__ret = __builtin_memmove((dst), (src), __len);	\ |  | ||||||
| +	__ret;							\ |  | ||||||
| +}) |  | ||||||
| + |  | ||||||
| +#define __HAVE_ARCH_MEMCMP |  | ||||||
| +#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len)) |  | ||||||
|   |  | ||||||
|  #endif /* _ASM_STRING_H */ |  | ||||||
| --- a/arch/mips/lib/Makefile |  | ||||||
| +++ b/arch/mips/lib/Makefile |  | ||||||
| @@ -3,7 +3,7 @@ |  | ||||||
|  # |  | ||||||
|   |  | ||||||
|  lib-y	+= csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \ |  | ||||||
| -	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o |  | ||||||
| +	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o memcmp.o |  | ||||||
|   |  | ||||||
|  obj-y			+= iomap.o |  | ||||||
|  obj-$(CONFIG_PCI)	+= iomap-pci.o |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/arch/mips/lib/memcmp.c |  | ||||||
| @@ -0,0 +1,22 @@ |  | ||||||
| +/* |  | ||||||
| + *  copied from linux/lib/string.c |  | ||||||
| + * |  | ||||||
| + *  Copyright (C) 1991, 1992  Linus Torvalds |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#include <linux/string.h> |  | ||||||
| + |  | ||||||
| +#undef memcmp |  | ||||||
| +int memcmp(const void *cs, const void *ct, size_t count) |  | ||||||
| +{ |  | ||||||
| +	const unsigned char *su1, *su2; |  | ||||||
| +	int res = 0; |  | ||||||
| + |  | ||||||
| +	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) |  | ||||||
| +		if ((res = *su1 - *su2) != 0) |  | ||||||
| +			break; |  | ||||||
| +	return res; |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL(memcmp); |  | ||||||
| + |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| --- a/include/linux/slab.h |  | ||||||
| +++ b/include/linux/slab.h |  | ||||||
| @@ -124,8 +124,8 @@ int kmem_ptr_validate(struct kmem_cache |  | ||||||
|   * to do various tricks to work around compiler limitations in order to |  | ||||||
|   * ensure proper constant folding. |  | ||||||
|   */ |  | ||||||
| -#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \ |  | ||||||
| -				(MAX_ORDER + PAGE_SHIFT - 1) : 25) |  | ||||||
| +#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 17 ? \ |  | ||||||
| +				(MAX_ORDER + PAGE_SHIFT - 1) : 17) |  | ||||||
|   |  | ||||||
|  #define KMALLOC_MAX_SIZE	(1UL << KMALLOC_SHIFT_HIGH) |  | ||||||
|  #define KMALLOC_MAX_ORDER	(KMALLOC_SHIFT_HIGH - PAGE_SHIFT) |  | ||||||
| @@ -1,132 +0,0 @@ | |||||||
| --- a/fs/jffs2/build.c |  | ||||||
| +++ b/fs/jffs2/build.c |  | ||||||
| @@ -111,6 +111,17 @@ static int jffs2_build_filesystem(struct |  | ||||||
|  	dbg_fsbuild("scanned flash completely\n"); |  | ||||||
|  	jffs2_dbg_dump_block_lists_nolock(c); |  | ||||||
|   |  | ||||||
| +	if (c->flags & (1 << 7)) { |  | ||||||
| +		printk("%s(): unlocking the mtd device... ", __func__); |  | ||||||
| +		if (c->mtd->unlock) |  | ||||||
| +			c->mtd->unlock(c->mtd, 0, c->mtd->size); |  | ||||||
| +		printk("done.\n"); |  | ||||||
| + |  | ||||||
| +		printk("%s(): erasing all blocks after the end marker... ", __func__); |  | ||||||
| +		jffs2_erase_pending_blocks(c, -1); |  | ||||||
| +		printk("done.\n"); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	dbg_fsbuild("pass 1 starting\n"); |  | ||||||
|  	c->flags |= JFFS2_SB_FLAG_BUILDING; |  | ||||||
|  	/* Now scan the directory tree, increasing nlink according to every dirent found. */ |  | ||||||
| --- a/fs/jffs2/scan.c |  | ||||||
| +++ b/fs/jffs2/scan.c |  | ||||||
| @@ -72,7 +72,7 @@ static int file_dirty(struct jffs2_sb_in |  | ||||||
|  		return ret; |  | ||||||
|  	if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size))) |  | ||||||
|  		return ret; |  | ||||||
| -	/* Turned wasted size into dirty, since we apparently  |  | ||||||
| +	/* Turned wasted size into dirty, since we apparently |  | ||||||
|  	   think it's recoverable now. */ |  | ||||||
|  	jeb->dirty_size += jeb->wasted_size; |  | ||||||
|  	c->dirty_size += jeb->wasted_size; |  | ||||||
| @@ -144,8 +144,11 @@ int jffs2_scan_medium(struct jffs2_sb_in |  | ||||||
|  		/* reset summary info for next eraseblock scan */ |  | ||||||
|  		jffs2_sum_reset_collected(s); |  | ||||||
|   |  | ||||||
| -		ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), |  | ||||||
| -						buf_size, s); |  | ||||||
| +		if (c->flags & (1 << 7)) |  | ||||||
| +			ret = BLK_STATE_ALLFF; |  | ||||||
| +		else |  | ||||||
| +			ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), |  | ||||||
| +							buf_size, s); |  | ||||||
|   |  | ||||||
|  		if (ret < 0) |  | ||||||
|  			goto out; |  | ||||||
| @@ -400,7 +403,7 @@ static int jffs2_scan_xref_node(struct j |  | ||||||
|  	if (!ref) |  | ||||||
|  		return -ENOMEM; |  | ||||||
|   |  | ||||||
| -	/* BEFORE jffs2_build_xattr_subsystem() called,  |  | ||||||
| +	/* BEFORE jffs2_build_xattr_subsystem() called, |  | ||||||
|  	 * and AFTER xattr_ref is marked as a dead xref, |  | ||||||
|  	 * ref->xid is used to store 32bit xid, xd is not used |  | ||||||
|  	 * ref->ino is used to store 32bit inode-number, ic is not used |  | ||||||
| @@ -473,7 +476,7 @@ static int jffs2_scan_eraseblock (struct |  | ||||||
|  		struct jffs2_sum_marker *sm; |  | ||||||
|  		void *sumptr = NULL; |  | ||||||
|  		uint32_t sumlen; |  | ||||||
| -	       |  | ||||||
| + |  | ||||||
|  		if (!buf_size) { |  | ||||||
|  			/* XIP case. Just look, point at the summary if it's there */ |  | ||||||
|  			sm = (void *)buf + c->sector_size - sizeof(*sm); |  | ||||||
| @@ -489,9 +492,9 @@ static int jffs2_scan_eraseblock (struct |  | ||||||
|  				buf_len = sizeof(*sm); |  | ||||||
|   |  | ||||||
|  			/* Read as much as we want into the _end_ of the preallocated buffer */ |  | ||||||
| -			err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,  |  | ||||||
| +			err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, |  | ||||||
|  						  jeb->offset + c->sector_size - buf_len, |  | ||||||
| -						  buf_len);				 |  | ||||||
| +						  buf_len); |  | ||||||
|  			if (err) |  | ||||||
|  				return err; |  | ||||||
|   |  | ||||||
| @@ -510,9 +513,9 @@ static int jffs2_scan_eraseblock (struct |  | ||||||
|  				} |  | ||||||
|  				if (buf_len < sumlen) { |  | ||||||
|  					/* Need to read more so that the entire summary node is present */ |  | ||||||
| -					err = jffs2_fill_scan_buf(c, sumptr,  |  | ||||||
| +					err = jffs2_fill_scan_buf(c, sumptr, |  | ||||||
|  								  jeb->offset + c->sector_size - sumlen, |  | ||||||
| -								  sumlen - buf_len);				 |  | ||||||
| +								  sumlen - buf_len); |  | ||||||
|  					if (err) |  | ||||||
|  						return err; |  | ||||||
|  				} |  | ||||||
| @@ -525,7 +528,7 @@ static int jffs2_scan_eraseblock (struct |  | ||||||
|   |  | ||||||
|  			if (buf_size && sumlen > buf_size) |  | ||||||
|  				kfree(sumptr); |  | ||||||
| -			/* If it returns with a real error, bail.  |  | ||||||
| +			/* If it returns with a real error, bail. |  | ||||||
|  			   If it returns positive, that's a block classification |  | ||||||
|  			   (i.e. BLK_STATE_xxx) so return that too. |  | ||||||
|  			   If it returns zero, fall through to full scan. */ |  | ||||||
| @@ -546,6 +549,17 @@ static int jffs2_scan_eraseblock (struct |  | ||||||
|  			return err; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	if ((buf[0] == 0xde) && |  | ||||||
| +		(buf[1] == 0xad) && |  | ||||||
| +		(buf[2] == 0xc0) && |  | ||||||
| +		(buf[3] == 0xde)) { |  | ||||||
| +		/* end of filesystem. erase everything after this point */ |  | ||||||
| +		printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); |  | ||||||
| +		c->flags |= (1 << 7); |  | ||||||
| + |  | ||||||
| +		return BLK_STATE_ALLFF; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */ |  | ||||||
|  	ofs = 0; |  | ||||||
|   |  | ||||||
| @@ -671,7 +685,7 @@ scan_more: |  | ||||||
|  				scan_end = buf_len; |  | ||||||
|  				goto more_empty; |  | ||||||
|  			} |  | ||||||
| -			 |  | ||||||
| + |  | ||||||
|  			/* See how much more there is to read in this eraseblock... */ |  | ||||||
|  			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); |  | ||||||
|  			if (!buf_len) { |  | ||||||
| @@ -907,7 +921,7 @@ scan_more: |  | ||||||
|   |  | ||||||
|  	D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n", |  | ||||||
|  		  jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size)); |  | ||||||
| -	 |  | ||||||
| + |  | ||||||
|  	/* mark_node_obsolete can add to wasted !! */ |  | ||||||
|  	if (jeb->wasted_size) { |  | ||||||
|  		jeb->dirty_size += jeb->wasted_size; |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| --- a/include/linux/skbuff.h |  | ||||||
| +++ b/include/linux/skbuff.h |  | ||||||
| @@ -1365,11 +1365,18 @@ static inline int skb_network_offset(con |  | ||||||
|   * |  | ||||||
|   * Various parts of the networking layer expect at least 32 bytes of |  | ||||||
|   * headroom, you should not reduce this. |  | ||||||
| + * |  | ||||||
| + * This has been changed to 64 to acommodate for routing between ethernet |  | ||||||
| + * and wireless, but only for new allocations |  | ||||||
|   */ |  | ||||||
|  #ifndef NET_SKB_PAD |  | ||||||
|  #define NET_SKB_PAD	32 |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#ifndef NET_SKB_PAD_ALLOC |  | ||||||
| +#define NET_SKB_PAD_ALLOC	64 |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len); |  | ||||||
|   |  | ||||||
|  static inline void __skb_trim(struct sk_buff *skb, unsigned int len) |  | ||||||
| @@ -1459,9 +1466,9 @@ static inline void __skb_queue_purge(str |  | ||||||
|  static inline struct sk_buff *__dev_alloc_skb(unsigned int length, |  | ||||||
|  					      gfp_t gfp_mask) |  | ||||||
|  { |  | ||||||
| -	struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); |  | ||||||
| +	struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD_ALLOC, gfp_mask); |  | ||||||
|  	if (likely(skb)) |  | ||||||
| -		skb_reserve(skb, NET_SKB_PAD); |  | ||||||
| +		skb_reserve(skb, NET_SKB_PAD_ALLOC); |  | ||||||
|  	return skb; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1534,7 +1541,7 @@ static inline int __skb_cow(struct sk_bu |  | ||||||
|  		delta = headroom - skb_headroom(skb); |  | ||||||
|   |  | ||||||
|  	if (delta || cloned) |  | ||||||
| -		return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0, |  | ||||||
| +		return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD_ALLOC), 0, |  | ||||||
|  					GFP_ATOMIC); |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| --- a/net/core/skbuff.c |  | ||||||
| +++ b/net/core/skbuff.c |  | ||||||
| @@ -259,9 +259,9 @@ struct sk_buff *__netdev_alloc_skb(struc |  | ||||||
|  	int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; |  | ||||||
|  	struct sk_buff *skb; |  | ||||||
|   |  | ||||||
| -	skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); |  | ||||||
| +	skb = __alloc_skb(length + NET_SKB_PAD_ALLOC, gfp_mask, 0, node); |  | ||||||
|  	if (likely(skb)) { |  | ||||||
| -		skb_reserve(skb, NET_SKB_PAD); |  | ||||||
| +		skb_reserve(skb, NET_SKB_PAD_ALLOC); |  | ||||||
|  		skb->dev = dev; |  | ||||||
|  	} |  | ||||||
|  	return skb; |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| --- /dev/null |  | ||||||
| +++ b/include/asm-powerpc/segment.h |  | ||||||
| @@ -0,0 +1,6 @@ |  | ||||||
| +#ifndef _ASM_SEGMENT_H |  | ||||||
| +#define _ASM_SEGMENT_H |  | ||||||
| + |  | ||||||
| +/* Only here because we have some old header files that expect it.. */ |  | ||||||
| + |  | ||||||
| +#endif /* _ASM_SEGMENT_H */ |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| --- a/arch/mips/Makefile |  | ||||||
| +++ b/arch/mips/Makefile |  | ||||||
| @@ -48,7 +48,9 @@ ifneq ($(SUBARCH),$(ARCH)) |  | ||||||
|    endif |  | ||||||
|  endif |  | ||||||
|   |  | ||||||
| +ifndef CONFIG_PROFILING |  | ||||||
|  cflags-y := -ffunction-sections |  | ||||||
| +endif |  | ||||||
|  cflags-y += $(call cc-option, -mno-check-zero-division) |  | ||||||
|   |  | ||||||
|  ifdef CONFIG_32BIT |  | ||||||
| --- a/arch/mips/oprofile/op_model_mipsxx.c |  | ||||||
| +++ b/arch/mips/oprofile/op_model_mipsxx.c |  | ||||||
| @@ -298,6 +298,11 @@ static void reset_counters(void *arg) |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id) |  | ||||||
| +{ |  | ||||||
| +	return mipsxx_perfcount_handler(); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static int __init mipsxx_init(void) |  | ||||||
|  { |  | ||||||
|  	int counters; |  | ||||||
| @@ -374,6 +379,10 @@ static int __init mipsxx_init(void) |  | ||||||
|  	save_perf_irq = perf_irq; |  | ||||||
|  	perf_irq = mipsxx_perfcount_handler; |  | ||||||
|   |  | ||||||
| +	if (cp0_perfcount_irq >= 0) |  | ||||||
| +		return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, |  | ||||||
| +			IRQF_SHARED, "Perfcounter", save_perf_irq); |  | ||||||
| + |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -381,6 +390,9 @@ static void mipsxx_exit(void) |  | ||||||
|  { |  | ||||||
|  	int counters = op_model_mipsxx_ops.num_counters; |  | ||||||
|   |  | ||||||
| +	if (cp0_perfcount_irq >= 0) |  | ||||||
| +		free_irq(cp0_perfcount_irq, save_perf_irq); |  | ||||||
| + |  | ||||||
|  	counters = counters_per_cpu_to_total(counters); |  | ||||||
|  	on_each_cpu(reset_counters, (void *)(long)counters, 1); |  | ||||||
|   |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,143 +0,0 @@ | |||||||
| --- a/fs/mini_fo/main.c |  | ||||||
| +++ b/fs/mini_fo/main.c |  | ||||||
| @@ -79,6 +79,7 @@ mini_fo_tri_interpose(dentry_t *hidden_d |  | ||||||
|  	 * of the new inode's fields |  | ||||||
|  	 */ |  | ||||||
|   |  | ||||||
| +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) |  | ||||||
|  	/* |  | ||||||
|  	 * original: inode = iget(sb, hidden_inode->i_ino); |  | ||||||
|  	 */ |  | ||||||
| @@ -87,6 +88,13 @@ mini_fo_tri_interpose(dentry_t *hidden_d |  | ||||||
|  		err = -EACCES;		/* should be impossible??? */ |  | ||||||
|  		goto out; |  | ||||||
|  	} |  | ||||||
| +#else |  | ||||||
| +	inode = mini_fo_iget(sb, iunique(sb, 25)); |  | ||||||
| +	if (IS_ERR(inode)) { |  | ||||||
| +		err = PTR_ERR(inode); |  | ||||||
| +		goto out; |  | ||||||
| +	} |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
|  	 * interpose the inode if not already interposed |  | ||||||
| @@ -184,9 +192,9 @@ mini_fo_parse_options(super_block_t *sb, |  | ||||||
|  				hidden_root = ERR_PTR(err); |  | ||||||
|  				goto out; |  | ||||||
|  			} |  | ||||||
| -			hidden_root = nd.dentry; |  | ||||||
| -			stopd(sb)->base_dir_dentry = nd.dentry; |  | ||||||
| -			stopd(sb)->hidden_mnt = nd.mnt; |  | ||||||
| +			hidden_root = nd_get_dentry(&nd); |  | ||||||
| +			stopd(sb)->base_dir_dentry = nd_get_dentry(&nd); |  | ||||||
| +			stopd(sb)->hidden_mnt = nd_get_mnt(&nd); |  | ||||||
|   |  | ||||||
|  		} else if(!strncmp("sto=", options, 4)) { |  | ||||||
|  			/* parse the storage dir */ |  | ||||||
| @@ -204,9 +212,9 @@ mini_fo_parse_options(super_block_t *sb, |  | ||||||
|  				hidden_root2 = ERR_PTR(err); |  | ||||||
|  				goto out; |  | ||||||
|  			} |  | ||||||
| -			hidden_root2 = nd2.dentry; |  | ||||||
| -			stopd(sb)->storage_dir_dentry = nd2.dentry; |  | ||||||
| -			stopd(sb)->hidden_mnt2 = nd2.mnt; |  | ||||||
| +			hidden_root2 = nd_get_dentry(&nd2); |  | ||||||
| +			stopd(sb)->storage_dir_dentry = nd_get_dentry(&nd2); |  | ||||||
| +			stopd(sb)->hidden_mnt2 = nd_get_mnt(&nd2); |  | ||||||
|  			stohs2(sb) = hidden_root2->d_sb; |  | ||||||
|   |  | ||||||
|  			/* validate storage dir, this is done in |  | ||||||
| --- a/fs/mini_fo/mini_fo.h |  | ||||||
| +++ b/fs/mini_fo/mini_fo.h |  | ||||||
| @@ -302,6 +302,10 @@ extern int mini_fo_tri_interpose(dentry_ |  | ||||||
|  extern int mini_fo_cp_cont(dentry_t *tgt_dentry, struct vfsmount *tgt_mnt, |  | ||||||
|  			   dentry_t *src_dentry, struct vfsmount *src_mnt); |  | ||||||
|   |  | ||||||
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) |  | ||||||
| +extern struct inode *mini_fo_iget(struct super_block *sb, unsigned long ino); |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
|  extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd); |  | ||||||
|   |  | ||||||
| @@ -501,6 +505,29 @@ static inline void double_unlock(struct |  | ||||||
|  #endif  /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ |  | ||||||
|  #endif /* __KERNEL__ */ |  | ||||||
|   |  | ||||||
| + |  | ||||||
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) |  | ||||||
| +static inline dentry_t *nd_get_dentry(struct nameidata *nd) |  | ||||||
| +{ |  | ||||||
| +	return (nd->path.dentry); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline struct vfsmount *nd_get_mnt(struct nameidata *nd) |  | ||||||
| +{ |  | ||||||
| +	return (nd->path.mnt); |  | ||||||
| +} |  | ||||||
| +#else |  | ||||||
| +static inline dentry_t *nd_get_dentry(struct nameidata *nd) |  | ||||||
| +{ |  | ||||||
| +	return (nd->dentry); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline struct vfsmount *nd_get_mnt(struct nameidata *nd) |  | ||||||
| +{ |  | ||||||
| +	return (nd->mnt); |  | ||||||
| +} |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  /* |  | ||||||
|   * Definitions for user and kernel code |  | ||||||
|   */ |  | ||||||
| --- a/fs/mini_fo/super.c |  | ||||||
| +++ b/fs/mini_fo/super.c |  | ||||||
| @@ -262,10 +262,31 @@ mini_fo_umount_begin(super_block_t *sb) |  | ||||||
|  } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) |  | ||||||
| +struct inode * |  | ||||||
| +mini_fo_iget(struct super_block *sb, unsigned long ino) |  | ||||||
| +{ |  | ||||||
| +	struct inode *inode; |  | ||||||
| + |  | ||||||
| +	inode = iget_locked(sb, ino); |  | ||||||
| +	if (!inode) |  | ||||||
| +		return ERR_PTR(-ENOMEM); |  | ||||||
| + |  | ||||||
| +	if (!(inode->i_state & I_NEW)) |  | ||||||
| +		return inode; |  | ||||||
| + |  | ||||||
| +	mini_fo_read_inode(inode); |  | ||||||
| + |  | ||||||
| +	unlock_new_inode(inode); |  | ||||||
| +	return inode; |  | ||||||
| +} |  | ||||||
| +#endif /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) */ |  | ||||||
|   |  | ||||||
|  struct super_operations mini_fo_sops = |  | ||||||
|  { |  | ||||||
| +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) |  | ||||||
|  	read_inode:		mini_fo_read_inode, |  | ||||||
| +#endif |  | ||||||
|  #if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) |  | ||||||
|  	write_inode:	mini_fo_write_inode, |  | ||||||
|  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ |  | ||||||
| --- a/fs/mini_fo/aux.c |  | ||||||
| +++ b/fs/mini_fo/aux.c |  | ||||||
| @@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb, |  | ||||||
|  	err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd); |  | ||||||
|   |  | ||||||
|  	/* validate */ |  | ||||||
| -	if (err || !nd.dentry || !nd.dentry->d_inode) { |  | ||||||
| +	if (err || !nd_get_dentry(&nd) || !nd_get_dentry(&nd)->d_inode) { |  | ||||||
|  		printk(KERN_CRIT "mini_fo: bpath_walk: path_walk failed.\n"); |  | ||||||
|  		return NULL; |  | ||||||
|  	} |  | ||||||
| -	return nd.dentry; |  | ||||||
| +	return nd_get_dentry(&nd); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| --- a/fs/mini_fo/meta.c |  | ||||||
| +++ b/fs/mini_fo/meta.c |  | ||||||
| @@ -442,6 +442,11 @@ int meta_write_d_entry(dentry_t *dentry, |  | ||||||
|  			   S_IRUSR | S_IWUSR); |  | ||||||
|  #endif |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	/* $%& err, is this correct? */ |  | ||||||
| +	meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2; |  | ||||||
| +	mntget(meta_mnt); |  | ||||||
| + |  | ||||||
|          /* open META-file for writing */ |  | ||||||
|          meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
| @@ -535,6 +540,11 @@ int meta_write_r_entry(dentry_t *dentry, |  | ||||||
|  			   meta_dentry, S_IRUSR | S_IWUSR); |  | ||||||
|  #endif |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	/* $%& err, is this correct? */ |  | ||||||
| +	meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2; |  | ||||||
| +	mntget(meta_mnt); |  | ||||||
| + |  | ||||||
|          /* open META-file for writing */ |  | ||||||
|          meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
| @@ -671,14 +681,16 @@ int meta_sync_d_list(dentry_t *dentry, i |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	/* $%& err, is this correct? */ |  | ||||||
| +	meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2; |  | ||||||
| +	mntget(meta_mnt); |  | ||||||
| + |  | ||||||
|          /* open META-file for writing */ |  | ||||||
|          meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|                  printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ |  | ||||||
|                                    ERROR opening meta file.\n"); |  | ||||||
| -		/* we don't mntget so we dont't mntput (for now) |  | ||||||
| -		 * mntput(meta_mnt); |  | ||||||
| -		 */ |  | ||||||
| +		mntput(meta_mnt); |  | ||||||
|  		dput(meta_dentry); |  | ||||||
|  		err = -1; |  | ||||||
|                  goto out; |  | ||||||
| @@ -811,14 +823,16 @@ int meta_sync_r_list(dentry_t *dentry, i |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	/* $%& err, is this correct? */ |  | ||||||
| +	meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2; |  | ||||||
| +	mntget(meta_mnt); |  | ||||||
| + |  | ||||||
|          /* open META-file for writing */ |  | ||||||
|          meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|                  printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ |  | ||||||
|                                    ERROR opening meta file.\n"); |  | ||||||
| -		/* we don't mntget so we dont't mntput (for now) |  | ||||||
| -		 * mntput(meta_mnt); |  | ||||||
| -		 */ |  | ||||||
| +		mntput(meta_mnt); |  | ||||||
|  		dput(meta_dentry); |  | ||||||
|  		err = -1; |  | ||||||
|                  goto out; |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| --- a/fs/mini_fo/super.c |  | ||||||
| +++ b/fs/mini_fo/super.c |  | ||||||
| @@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int |  | ||||||
|  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ |  | ||||||
|   |  | ||||||
|   |  | ||||||
| +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) |  | ||||||
|  STATIC void |  | ||||||
|  mini_fo_put_inode(inode_t *inode) |  | ||||||
|  { |  | ||||||
| @@ -99,6 +100,7 @@ mini_fo_put_inode(inode_t *inode) |  | ||||||
|  	if (atomic_read(&inode->i_count) == 1) |  | ||||||
|  		inode->i_nlink = 0; |  | ||||||
|  } |  | ||||||
| +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */ |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  #if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) |  | ||||||
| @@ -238,7 +240,7 @@ mini_fo_clear_inode(inode_t *inode) |  | ||||||
|   * dies. |  | ||||||
|   */ |  | ||||||
|  STATIC void |  | ||||||
| -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) |  | ||||||
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) |  | ||||||
|  mini_fo_umount_begin(struct vfsmount *mnt, int flags) |  | ||||||
|  { |  | ||||||
|  	struct vfsmount *hidden_mnt; |  | ||||||
| @@ -290,7 +292,9 @@ struct super_operations mini_fo_sops = |  | ||||||
|  #if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) |  | ||||||
|  	write_inode:	mini_fo_write_inode, |  | ||||||
|  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ |  | ||||||
| +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) |  | ||||||
|  	put_inode:		mini_fo_put_inode, |  | ||||||
| +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */ |  | ||||||
|  #if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) |  | ||||||
|  	delete_inode:	mini_fo_delete_inode, |  | ||||||
|  #endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ |  | ||||||
| @@ -1,41 +0,0 @@ | |||||||
| --- a/fs/mini_fo/inode.c |  | ||||||
| +++ b/fs/mini_fo/inode.c |  | ||||||
| @@ -439,7 +439,7 @@ mini_fo_symlink(inode_t *dir, dentry_t * |  | ||||||
|  	int err=0; |  | ||||||
|  	dentry_t *hidden_sto_dentry; |  | ||||||
|  	dentry_t *hidden_sto_dir_dentry; |  | ||||||
| -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) |  | ||||||
|          umode_t mode; |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| @@ -466,7 +466,7 @@ mini_fo_symlink(inode_t *dir, dentry_t * |  | ||||||
|  	down(&hidden_sto_dir_dentry->d_inode->i_sem); |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) |  | ||||||
|  	mode = S_IALLUGO; |  | ||||||
|  	err = vfs_symlink(hidden_sto_dir_dentry->d_inode, |  | ||||||
|  			  hidden_sto_dentry, symname, mode); |  | ||||||
| @@ -1128,7 +1128,7 @@ void mini_fo_put_link(struct dentry *den |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  STATIC int |  | ||||||
| -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) |  | ||||||
|  mini_fo_permission(inode_t *inode, int mask, struct nameidata *nd) |  | ||||||
|  #else |  | ||||||
|  mini_fo_permission(inode_t *inode, int mask) |  | ||||||
| @@ -1150,8 +1150,9 @@ mini_fo_permission(inode_t *inode, int m |  | ||||||
|  	 *	if (err) |  | ||||||
|  	 *		goto out; |  | ||||||
|  	 */ |  | ||||||
| - |  | ||||||
| -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) |  | ||||||
| +	err = inode_permission(hidden_inode, mask); |  | ||||||
| +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
|  	err = permission(hidden_inode, mask, nd); |  | ||||||
|  #else |  | ||||||
|  	err = permission(hidden_inode, mask); |  | ||||||
| @@ -1,96 +0,0 @@ | |||||||
| --- a/fs/mini_fo/aux.c |  | ||||||
| +++ b/fs/mini_fo/aux.c |  | ||||||
| @@ -236,7 +236,7 @@ int mini_fo_cp_cont(dentry_t *tgt_dentry |  | ||||||
|  	mntget(src_mnt); |  | ||||||
|   |  | ||||||
|  	/* open file write only */ |  | ||||||
| -	tgt_file = dentry_open(tgt_dentry, tgt_mnt, 0x1); |  | ||||||
| +	tgt_file = dentry_open(tgt_dentry, tgt_mnt, 0x1, current_cred()); |  | ||||||
|  	if(!tgt_file || IS_ERR(tgt_file)) { |  | ||||||
|  		printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening target file.\n"); |  | ||||||
|  		err = PTR_ERR(tgt_file); |  | ||||||
| @@ -244,7 +244,7 @@ int mini_fo_cp_cont(dentry_t *tgt_dentry |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* open file read only */ |  | ||||||
| -	src_file = dentry_open(src_dentry, src_mnt, 0x0); |  | ||||||
| +	src_file = dentry_open(src_dentry, src_mnt, 0x0, current_cred()); |  | ||||||
|  	if(!src_file || IS_ERR(src_file)) { |  | ||||||
|  		printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening source file.\n"); |  | ||||||
|  		err = PTR_ERR(src_file); |  | ||||||
| --- a/fs/mini_fo/file.c |  | ||||||
| +++ b/fs/mini_fo/file.c |  | ||||||
| @@ -437,7 +437,7 @@ mini_fo_open(inode_t *inode, file_t *fil |  | ||||||
|  			mntget(stopd(inode->i_sb)->hidden_mnt); |  | ||||||
|  			hidden_file = dentry_open(hidden_dentry, |  | ||||||
|  						  stopd(inode->i_sb)->hidden_mnt, |  | ||||||
| -						  hidden_flags); |  | ||||||
| +						  hidden_flags, file->f_cred); |  | ||||||
|  			if (IS_ERR(hidden_file)) { |  | ||||||
|  				err = PTR_ERR(hidden_file); |  | ||||||
|  				dput(hidden_dentry); |  | ||||||
| @@ -479,7 +479,7 @@ mini_fo_open(inode_t *inode, file_t *fil |  | ||||||
|  			mntget(stopd(inode->i_sb)->hidden_mnt); |  | ||||||
|  			hidden_file = dentry_open(hidden_dentry, |  | ||||||
|  						  stopd(inode->i_sb)->hidden_mnt, |  | ||||||
| -						  hidden_flags); |  | ||||||
| +						  hidden_flags, file->f_cred); |  | ||||||
|  			if (IS_ERR(hidden_file)) { |  | ||||||
|  				err = PTR_ERR(hidden_file); |  | ||||||
|  				dput(hidden_dentry); |  | ||||||
| @@ -512,7 +512,7 @@ mini_fo_open(inode_t *inode, file_t *fil |  | ||||||
|  	mntget(stopd(inode->i_sb)->hidden_mnt2); |  | ||||||
|  	hidden_sto_file = dentry_open(hidden_sto_dentry, |  | ||||||
|  				      stopd(inode->i_sb)->hidden_mnt2, |  | ||||||
| -				      hidden_flags); |  | ||||||
| +				      hidden_flags, file->f_cred); |  | ||||||
|   |  | ||||||
|  	/* dentry_open dputs the dentry if it fails */ |  | ||||||
|  	if (IS_ERR(hidden_sto_file)) { |  | ||||||
| --- a/fs/mini_fo/meta.c |  | ||||||
| +++ b/fs/mini_fo/meta.c |  | ||||||
| @@ -56,7 +56,7 @@ int meta_build_lists(dentry_t *dentry) |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  		/* open META-file for reading */ |  | ||||||
| -		meta_file = dentry_open(meta_dentry, meta_mnt, 0x0); |  | ||||||
| +		meta_file = dentry_open(meta_dentry, meta_mnt, 0x0, current_cred()); |  | ||||||
|  		if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|  			printk(KERN_CRIT "mini_fo: meta_build_lists: \ |  | ||||||
|                                            ERROR opening META file.\n"); |  | ||||||
| @@ -448,7 +448,7 @@ int meta_write_d_entry(dentry_t *dentry, |  | ||||||
|  	mntget(meta_mnt); |  | ||||||
|   |  | ||||||
|          /* open META-file for writing */ |  | ||||||
| -        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
| +        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred()); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|                  printk(KERN_CRIT "mini_fo: meta_write_d_entry: \ |  | ||||||
|                                    ERROR opening meta file.\n"); |  | ||||||
| @@ -546,7 +546,7 @@ int meta_write_r_entry(dentry_t *dentry, |  | ||||||
|  	mntget(meta_mnt); |  | ||||||
|   |  | ||||||
|          /* open META-file for writing */ |  | ||||||
| -        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
| +        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred()); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|                  printk(KERN_CRIT "mini_fo: meta_write_r_entry: \ |  | ||||||
|                                    ERROR opening meta file.\n"); |  | ||||||
| @@ -686,7 +686,7 @@ int meta_sync_d_list(dentry_t *dentry, i |  | ||||||
|  	mntget(meta_mnt); |  | ||||||
|   |  | ||||||
|          /* open META-file for writing */ |  | ||||||
| -        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
| +        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred()); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|                  printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ |  | ||||||
|                                    ERROR opening meta file.\n"); |  | ||||||
| @@ -828,7 +828,7 @@ int meta_sync_r_list(dentry_t *dentry, i |  | ||||||
|  	mntget(meta_mnt); |  | ||||||
|   |  | ||||||
|          /* open META-file for writing */ |  | ||||||
| -        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); |  | ||||||
| +        meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred()); |  | ||||||
|          if(!meta_file || IS_ERR(meta_file)) { |  | ||||||
|                  printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ |  | ||||||
|                                    ERROR opening meta file.\n"); |  | ||||||
| @@ -1,157 +0,0 @@ | |||||||
| --- a/fs/mini_fo/aux.c |  | ||||||
| +++ b/fs/mini_fo/aux.c |  | ||||||
| @@ -86,8 +86,10 @@ int get_neg_sto_dentry(dentry_t *dentry) |  | ||||||
|  	len = dentry->d_name.len; |  | ||||||
|  	name = dentry->d_name.name; |  | ||||||
|   |  | ||||||
| +	mutex_lock(&dtohd2(dentry->d_parent)->d_inode->i_mutex); |  | ||||||
|  	dtohd2(dentry) = |  | ||||||
|  		lookup_one_len(name, dtohd2(dentry->d_parent), len); |  | ||||||
| +	mutex_unlock(&dtohd2(dentry->d_parent)->d_inode->i_mutex); |  | ||||||
|   |  | ||||||
|   out: |  | ||||||
|  	return err; |  | ||||||
| @@ -426,7 +428,9 @@ int build_sto_structure(dentry_t *dir, d |  | ||||||
|  		const unsigned char *name; |  | ||||||
|  		len = dtohd(dentry)->d_name.len; |  | ||||||
|  		name = dtohd(dentry)->d_name.name; |  | ||||||
| +		mutex_lock(&dtohd2(dir)->d_inode->i_mutex); |  | ||||||
|  		hidden_sto_dentry = lookup_one_len(name, dtohd2(dir), len); |  | ||||||
| +		mutex_unlock(&dtohd2(dir)->d_inode->i_mutex); |  | ||||||
|  		dtohd2(dentry) = hidden_sto_dentry; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| --- a/fs/mini_fo/inode.c |  | ||||||
| +++ b/fs/mini_fo/inode.c |  | ||||||
| @@ -113,17 +113,23 @@ mini_fo_lookup(inode_t *dir, dentry_t *d |  | ||||||
|  		hidden_dir_dentry = hidden_dentry->d_parent; |  | ||||||
|  		kfree(bpath); |  | ||||||
|  	} |  | ||||||
| -	else if(hidden_dir_dentry && hidden_dir_dentry->d_inode) |  | ||||||
| +	else if(hidden_dir_dentry && hidden_dir_dentry->d_inode) { |  | ||||||
| +		mutex_lock(&hidden_dir_dentry->d_inode->i_mutex); |  | ||||||
|  		hidden_dentry = |  | ||||||
|  			lookup_one_len(name, hidden_dir_dentry, namelen); |  | ||||||
| -	else |  | ||||||
| +		mutex_unlock(&hidden_dir_dentry->d_inode->i_mutex); |  | ||||||
| +	} else { |  | ||||||
|  		hidden_dentry = NULL; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
| -	if(hidden_sto_dir_dentry && hidden_sto_dir_dentry->d_inode) |  | ||||||
| +	if(hidden_sto_dir_dentry && hidden_sto_dir_dentry->d_inode) { |  | ||||||
| +		mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); |  | ||||||
|  		hidden_sto_dentry = |  | ||||||
|  			lookup_one_len(name, hidden_sto_dir_dentry, namelen); |  | ||||||
| -	else |  | ||||||
| +		mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); |  | ||||||
| +	} else { |  | ||||||
|  		hidden_sto_dentry =  NULL; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	/* catch error in lookup */ |  | ||||||
|  	if (IS_ERR(hidden_dentry) || IS_ERR(hidden_sto_dentry)) { |  | ||||||
| @@ -553,9 +559,11 @@ mini_fo_rmdir(inode_t *dir, dentry_t *de |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  		/* Delete an old WOL file contained in the storage dir */ |  | ||||||
| +		mutex_lock(&hidden_sto_dentry->d_inode->i_mutex); |  | ||||||
|  		meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  					     hidden_sto_dentry, |  | ||||||
|  					     strlen(META_FILENAME)); |  | ||||||
| +		mutex_unlock(&hidden_sto_dentry->d_inode->i_mutex); |  | ||||||
|  		if(meta_dentry->d_inode) { |  | ||||||
|  			err = vfs_unlink(hidden_sto_dentry->d_inode, meta_dentry); |  | ||||||
|  			dput(meta_dentry); |  | ||||||
| @@ -643,9 +651,11 @@ mini_fo_rmdir(inode_t *dir, dentry_t *de |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  		/* Delete an old WOL file contained in the storage dir */ |  | ||||||
| +		mutex_lock(&hidden_sto_dentry->d_inode->i_mutex); |  | ||||||
|  		meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  					     hidden_sto_dentry, |  | ||||||
|  					     strlen(META_FILENAME)); |  | ||||||
| +		mutex_unlock(&hidden_sto_dentry->d_inode->i_mutex); |  | ||||||
|  		if(meta_dentry->d_inode) { |  | ||||||
|  			/* is this necessary? dget(meta_dentry); */ |  | ||||||
|  			err = vfs_unlink(hidden_sto_dentry->d_inode, |  | ||||||
| @@ -688,9 +698,11 @@ mini_fo_rmdir(inode_t *dir, dentry_t *de |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  		/* Delete an old WOL file contained in the storage dir */ |  | ||||||
| +		mutex_lock(&hidden_sto_dentry->d_inode->i_mutex); |  | ||||||
|  		meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  					     hidden_sto_dentry, |  | ||||||
|  					     strlen(META_FILENAME)); |  | ||||||
| +		mutex_unlock(&hidden_sto_dentry->d_inode->i_mutex); |  | ||||||
|  		if(meta_dentry->d_inode) { |  | ||||||
|  			/* is this necessary? dget(meta_dentry); */ |  | ||||||
|  			err = vfs_unlink(hidden_sto_dentry->d_inode, |  | ||||||
| --- a/fs/mini_fo/meta.c |  | ||||||
| +++ b/fs/mini_fo/meta.c |  | ||||||
| @@ -43,9 +43,11 @@ int meta_build_lists(dentry_t *dentry) |  | ||||||
|   |  | ||||||
|    	/* might there be a META-file? */ |  | ||||||
|  	if(dtohd2(dentry) && dtohd2(dentry)->d_inode) { |  | ||||||
| +		mutex_lock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|  		meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  					     dtohd2(dentry), |  | ||||||
|  					     strlen(META_FILENAME)); |  | ||||||
| +		mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|  		if(!meta_dentry->d_inode) { |  | ||||||
|  			dput(meta_dentry); |  | ||||||
|  			goto out_ok; |  | ||||||
| @@ -426,8 +428,11 @@ int meta_write_d_entry(dentry_t *dentry, |  | ||||||
|  			goto out; |  | ||||||
|                  } |  | ||||||
|          } |  | ||||||
| + |  | ||||||
| +	mutex_lock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|  	meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  				     dtohd2(dentry), strlen (META_FILENAME)); |  | ||||||
| +	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|   |  | ||||||
|  	/* We need to create a META-file */ |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
| @@ -527,9 +532,13 @@ int meta_write_r_entry(dentry_t *dentry, |  | ||||||
|  			goto out; |  | ||||||
|                  } |  | ||||||
|          } |  | ||||||
| + |  | ||||||
| +	mutex_lock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|  	meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  				     dtohd2(dentry), |  | ||||||
|  				     strlen (META_FILENAME)); |  | ||||||
| +	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| + |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
|                  /* We need to create a META-file */ |  | ||||||
|  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| @@ -641,9 +650,13 @@ int meta_sync_d_list(dentry_t *dentry, i |  | ||||||
|  			goto out; |  | ||||||
|                  } |  | ||||||
|          } |  | ||||||
| + |  | ||||||
| +	mutex_lock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|  	meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  				     dtohd2(dentry), |  | ||||||
|  				     strlen(META_FILENAME)); |  | ||||||
| +	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| + |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
|                  /* We need to create a META-file */ |  | ||||||
|  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| @@ -784,9 +797,13 @@ int meta_sync_r_list(dentry_t *dentry, i |  | ||||||
|  			goto out; |  | ||||||
|                  } |  | ||||||
|          } |  | ||||||
| + |  | ||||||
| +	mutex_lock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
|  	meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  				     dtohd2(dentry), |  | ||||||
|  				     strlen(META_FILENAME)); |  | ||||||
| +	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| + |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
|                  /* We need to create a META-file */ |  | ||||||
|  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| --- a/fs/mini_fo/state.c |  | ||||||
| +++ b/fs/mini_fo/state.c |  | ||||||
| @@ -537,17 +537,17 @@ int nondir_mod_to_del(dentry_t *dentry) |  | ||||||
|  	dtohd(dentry) = NULL; |  | ||||||
|  	dtost(dentry) = DELETED; |  | ||||||
|   |  | ||||||
| -	/* add deleted file to META-file */ |  | ||||||
| -	meta_add_d_entry(dentry->d_parent, |  | ||||||
| -			 dentry->d_name.name, |  | ||||||
| -			 dentry->d_name.len); |  | ||||||
| - |  | ||||||
|  	/* was: unlock_dir(hidden_sto_dir_dentry); */ |  | ||||||
|  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) |  | ||||||
|  	mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); |  | ||||||
|  #else |  | ||||||
|  	up(&hidden_sto_dir_dentry->d_inode->i_sem); |  | ||||||
|  #endif |  | ||||||
| +	/* add deleted file to META-file */ |  | ||||||
| +	meta_add_d_entry(dentry->d_parent, |  | ||||||
| +			 dentry->d_name.name, |  | ||||||
| +			 dentry->d_name.len); |  | ||||||
| + |  | ||||||
|  	dput(hidden_sto_dir_dentry); |  | ||||||
|   |  | ||||||
|   out: |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| --- a/fs/mini_fo/meta.c |  | ||||||
| +++ b/fs/mini_fo/meta.c |  | ||||||
| @@ -48,6 +48,9 @@ int meta_build_lists(dentry_t *dentry) |  | ||||||
|  					     dtohd2(dentry), |  | ||||||
|  					     strlen(META_FILENAME)); |  | ||||||
|  		mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| +		if (IS_ERR(meta_dentry)) |  | ||||||
| +			goto out_ok; |  | ||||||
| + |  | ||||||
|  		if(!meta_dentry->d_inode) { |  | ||||||
|  			dput(meta_dentry); |  | ||||||
|  			goto out_ok; |  | ||||||
| @@ -433,6 +436,8 @@ int meta_write_d_entry(dentry_t *dentry, |  | ||||||
|  	meta_dentry = lookup_one_len(META_FILENAME, |  | ||||||
|  				     dtohd2(dentry), strlen (META_FILENAME)); |  | ||||||
|  	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| +	if (IS_ERR(meta_dentry)) |  | ||||||
| +		return PTR_ERR(meta_dentry); |  | ||||||
|   |  | ||||||
|  	/* We need to create a META-file */ |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
| @@ -538,6 +543,8 @@ int meta_write_r_entry(dentry_t *dentry, |  | ||||||
|  				     dtohd2(dentry), |  | ||||||
|  				     strlen (META_FILENAME)); |  | ||||||
|  	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| +	if (IS_ERR(meta_dentry)) |  | ||||||
| +		return PTR_ERR(meta_dentry); |  | ||||||
|   |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
|                  /* We need to create a META-file */ |  | ||||||
| @@ -656,6 +663,8 @@ int meta_sync_d_list(dentry_t *dentry, i |  | ||||||
|  				     dtohd2(dentry), |  | ||||||
|  				     strlen(META_FILENAME)); |  | ||||||
|  	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| +	if (IS_ERR(meta_dentry)) |  | ||||||
| +		return PTR_ERR(meta_dentry); |  | ||||||
|   |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
|                  /* We need to create a META-file */ |  | ||||||
| @@ -803,6 +812,8 @@ int meta_sync_r_list(dentry_t *dentry, i |  | ||||||
|  				     dtohd2(dentry), |  | ||||||
|  				     strlen(META_FILENAME)); |  | ||||||
|  	mutex_unlock(&dtohd2(dentry)->d_inode->i_mutex); |  | ||||||
| +	if (IS_ERR(meta_dentry)) |  | ||||||
| +		return PTR_ERR(meta_dentry); |  | ||||||
|   |  | ||||||
|          if(!meta_dentry->d_inode) { |  | ||||||
|                  /* We need to create a META-file */ |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| --- a/lib/kobject_uevent.c |  | ||||||
| +++ b/lib/kobject_uevent.c |  | ||||||
| @@ -29,7 +29,8 @@ u64 uevent_seqnum; |  | ||||||
|  char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH; |  | ||||||
|  static DEFINE_SPINLOCK(sequence_lock); |  | ||||||
|  #if defined(CONFIG_NET) |  | ||||||
| -static struct sock *uevent_sock; |  | ||||||
| +struct sock *uevent_sock = NULL; |  | ||||||
| +EXPORT_SYMBOL_GPL(uevent_sock); |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  /* the strings here must match the enum in include/linux/kobject.h */ |  | ||||||
| @@ -42,6 +43,18 @@ static const char *kobject_actions[] = { |  | ||||||
|  	[KOBJ_OFFLINE] =	"offline", |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +u64 uevent_next_seqnum(void) |  | ||||||
| +{ |  | ||||||
| +	u64 seq; |  | ||||||
| + |  | ||||||
| +	spin_lock(&sequence_lock); |  | ||||||
| +	seq = ++uevent_seqnum; |  | ||||||
| +	spin_unlock(&sequence_lock); |  | ||||||
| + |  | ||||||
| +	return seq; |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL_GPL(uevent_next_seqnum); |  | ||||||
| + |  | ||||||
|  /** |  | ||||||
|   * kobject_action_type - translate action string to numeric type |  | ||||||
|   * |  | ||||||
| @@ -201,9 +214,7 @@ int kobject_uevent_env(struct kobject *k |  | ||||||
|  		kobj->state_remove_uevent_sent = 1; |  | ||||||
|   |  | ||||||
|  	/* we will send an event, so request a new sequence number */ |  | ||||||
| -	spin_lock(&sequence_lock); |  | ||||||
| -	seq = ++uevent_seqnum; |  | ||||||
| -	spin_unlock(&sequence_lock); |  | ||||||
| +	seq = uevent_next_seqnum(); |  | ||||||
|  	retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto exit; |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/sound/core/Kconfig |  | ||||||
| +++ b/sound/core/Kconfig |  | ||||||
| @@ -7,7 +7,7 @@ config SND_PCM |  | ||||||
|  	select SND_TIMER |  | ||||||
|   |  | ||||||
|  config SND_HWDEP |  | ||||||
| -	tristate |  | ||||||
| +	tristate "Sound hardware support" |  | ||||||
|   |  | ||||||
|  config SND_RAWMIDI |  | ||||||
|  	tristate |  | ||||||
| @@ -1,146 +0,0 @@ | |||||||
| --- a/drivers/mtd/mtdpart.c |  | ||||||
| +++ b/drivers/mtd/mtdpart.c |  | ||||||
| @@ -21,6 +21,8 @@ |  | ||||||
|  #include <linux/root_dev.h> |  | ||||||
|  #include <linux/magic.h> |  | ||||||
|   |  | ||||||
| +#define MTD_ERASE_PARTIAL	0x8000 /* partition only covers parts of an erase block */ |  | ||||||
| + |  | ||||||
|  /* Our partition linked list */ |  | ||||||
|  static LIST_HEAD(mtd_partitions); |  | ||||||
|   |  | ||||||
| @@ -226,13 +228,60 @@ static int part_erase(struct mtd_info *m |  | ||||||
|  		return -EROFS; |  | ||||||
|  	if (instr->addr >= mtd->size) |  | ||||||
|  		return -EINVAL; |  | ||||||
| + |  | ||||||
| +	instr->partial_start = false; |  | ||||||
| +	if (mtd->flags & MTD_ERASE_PARTIAL) { |  | ||||||
| +		size_t readlen = 0; |  | ||||||
| +		u64 mtd_ofs; |  | ||||||
| + |  | ||||||
| +		instr->erase_buf = kmalloc(part->master->erasesize, GFP_ATOMIC); |  | ||||||
| +		if (!instr->erase_buf) |  | ||||||
| +			return -ENOMEM; |  | ||||||
| + |  | ||||||
| +		mtd_ofs = part->offset + instr->addr; |  | ||||||
| +		instr->erase_buf_ofs = do_div(mtd_ofs, part->master->erasesize); |  | ||||||
| + |  | ||||||
| +		if (instr->erase_buf_ofs > 0) { |  | ||||||
| +			instr->addr -= instr->erase_buf_ofs; |  | ||||||
| +			ret = part->master->read(part->master, |  | ||||||
| +				instr->addr + part->offset, |  | ||||||
| +				part->master->erasesize, |  | ||||||
| +				&readlen, instr->erase_buf); |  | ||||||
| + |  | ||||||
| +			instr->partial_start = true; |  | ||||||
| +		} else { |  | ||||||
| +			mtd_ofs = part->offset + part->mtd.size; |  | ||||||
| +			instr->erase_buf_ofs = part->master->erasesize - |  | ||||||
| +				do_div(mtd_ofs, part->master->erasesize); |  | ||||||
| + |  | ||||||
| +			if (instr->erase_buf_ofs > 0) { |  | ||||||
| +				instr->len += instr->erase_buf_ofs; |  | ||||||
| +				ret = part->master->read(part->master, |  | ||||||
| +					part->offset + instr->addr + |  | ||||||
| +					instr->len - part->master->erasesize, |  | ||||||
| +					part->master->erasesize, &readlen, |  | ||||||
| +					instr->erase_buf); |  | ||||||
| +			} else { |  | ||||||
| +				ret = 0; |  | ||||||
| +			} |  | ||||||
| +		} |  | ||||||
| +		if (ret < 0) { |  | ||||||
| +			kfree(instr->erase_buf); |  | ||||||
| +			return ret; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	instr->addr += part->offset; |  | ||||||
|  	ret = part->master->erase(part->master, instr); |  | ||||||
|  	if (ret) { |  | ||||||
|  		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |  | ||||||
|  			instr->fail_addr -= part->offset; |  | ||||||
|  		instr->addr -= part->offset; |  | ||||||
| +		if (mtd->flags & MTD_ERASE_PARTIAL) |  | ||||||
| +			kfree(instr->erase_buf); |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -240,7 +289,25 @@ void mtd_erase_callback(struct erase_inf |  | ||||||
|  { |  | ||||||
|  	if (instr->mtd->erase == part_erase) { |  | ||||||
|  		struct mtd_part *part = PART(instr->mtd); |  | ||||||
| +		size_t wrlen = 0; |  | ||||||
|   |  | ||||||
| +		if (instr->mtd->flags & MTD_ERASE_PARTIAL) { |  | ||||||
| +			if (instr->partial_start) { |  | ||||||
| +				part->master->write(part->master, |  | ||||||
| +					instr->addr, instr->erase_buf_ofs, |  | ||||||
| +					&wrlen, instr->erase_buf); |  | ||||||
| +				instr->addr += instr->erase_buf_ofs; |  | ||||||
| +			} else { |  | ||||||
| +				instr->len -= instr->erase_buf_ofs; |  | ||||||
| +				part->master->write(part->master, |  | ||||||
| +					instr->addr + instr->len, |  | ||||||
| +					instr->erase_buf_ofs, &wrlen, |  | ||||||
| +					instr->erase_buf + |  | ||||||
| +					part->master->erasesize - |  | ||||||
| +					instr->erase_buf_ofs); |  | ||||||
| +			} |  | ||||||
| +			kfree(instr->erase_buf); |  | ||||||
| +		} |  | ||||||
|  		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |  | ||||||
|  			instr->fail_addr -= part->offset; |  | ||||||
|  		instr->addr -= part->offset; |  | ||||||
| @@ -473,18 +540,24 @@ static struct mtd_part *add_one_partitio |  | ||||||
|  	if ((slave->mtd.flags & MTD_WRITEABLE) && |  | ||||||
|  	    mtd_mod_by_eb(slave->offset, &slave->mtd)) { |  | ||||||
|  		/* Doesn't start on a boundary of major erase size */ |  | ||||||
| -		/* FIXME: Let it be writable if it is on a boundary of |  | ||||||
| -		 * _minor_ erase size though */ |  | ||||||
| -		slave->mtd.flags &= ~MTD_WRITEABLE; |  | ||||||
| -		printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", |  | ||||||
| -			part->name); |  | ||||||
| +		slave->mtd.flags |= MTD_ERASE_PARTIAL; |  | ||||||
| +		if (((u32) slave->mtd.size) > master->erasesize) |  | ||||||
| +			slave->mtd.flags &= ~MTD_WRITEABLE; |  | ||||||
| +		else |  | ||||||
| +			slave->mtd.erasesize = slave->mtd.size; |  | ||||||
|  	} |  | ||||||
|  	if ((slave->mtd.flags & MTD_WRITEABLE) && |  | ||||||
| -	    mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) { |  | ||||||
| -		slave->mtd.flags &= ~MTD_WRITEABLE; |  | ||||||
| -		printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", |  | ||||||
| -			part->name); |  | ||||||
| -	} |  | ||||||
| +	    mtd_mod_by_eb(slave->offset + slave->mtd.size, &slave->mtd)) { |  | ||||||
| +		slave->mtd.flags |= MTD_ERASE_PARTIAL; |  | ||||||
| + |  | ||||||
| +		if ((u32) slave->mtd.size > master->erasesize) |  | ||||||
| +			slave->mtd.flags &= ~MTD_WRITEABLE; |  | ||||||
| +		else |  | ||||||
| +			slave->mtd.erasesize = slave->mtd.size; |  | ||||||
| +	} |  | ||||||
| +	if ((slave->mtd.flags & (MTD_ERASE_PARTIAL|MTD_WRITEABLE)) == MTD_ERASE_PARTIAL) |  | ||||||
| +		printk(KERN_WARNING"mtd: partition \"%s\" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only\n", |  | ||||||
| +				part->name); |  | ||||||
|   |  | ||||||
|  	slave->mtd.ecclayout = master->ecclayout; |  | ||||||
|  	if (master->block_isbad) { |  | ||||||
| --- a/include/linux/mtd/mtd.h |  | ||||||
| +++ b/include/linux/mtd/mtd.h |  | ||||||
| @@ -46,6 +46,10 @@ struct erase_info { |  | ||||||
|  	u_long priv; |  | ||||||
|  	u_char state; |  | ||||||
|  	struct erase_info *next; |  | ||||||
| + |  | ||||||
| +	u8 *erase_buf; |  | ||||||
| +	u32 erase_buf_ofs; |  | ||||||
| +	bool partial_start; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  struct mtd_erase_region_info { |  | ||||||
| @@ -1,69 +0,0 @@ | |||||||
| --- a/include/linux/kobject.h |  | ||||||
| +++ b/include/linux/kobject.h |  | ||||||
| @@ -30,6 +30,8 @@ |  | ||||||
|  #define UEVENT_NUM_ENVP			32	/* number of env pointers */ |  | ||||||
|  #define UEVENT_BUFFER_SIZE		2048	/* buffer for the variables */ |  | ||||||
|   |  | ||||||
| +struct sk_buff; |  | ||||||
| + |  | ||||||
|  /* path to the userspace helper executed on an event */ |  | ||||||
|  extern char uevent_helper[]; |  | ||||||
|   |  | ||||||
| @@ -208,6 +210,10 @@ int add_uevent_var(struct kobj_uevent_en |  | ||||||
|   |  | ||||||
|  int kobject_action_type(const char *buf, size_t count, |  | ||||||
|  			enum kobject_action *type); |  | ||||||
| + |  | ||||||
| +int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, |  | ||||||
| +		     gfp_t allocation); |  | ||||||
| + |  | ||||||
|  #else |  | ||||||
|  static inline int kobject_uevent(struct kobject *kobj, |  | ||||||
|  				 enum kobject_action action) |  | ||||||
| @@ -224,6 +230,16 @@ static inline int add_uevent_var(struct |  | ||||||
|  static inline int kobject_action_type(const char *buf, size_t count, |  | ||||||
|  				      enum kobject_action *type) |  | ||||||
|  { return -EINVAL; } |  | ||||||
| + |  | ||||||
| +void kfree_skb(struct sk_buff *); |  | ||||||
| + |  | ||||||
| +static inline int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, |  | ||||||
| +				   gfp_t allocation) |  | ||||||
| +{ |  | ||||||
| +	kfree_skb(skb); |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  #endif /* _KOBJECT_H_ */ |  | ||||||
| --- a/lib/kobject_uevent.c |  | ||||||
| +++ b/lib/kobject_uevent.c |  | ||||||
| @@ -330,6 +330,27 @@ int add_uevent_var(struct kobj_uevent_en |  | ||||||
|  EXPORT_SYMBOL_GPL(add_uevent_var); |  | ||||||
|   |  | ||||||
|  #if defined(CONFIG_NET) |  | ||||||
| +int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, |  | ||||||
| +		     gfp_t allocation) |  | ||||||
| +{ |  | ||||||
| +	if (!uevent_sock) { |  | ||||||
| +		kfree_skb(skb); |  | ||||||
| +		return -ENODEV; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return netlink_broadcast(uevent_sock, skb, pid, group, allocation);; |  | ||||||
| +} |  | ||||||
| +#else |  | ||||||
| +int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, |  | ||||||
| +		     gfp_t allocation) |  | ||||||
| +{ |  | ||||||
| +	kfree_skb(skb); |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| +#endif |  | ||||||
| +EXPORT_SYMBOL_GPL(broadcast_uevent); |  | ||||||
| + |  | ||||||
| +#if defined(CONFIG_NET) |  | ||||||
|  static int __init kobject_uevent_init(void) |  | ||||||
|  { |  | ||||||
|  	uevent_sock = netlink_kernel_create(&init_net, NETLINK_KOBJECT_UEVENT, |  | ||||||
| @@ -1,132 +0,0 @@ | |||||||
| This patch allows the user to specify desired packet types (outgoing, |  | ||||||
| broadcast, unicast, etc.) on packet sockets via setsockopt. |  | ||||||
| This can reduce the load in situations where only a limited number |  | ||||||
| of packet types are necessary |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@openwrt.org> |  | ||||||
|  |  | ||||||
| --- a/include/linux/if_packet.h |  | ||||||
| +++ b/include/linux/if_packet.h |  | ||||||
| @@ -31,6 +31,8 @@ struct sockaddr_ll |  | ||||||
|  /* These ones are invisible by user level */ |  | ||||||
|  #define PACKET_LOOPBACK		5		/* MC/BRD frame looped back */ |  | ||||||
|  #define PACKET_FASTROUTE	6		/* Fastrouted frame	*/ |  | ||||||
| +#define PACKET_MASK_ANY		0xffffffff	/* mask for packet type bits */ |  | ||||||
| + |  | ||||||
|   |  | ||||||
|  /* Packet socket options */ |  | ||||||
|   |  | ||||||
| @@ -48,6 +50,7 @@ struct sockaddr_ll |  | ||||||
|  #define PACKET_RESERVE			12 |  | ||||||
|  #define PACKET_TX_RING			13 |  | ||||||
|  #define PACKET_LOSS			14 |  | ||||||
| +#define PACKET_RECV_TYPE		15 |  | ||||||
|   |  | ||||||
|  struct tpacket_stats |  | ||||||
|  { |  | ||||||
| --- a/net/packet/af_packet.c |  | ||||||
| +++ b/net/packet/af_packet.c |  | ||||||
| @@ -204,6 +204,7 @@ struct packet_sock { |  | ||||||
|  	unsigned int		tp_reserve; |  | ||||||
|  	unsigned int		tp_loss:1; |  | ||||||
|  #endif |  | ||||||
| +	unsigned int		pkt_type; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  struct packet_skb_cb { |  | ||||||
| @@ -342,6 +343,7 @@ static int packet_rcv_spkt(struct sk_buf |  | ||||||
|  { |  | ||||||
|  	struct sock *sk; |  | ||||||
|  	struct sockaddr_pkt *spkt; |  | ||||||
| +	struct packet_sock *po; |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
|  	 *	When we registered the protocol we saved the socket in the data |  | ||||||
| @@ -349,6 +351,7 @@ static int packet_rcv_spkt(struct sk_buf |  | ||||||
|  	 */ |  | ||||||
|   |  | ||||||
|  	sk = pt->af_packet_priv; |  | ||||||
| +	po = pkt_sk(sk); |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
|  	 *	Yank back the headers [hope the device set this |  | ||||||
| @@ -361,7 +364,7 @@ static int packet_rcv_spkt(struct sk_buf |  | ||||||
|  	 *	so that this procedure is noop. |  | ||||||
|  	 */ |  | ||||||
|   |  | ||||||
| -	if (skb->pkt_type == PACKET_LOOPBACK) |  | ||||||
| +	if (!(po->pkt_type & (1 << skb->pkt_type))) |  | ||||||
|  		goto out; |  | ||||||
|   |  | ||||||
|  	if (dev_net(dev) != sock_net(sk)) |  | ||||||
| @@ -545,12 +548,12 @@ static int packet_rcv(struct sk_buff *sk |  | ||||||
|  	int skb_len = skb->len; |  | ||||||
|  	unsigned int snaplen, res; |  | ||||||
|   |  | ||||||
| -	if (skb->pkt_type == PACKET_LOOPBACK) |  | ||||||
| -		goto drop; |  | ||||||
| - |  | ||||||
|  	sk = pt->af_packet_priv; |  | ||||||
|  	po = pkt_sk(sk); |  | ||||||
|   |  | ||||||
| +	if (!(po->pkt_type & (1 << skb->pkt_type))) |  | ||||||
| +		goto drop; |  | ||||||
| + |  | ||||||
|  	if (dev_net(dev) != sock_net(sk)) |  | ||||||
|  		goto drop; |  | ||||||
|   |  | ||||||
| @@ -667,12 +670,12 @@ static int tpacket_rcv(struct sk_buff *s |  | ||||||
|  	struct timeval tv; |  | ||||||
|  	struct timespec ts; |  | ||||||
|   |  | ||||||
| -	if (skb->pkt_type == PACKET_LOOPBACK) |  | ||||||
| -		goto drop; |  | ||||||
| - |  | ||||||
|  	sk = pt->af_packet_priv; |  | ||||||
|  	po = pkt_sk(sk); |  | ||||||
|   |  | ||||||
| +	if (!(po->pkt_type & (1 << skb->pkt_type))) |  | ||||||
| +		goto drop; |  | ||||||
| + |  | ||||||
|  	if (dev_net(dev) != sock_net(sk)) |  | ||||||
|  		goto drop; |  | ||||||
|   |  | ||||||
| @@ -1390,6 +1393,7 @@ static int packet_create(struct net *net |  | ||||||
|  	spin_lock_init(&po->bind_lock); |  | ||||||
|  	mutex_init(&po->pg_vec_lock); |  | ||||||
|  	po->prot_hook.func = packet_rcv; |  | ||||||
| +	po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); |  | ||||||
|   |  | ||||||
|  	if (sock->type == SOCK_PACKET) |  | ||||||
|  		po->prot_hook.func = packet_rcv_spkt; |  | ||||||
| @@ -1737,6 +1741,16 @@ packet_setsockopt(struct socket *sock, i |  | ||||||
|  			ret = packet_mc_drop(sk, &mreq); |  | ||||||
|  		return ret; |  | ||||||
|  	} |  | ||||||
| +	case PACKET_RECV_TYPE: |  | ||||||
| +	{ |  | ||||||
| +		unsigned int val; |  | ||||||
| +		if (optlen != sizeof(val)) |  | ||||||
| +			return -EINVAL; |  | ||||||
| +		if (copy_from_user(&val, optval, sizeof(val))) |  | ||||||
| +			return -EFAULT; |  | ||||||
| +		po->pkt_type = val & ~PACKET_LOOPBACK; |  | ||||||
| +		return 0; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_PACKET_MMAP |  | ||||||
|  	case PACKET_RX_RING: |  | ||||||
| @@ -1882,6 +1896,13 @@ static int packet_getsockopt(struct sock |  | ||||||
|   |  | ||||||
|  		data = &val; |  | ||||||
|  		break; |  | ||||||
| +	case PACKET_RECV_TYPE: |  | ||||||
| +		if (len > sizeof(unsigned int)) |  | ||||||
| +			len = sizeof(unsigned int); |  | ||||||
| +		val = po->pkt_type; |  | ||||||
| + |  | ||||||
| +		data = &val; |  | ||||||
| +		break; |  | ||||||
|  #ifdef CONFIG_PACKET_MMAP |  | ||||||
|  	case PACKET_VERSION: |  | ||||||
|  		if (len > sizeof(int)) |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| --- a/drivers/net/pppoe.c |  | ||||||
| +++ b/drivers/net/pppoe.c |  | ||||||
| @@ -863,7 +863,7 @@ static int pppoe_sendmsg(struct kiocb *i |  | ||||||
|  		goto end; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -	skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32, |  | ||||||
| +	skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32 + NET_SKB_PAD, |  | ||||||
|  			   0, GFP_KERNEL); |  | ||||||
|  	if (!skb) { |  | ||||||
|  		error = -ENOMEM; |  | ||||||
| @@ -871,7 +871,7 @@ static int pppoe_sendmsg(struct kiocb *i |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* Reserve space for headers. */ |  | ||||||
| -	skb_reserve(skb, dev->hard_header_len); |  | ||||||
| +	skb_reserve(skb, dev->hard_header_len + NET_SKB_PAD); |  | ||||||
|  	skb_reset_network_header(skb); |  | ||||||
|   |  | ||||||
|  	skb->dev = dev; |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| --- a/include/linux/atm.h |  | ||||||
| +++ b/include/linux/atm.h |  | ||||||
| @@ -139,6 +139,9 @@ struct atm_trafprm { |  | ||||||
|  	int		min_pcr;	/* minimum PCR in cells per second */ |  | ||||||
|  	int		max_cdv;	/* maximum CDV in microseconds */ |  | ||||||
|  	int		max_sdu;	/* maximum SDU in bytes */ |  | ||||||
| +	int		scr;		/* sustained rate in cells per second */ |  | ||||||
| +	int		mbs;		/* maximum burst size (MBS) in cells */ |  | ||||||
| +	int		cdv;		/* Cell delay varition */ |  | ||||||
|          /* extra params for ABR */ |  | ||||||
|          unsigned int 	icr;         	/* Initial Cell Rate (24-bit) */ |  | ||||||
|          unsigned int	tbe;		/* Transient Buffer Exposure (24-bit) */  |  | ||||||
| @@ -1,63 +0,0 @@ | |||||||
| --- a/crypto/Kconfig |  | ||||||
| +++ b/crypto/Kconfig |  | ||||||
| @@ -96,6 +96,10 @@ config CRYPTO_MANAGER2 |  | ||||||
|  	select CRYPTO_BLKCIPHER2 |  | ||||||
|  	select CRYPTO_PCOMP |  | ||||||
|   |  | ||||||
| +config CRYPTO_MANAGER_NO_TESTS |  | ||||||
| +	bool "Disable internal testsuite to save space" |  | ||||||
| +	depends on CRYPTO_MANAGER |  | ||||||
| + |  | ||||||
|  config CRYPTO_GF128MUL |  | ||||||
|  	tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" |  | ||||||
|  	depends on EXPERIMENTAL |  | ||||||
| --- a/crypto/testmgr.c |  | ||||||
| +++ b/crypto/testmgr.c |  | ||||||
| @@ -47,6 +47,8 @@ |  | ||||||
|  #define ENCRYPT 1 |  | ||||||
|  #define DECRYPT 0 |  | ||||||
|   |  | ||||||
| +#ifndef CONFIG_CRYPTO_MANAGER_NO_TESTS |  | ||||||
| + |  | ||||||
|  struct tcrypt_result { |  | ||||||
|  	struct completion completion; |  | ||||||
|  	int err; |  | ||||||
| @@ -2434,8 +2436,11 @@ static int alg_find_test(const char *alg |  | ||||||
|  	return -1; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +#endif /* CONFIG_CRYPTO_MANAGER_NO_TESTS */ |  | ||||||
| + |  | ||||||
|  int alg_test(const char *driver, const char *alg, u32 type, u32 mask) |  | ||||||
|  { |  | ||||||
| +#ifndef CONFIG_CRYPTO_MANAGER_NO_TESTS |  | ||||||
|  	int i; |  | ||||||
|  	int j; |  | ||||||
|  	int rc; |  | ||||||
| @@ -2490,5 +2495,8 @@ notest: |  | ||||||
|  	return 0; |  | ||||||
|  non_fips_alg: |  | ||||||
|  	return -EINVAL; |  | ||||||
| +#else /* CONFIG_CRYPTO_MANAGER_NO_TESTS */ |  | ||||||
| +	return 0; |  | ||||||
| +#endif /* CONFIG_CRYPTO_MANAGER_NO_TESTS */ |  | ||||||
|  } |  | ||||||
|  EXPORT_SYMBOL_GPL(alg_test); |  | ||||||
| --- a/crypto/testmgr.h |  | ||||||
| +++ b/crypto/testmgr.h |  | ||||||
| @@ -20,6 +20,8 @@ |  | ||||||
|   |  | ||||||
|  #include <crypto/compress.h> |  | ||||||
|   |  | ||||||
| +#ifndef CONFIG_CRYPTO_MANAGER_NO_TESTS |  | ||||||
| + |  | ||||||
|  #define MAX_DIGEST_SIZE		64 |  | ||||||
|  #define MAX_TAP			8 |  | ||||||
|   |  | ||||||
| @@ -9537,4 +9539,6 @@ static struct hash_testvec crc32c_tv_tem |  | ||||||
|  	}, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +#endif /* CONFIG_CRYPTO_MANAGER_NO_TESTS */ |  | ||||||
| + |  | ||||||
|  #endif	/* _CRYPTO_TESTMGR_H */ |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| --- a/net/bridge/br_input.c |  | ||||||
| +++ b/net/bridge/br_input.c |  | ||||||
| @@ -61,7 +61,11 @@ int br_handle_frame_finish(struct sk_buf |  | ||||||
|   |  | ||||||
|  	dst = NULL; |  | ||||||
|   |  | ||||||
| -	if (is_multicast_ether_addr(dest)) { |  | ||||||
| +	if (skb->protocol == htons(ETH_P_PAE)) { |  | ||||||
| +		skb2 = skb; |  | ||||||
| +		/* Do not forward 802.1x/EAP frames */ |  | ||||||
| +		skb = NULL; |  | ||||||
| +	} else if (is_multicast_ether_addr(dest)) { |  | ||||||
|  		br->dev->stats.multicast++; |  | ||||||
|  		skb2 = skb; |  | ||||||
|  	} else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) { |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/net/bridge/br_input.c |  | ||||||
| +++ b/net/bridge/br_input.c |  | ||||||
| @@ -50,7 +50,7 @@ int br_handle_frame_finish(struct sk_buf |  | ||||||
|  	br = p->br; |  | ||||||
|  	br_fdb_update(br, p, eth_hdr(skb)->h_source); |  | ||||||
|   |  | ||||||
| -	if (p->state == BR_STATE_LEARNING) |  | ||||||
| +	if ((p->state == BR_STATE_LEARNING) && skb->protocol != htons(ETH_P_PAE)) |  | ||||||
|  		goto drop; |  | ||||||
|   |  | ||||||
|  	/* The packet skb2 goes to the local host (NULL to skip). */ |  | ||||||
| @@ -1,172 +0,0 @@ | |||||||
| --- /dev/null |  | ||||||
| +++ b/net/sched/act_connmark.c |  | ||||||
| @@ -0,0 +1,137 @@ |  | ||||||
| +/* |  | ||||||
| + * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify it |  | ||||||
| + * under the terms and conditions of the GNU General Public License, |  | ||||||
| + * version 2, as published by the Free Software Foundation. |  | ||||||
| + * |  | ||||||
| + * This program is distributed in the hope it will be useful, but WITHOUT |  | ||||||
| + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |  | ||||||
| + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for |  | ||||||
| + * more details. |  | ||||||
| + * |  | ||||||
| + * You should have received a copy of the GNU General Public License along with |  | ||||||
| + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |  | ||||||
| + * Place - Suite 330, Boston, MA 02111-1307 USA. |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#include <linux/init.h> |  | ||||||
| +#include <linux/kernel.h> |  | ||||||
| +#include <linux/skbuff.h> |  | ||||||
| +#include <linux/rtnetlink.h> |  | ||||||
| +#include <linux/pkt_cls.h> |  | ||||||
| +#include <linux/ip.h> |  | ||||||
| +#include <linux/ipv6.h> |  | ||||||
| +#include <net/netlink.h> |  | ||||||
| +#include <net/pkt_sched.h> |  | ||||||
| +#include <net/act_api.h> |  | ||||||
| + |  | ||||||
| +#include <net/netfilter/nf_conntrack.h> |  | ||||||
| +#include <net/netfilter/nf_conntrack_core.h> |  | ||||||
| + |  | ||||||
| +#define TCA_ACT_CONNMARK	20 |  | ||||||
| + |  | ||||||
| +#define CONNMARK_TAB_MASK     3 |  | ||||||
| +static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1]; |  | ||||||
| +static u32 connmark_idx_gen; |  | ||||||
| +static DEFINE_RWLOCK(connmark_lock); |  | ||||||
| + |  | ||||||
| +static struct tcf_hashinfo connmark_hash_info = { |  | ||||||
| +	.htab	=	tcf_connmark_ht, |  | ||||||
| +	.hmask	=	CONNMARK_TAB_MASK, |  | ||||||
| +	.lock	=	&connmark_lock, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +static int tcf_connmark(struct sk_buff *skb, struct tc_action *a, |  | ||||||
| +		       struct tcf_result *res) |  | ||||||
| +{ |  | ||||||
| +	struct nf_conn *c; |  | ||||||
| +	enum ip_conntrack_info ctinfo; |  | ||||||
| +	int proto; |  | ||||||
| +	int r; |  | ||||||
| + |  | ||||||
| +	if (skb->protocol == htons(ETH_P_IP)) { |  | ||||||
| +		if (skb->len < sizeof(struct iphdr)) |  | ||||||
| +			goto out; |  | ||||||
| +		proto = PF_INET; |  | ||||||
| +	} else if (skb->protocol == htons(ETH_P_IPV6)) { |  | ||||||
| +		if (skb->len < sizeof(struct ipv6hdr)) |  | ||||||
| +			goto out; |  | ||||||
| +		proto = PF_INET6; |  | ||||||
| +	} else |  | ||||||
| +		goto out; |  | ||||||
| + |  | ||||||
| +	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb); |  | ||||||
| +	if (r != NF_ACCEPT) |  | ||||||
| +		goto out; |  | ||||||
| + |  | ||||||
| +	c = nf_ct_get(skb, &ctinfo); |  | ||||||
| +	if (!c) |  | ||||||
| +		goto out; |  | ||||||
| + |  | ||||||
| +	skb->mark = c->mark; |  | ||||||
| +	nf_conntrack_put(skb->nfct); |  | ||||||
| +	skb->nfct = NULL; |  | ||||||
| + |  | ||||||
| +out: |  | ||||||
| +	return TC_ACT_PIPE; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, |  | ||||||
| +			 struct tc_action *a, int ovr, int bind) |  | ||||||
| +{ |  | ||||||
| +	struct tcf_common *pc; |  | ||||||
| + |  | ||||||
| +	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, |  | ||||||
| +			     &connmark_idx_gen, &connmark_hash_info); |  | ||||||
| +	if (IS_ERR(pc)) |  | ||||||
| +	    return PTR_ERR(pc); |  | ||||||
| + |  | ||||||
| +	tcf_hash_insert(pc, &connmark_hash_info); |  | ||||||
| + |  | ||||||
| +	return ACT_P_CREATED; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) |  | ||||||
| +{ |  | ||||||
| +	if (a->priv) |  | ||||||
| +		return tcf_hash_release(a->priv, bind, &connmark_hash_info); |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, |  | ||||||
| +				int bind, int ref) |  | ||||||
| +{ |  | ||||||
| +	return skb->len; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct tc_action_ops act_connmark_ops = { |  | ||||||
| +	.kind		=	"connmark", |  | ||||||
| +	.hinfo		=	&connmark_hash_info, |  | ||||||
| +	.type		=	TCA_ACT_CONNMARK, |  | ||||||
| +	.capab		=	TCA_CAP_NONE, |  | ||||||
| +	.owner		=	THIS_MODULE, |  | ||||||
| +	.act		=	tcf_connmark, |  | ||||||
| +	.dump		=	tcf_connmark_dump, |  | ||||||
| +	.cleanup	=	tcf_connmark_cleanup, |  | ||||||
| +	.init		=	tcf_connmark_init, |  | ||||||
| +	.walk		=	tcf_generic_walker, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>"); |  | ||||||
| +MODULE_DESCRIPTION("Connection tracking mark restoring"); |  | ||||||
| +MODULE_LICENSE("GPL"); |  | ||||||
| + |  | ||||||
| +static int __init connmark_init_module(void) |  | ||||||
| +{ |  | ||||||
| +	return tcf_register_action(&act_connmark_ops); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void __exit connmark_cleanup_module(void) |  | ||||||
| +{ |  | ||||||
| +	tcf_unregister_action(&act_connmark_ops); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +module_init(connmark_init_module); |  | ||||||
| +module_exit(connmark_cleanup_module); |  | ||||||
| --- a/net/sched/Kconfig |  | ||||||
| +++ b/net/sched/Kconfig |  | ||||||
| @@ -546,6 +546,19 @@ config NET_ACT_SKBEDIT |  | ||||||
|  	  To compile this code as a module, choose M here: the |  | ||||||
|  	  module will be called skbedit. |  | ||||||
|   |  | ||||||
| +config NET_ACT_CONNMARK |  | ||||||
| +        tristate "Connection Tracking Marking" |  | ||||||
| +        depends on NET_CLS_ACT |  | ||||||
| +        depends on NF_CONNTRACK |  | ||||||
| +	 depends on NF_CONNTRACK_MARK |  | ||||||
| +        ---help--- |  | ||||||
| +	  Say Y here to restore the connmark from a scheduler action |  | ||||||
| + |  | ||||||
| +	  If unsure, say N. |  | ||||||
| + |  | ||||||
| +	  To compile this code as a module, choose M here: the |  | ||||||
| +	  module will be called act_connmark. |  | ||||||
| + |  | ||||||
|  config NET_CLS_IND |  | ||||||
|  	bool "Incoming device classification" |  | ||||||
|  	depends on NET_CLS_U32 || NET_CLS_FW |  | ||||||
| --- a/net/sched/Makefile |  | ||||||
| +++ b/net/sched/Makefile |  | ||||||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT)	+= act_nat.o |  | ||||||
|  obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o |  | ||||||
|  obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o |  | ||||||
|  obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o |  | ||||||
| +obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o |  | ||||||
|  obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o |  | ||||||
| @@ -1,41 +0,0 @@ | |||||||
| --- a/net/ipv6/ndisc.c |  | ||||||
| +++ b/net/ipv6/ndisc.c |  | ||||||
| @@ -1105,6 +1105,18 @@ errout: |  | ||||||
|  	rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static inline int accept_ra(struct inet6_dev *in6_dev) |  | ||||||
| +{ |  | ||||||
| +	/* |  | ||||||
| +	 * If forwarding is enabled, RA are not accepted unless the special |  | ||||||
| +	 * hybrid mode (accept_ra=2) is enabled. |  | ||||||
| +	 */ |  | ||||||
| +	if (in6_dev->cnf.forwarding && in6_dev->cnf.accept_ra < 2) |  | ||||||
| +		return 0; |  | ||||||
| + |  | ||||||
| +	return in6_dev->cnf.accept_ra; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static void ndisc_router_discovery(struct sk_buff *skb) |  | ||||||
|  { |  | ||||||
|  	struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb); |  | ||||||
| @@ -1158,8 +1170,7 @@ static void ndisc_router_discovery(struc |  | ||||||
|  		return; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	/* skip route and link configuration on routers */ |  | ||||||
| -	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) |  | ||||||
| +	if (!accept_ra(in6_dev)) |  | ||||||
|  		goto skip_linkparms; |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_IPV6_NDISC_NODETYPE |  | ||||||
| @@ -1309,8 +1320,7 @@ skip_linkparms: |  | ||||||
|  			     NEIGH_UPDATE_F_ISROUTER); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	/* skip route and link configuration on routers */ |  | ||||||
| -	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) |  | ||||||
| +	if (!accept_ra(in6_dev)) |  | ||||||
|  		goto out; |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_IPV6_ROUTE_INFO |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| --- a/net/ipv6/addrconf.c |  | ||||||
| +++ b/net/ipv6/addrconf.c |  | ||||||
| @@ -2888,7 +2888,8 @@ static void addrconf_dad_completed(struc |  | ||||||
|  	   start sending router solicitations. |  | ||||||
|  	 */ |  | ||||||
|   |  | ||||||
| -	if (ifp->idev->cnf.forwarding == 0 && |  | ||||||
| +	if ((ifp->idev->cnf.forwarding == 0 || |  | ||||||
| +	     ifp->idev->cnf.forwarding == 2) && |  | ||||||
|  	    ifp->idev->cnf.rtr_solicits > 0 && |  | ||||||
|  	    (dev->flags&IFF_LOOPBACK) == 0 && |  | ||||||
|  	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { |  | ||||||
| @@ -1,84 +0,0 @@ | |||||||
| --- a/drivers/usb/core/usb.c |  | ||||||
| +++ b/drivers/usb/core/usb.c |  | ||||||
| @@ -651,6 +651,71 @@ exit: |  | ||||||
|  	return dev; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static struct usb_device *match_device_name(struct usb_device *dev, |  | ||||||
| +					    const char *name) |  | ||||||
| +{ |  | ||||||
| +	struct usb_device *ret_dev = NULL; |  | ||||||
| +	int child; |  | ||||||
| + |  | ||||||
| +	dev_dbg(&dev->dev, "check for name %s ...\n", name); |  | ||||||
| + |  | ||||||
| +	/* see if this device matches */ |  | ||||||
| +	if (strcmp(dev_name(&dev->dev), name) == 0 ) { |  | ||||||
| +		dev_dbg(&dev->dev, "matched this device!\n"); |  | ||||||
| +		ret_dev = usb_get_dev(dev); |  | ||||||
| +		goto exit; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	/* look through all of the children of this device */ |  | ||||||
| +	for (child = 0; child < dev->maxchild; ++child) { |  | ||||||
| +		if (dev->children[child]) { |  | ||||||
| +			usb_lock_device(dev->children[child]); |  | ||||||
| +			ret_dev = match_device_name(dev->children[child], name); |  | ||||||
| +			usb_unlock_device(dev->children[child]); |  | ||||||
| +			if (ret_dev) |  | ||||||
| +				goto exit; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| +exit: |  | ||||||
| +	return ret_dev; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * usb_find_device_by_name - find a specific usb device in the system |  | ||||||
| + * @name: the name of the device to find |  | ||||||
| + * |  | ||||||
| + * Returns a pointer to a struct usb_device if such a specified usb |  | ||||||
| + * device is present in the system currently.  The usage count of the |  | ||||||
| + * device will be incremented if a device is found.  Make sure to call |  | ||||||
| + * usb_put_dev() when the caller is finished with the device. |  | ||||||
| + * |  | ||||||
| + * If a device with the specified bus id is not found, NULL is returned. |  | ||||||
| + */ |  | ||||||
| +struct usb_device *usb_find_device_by_name(const char *name) |  | ||||||
| +{ |  | ||||||
| +	struct list_head *buslist; |  | ||||||
| +	struct usb_bus *bus; |  | ||||||
| +	struct usb_device *dev = NULL; |  | ||||||
| + |  | ||||||
| +	mutex_lock(&usb_bus_list_lock); |  | ||||||
| +	for (buslist = usb_bus_list.next; |  | ||||||
| +	     buslist != &usb_bus_list; |  | ||||||
| +	     buslist = buslist->next) { |  | ||||||
| +		bus = container_of(buslist, struct usb_bus, bus_list); |  | ||||||
| +		if (!bus->root_hub) |  | ||||||
| +			continue; |  | ||||||
| +		usb_lock_device(bus->root_hub); |  | ||||||
| +		dev = match_device_name(bus->root_hub, name); |  | ||||||
| +		usb_unlock_device(bus->root_hub); |  | ||||||
| +		if (dev) |  | ||||||
| +			goto exit; |  | ||||||
| +	} |  | ||||||
| +exit: |  | ||||||
| +	mutex_unlock(&usb_bus_list_lock); |  | ||||||
| +	return dev; |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL_GPL(usb_find_device_by_name); |  | ||||||
| + |  | ||||||
|  /** |  | ||||||
|   * usb_get_current_frame_number - return current bus frame number |  | ||||||
|   * @dev: the device whose bus is being queried |  | ||||||
| --- a/include/linux/usb.h |  | ||||||
| +++ b/include/linux/usb.h |  | ||||||
| @@ -540,6 +540,7 @@ extern int usb_reset_device(struct usb_d |  | ||||||
|  extern void usb_queue_reset_device(struct usb_interface *dev); |  | ||||||
|   |  | ||||||
|  extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); |  | ||||||
| +extern struct usb_device *usb_find_device_by_name(const char *name); |  | ||||||
|   |  | ||||||
|  /* USB autosuspend and autoresume */ |  | ||||||
|  #ifdef CONFIG_USB_SUSPEND |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| --- a/drivers/leds/Kconfig |  | ||||||
| +++ b/drivers/leds/Kconfig |  | ||||||
| @@ -304,4 +304,8 @@ config LEDS_TRIGGER_DEFAULT_ON |  | ||||||
|  comment "iptables trigger is under Netfilter config (LED target)" |  | ||||||
|  	depends on LEDS_TRIGGERS |  | ||||||
|   |  | ||||||
| +config LEDS_TRIGGER_MORSE |  | ||||||
| +	tristate "LED Morse Trigger" |  | ||||||
| +	depends on LEDS_TRIGGERS |  | ||||||
| + |  | ||||||
|  endif # NEW_LEDS |  | ||||||
| --- a/drivers/leds/Makefile |  | ||||||
| +++ b/drivers/leds/Makefile |  | ||||||
| @@ -40,3 +40,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)	+= |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= ledtrig-backlight.o |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o |  | ||||||
| +obj-$(CONFIG_LEDS_TRIGGER_MORSE)	+= ledtrig-morse.o |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| --- a/drivers/leds/Kconfig |  | ||||||
| +++ b/drivers/leds/Kconfig |  | ||||||
| @@ -308,4 +308,11 @@ config LEDS_TRIGGER_MORSE |  | ||||||
|  	tristate "LED Morse Trigger" |  | ||||||
|  	depends on LEDS_TRIGGERS |  | ||||||
|   |  | ||||||
| +config LEDS_TRIGGER_NETDEV |  | ||||||
| +	tristate "LED Netdev Trigger" |  | ||||||
| +	depends on NET && LEDS_TRIGGERS |  | ||||||
| +	help |  | ||||||
| +	  This allows LEDs to be controlled by network device activity. |  | ||||||
| +	  If unsure, say Y. |  | ||||||
| + |  | ||||||
|  endif # NEW_LEDS |  | ||||||
| --- a/drivers/leds/Makefile |  | ||||||
| +++ b/drivers/leds/Makefile |  | ||||||
| @@ -41,3 +41,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_MORSE)	+= ledtrig-morse.o |  | ||||||
| +obj-$(CONFIG_LEDS_TRIGGER_NETDEV)	+= ledtrig-netdev.o |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| --- a/drivers/leds/Kconfig |  | ||||||
| +++ b/drivers/leds/Kconfig |  | ||||||
| @@ -315,4 +315,11 @@ config LEDS_TRIGGER_NETDEV |  | ||||||
|  	  This allows LEDs to be controlled by network device activity. |  | ||||||
|  	  If unsure, say Y. |  | ||||||
|   |  | ||||||
| +config LEDS_TRIGGER_USBDEV |  | ||||||
| +	tristate "LED USB device Trigger" |  | ||||||
| +	depends on USB && LEDS_TRIGGERS |  | ||||||
| +	help |  | ||||||
| +	  This allows LEDs to be controlled by the presence/activity of |  | ||||||
| +	  an USB device. If unsure, say N. |  | ||||||
| + |  | ||||||
|  endif # NEW_LEDS |  | ||||||
| --- a/drivers/leds/Makefile |  | ||||||
| +++ b/drivers/leds/Makefile |  | ||||||
| @@ -42,3 +42,4 @@ obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledt |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_MORSE)	+= ledtrig-morse.o |  | ||||||
|  obj-$(CONFIG_LEDS_TRIGGER_NETDEV)	+= ledtrig-netdev.o |  | ||||||
| +obj-$(CONFIG_LEDS_TRIGGER_USBDEV)	+= ledtrig-usbdev.o |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| --- a/drivers/input/misc/Kconfig |  | ||||||
| +++ b/drivers/input/misc/Kconfig |  | ||||||
| @@ -317,4 +317,20 @@ config INPUT_PCAP |  | ||||||
|  	  To compile this driver as a module, choose M here: the |  | ||||||
|  	  module will be called pcap_keys. |  | ||||||
|   |  | ||||||
| +config INPUT_GPIO_BUTTONS |  | ||||||
| +	tristate "Polled GPIO buttons interface" |  | ||||||
| +	depends on GENERIC_GPIO |  | ||||||
| +	select INPUT_POLLDEV |  | ||||||
| +	help |  | ||||||
| +	  This driver implements support for buttons connected |  | ||||||
| +	  to GPIO pins of various CPUs (and some other chips). |  | ||||||
| + |  | ||||||
| +	  Say Y here if your device has buttons connected |  | ||||||
| +	  directly to such GPIO pins.  Your board-specific |  | ||||||
| +	  setup logic must also provide a platform device, |  | ||||||
| +	  with configuration data saying which GPIOs are used. |  | ||||||
| + |  | ||||||
| +	  To compile this driver as a module, choose M here: the |  | ||||||
| +	  module will be called gpio-buttons. |  | ||||||
| + |  | ||||||
|  endif |  | ||||||
| --- a/drivers/input/misc/Makefile |  | ||||||
| +++ b/drivers/input/misc/Makefile |  | ||||||
| @@ -30,4 +30,5 @@ obj-$(CONFIG_INPUT_WINBOND_CIR)		+= winb |  | ||||||
|  obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o |  | ||||||
|  obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o |  | ||||||
|  obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o |  | ||||||
| +obj-$(CONFIG_INPUT_GPIO_BUTTONS)	+= gpio_buttons.o |  | ||||||
|   |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| From 492d4f25416528ffb900e6edf0fd70eafd098cfc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Dmitry Torokhov <dmitry.torokhov@gmail.com> |  | ||||||
| Date: Fri, 26 Feb 2010 00:16:05 -0800 |  | ||||||
| Subject: [PATCH] Input: add KEY_WPS_BUTTON definition |  | ||||||
|  |  | ||||||
| The new key definition is supposed to be used for buttons that initiate |  | ||||||
| WiFi Protected setup sequence: |  | ||||||
|  |  | ||||||
| 	http://en.wikipedia.org/wiki/Wi-Fi_Protected_Setup |  | ||||||
|  |  | ||||||
| Signed-off-by: Dmitry Torokhov <dtor@mail.ru> |  | ||||||
| --- |  | ||||||
|  include/linux/input.h |    1 + |  | ||||||
|  1 files changed, 1 insertions(+), 0 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/include/linux/input.h |  | ||||||
| +++ b/include/linux/input.h |  | ||||||
| @@ -595,6 +595,8 @@ struct input_absinfo { |  | ||||||
|  #define KEY_NUMERIC_STAR	0x20a |  | ||||||
|  #define KEY_NUMERIC_POUND	0x20b |  | ||||||
|   |  | ||||||
| +#define KEY_WPS_BUTTON		0x211	/* WiFi Protected Setup key */ |  | ||||||
| + |  | ||||||
|  /* We avoid low common keys in module aliases so they don't get huge. */ |  | ||||||
|  #define KEY_MIN_INTERESTING	KEY_MUTE |  | ||||||
|  #define KEY_MAX			0x2ff |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| --- a/drivers/char/Kconfig |  | ||||||
| +++ b/drivers/char/Kconfig |  | ||||||
| @@ -1029,6 +1029,14 @@ config CS5535_GPIO |  | ||||||
|   |  | ||||||
|  	  If compiled as a module, it will be called cs5535_gpio. |  | ||||||
|   |  | ||||||
| +config GPIO_DEVICE |  | ||||||
| +	tristate "GPIO device support" |  | ||||||
| +	depends on GENERIC_GPIO |  | ||||||
| +	help |  | ||||||
| +	  Say Y to enable Linux GPIO device support.  This allows control of |  | ||||||
| +	  GPIO pins using a character device |  | ||||||
| + |  | ||||||
| + |  | ||||||
|  config RAW_DRIVER |  | ||||||
|  	tristate "RAW driver (/dev/raw/rawN)" |  | ||||||
|  	depends on BLOCK |  | ||||||
| --- a/drivers/char/Makefile |  | ||||||
| +++ b/drivers/char/Makefile |  | ||||||
| @@ -96,6 +96,7 @@ obj-$(CONFIG_SCx200_GPIO)	+= scx200_gpio |  | ||||||
|  obj-$(CONFIG_PC8736x_GPIO)	+= pc8736x_gpio.o |  | ||||||
|  obj-$(CONFIG_NSC_GPIO)		+= nsc_gpio.o |  | ||||||
|  obj-$(CONFIG_CS5535_GPIO)	+= cs5535_gpio.o |  | ||||||
| +obj-$(CONFIG_GPIO_DEVICE)	+= gpio_dev.o |  | ||||||
|  obj-$(CONFIG_GPIO_TB0219)	+= tb0219.o |  | ||||||
|  obj-$(CONFIG_TELCLOCK)		+= tlclk.o |  | ||||||
|   |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| --- a/include/scsi/scsi.h |  | ||||||
| +++ b/include/scsi/scsi.h |  | ||||||
| @@ -145,10 +145,10 @@ struct scsi_cmnd; |  | ||||||
|   |  | ||||||
|  /* defined in T10 SCSI Primary Commands-2 (SPC2) */ |  | ||||||
|  struct scsi_varlen_cdb_hdr { |  | ||||||
| -	u8 opcode;        /* opcode always == VARIABLE_LENGTH_CMD */ |  | ||||||
| -	u8 control; |  | ||||||
| -	u8 misc[5]; |  | ||||||
| -	u8 additional_cdb_length;         /* total cdb length - 8 */ |  | ||||||
| +	__u8 opcode;        /* opcode always == VARIABLE_LENGTH_CMD */ |  | ||||||
| +	__u8 control; |  | ||||||
| +	__u8 misc[5]; |  | ||||||
| +	__u8 additional_cdb_length;         /* total cdb length - 8 */ |  | ||||||
|  	__be16 service_action; |  | ||||||
|  	/* service specific data follows */ |  | ||||||
|  }; |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| --- a/fs/Kconfig |  | ||||||
| +++ b/fs/Kconfig |  | ||||||
| @@ -44,6 +44,7 @@ source "fs/gfs2/Kconfig" |  | ||||||
|  source "fs/ocfs2/Kconfig" |  | ||||||
|  source "fs/btrfs/Kconfig" |  | ||||||
|  source "fs/nilfs2/Kconfig" |  | ||||||
| +source "fs/yaffs2/Kconfig" |  | ||||||
|   |  | ||||||
|  endif # BLOCK |  | ||||||
|   |  | ||||||
| --- a/fs/Makefile |  | ||||||
| +++ b/fs/Makefile |  | ||||||
| @@ -125,3 +125,4 @@ obj-$(CONFIG_OCFS2_FS)		+= ocfs2/ |  | ||||||
|  obj-$(CONFIG_BTRFS_FS)		+= btrfs/ |  | ||||||
|  obj-$(CONFIG_GFS2_FS)           += gfs2/ |  | ||||||
|  obj-$(CONFIG_EXOFS_FS)          += exofs/ |  | ||||||
| +obj-$(CONFIG_YAFFS_FS)		+= yaffs2/ |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Gabor Juhos
					Gabor Juhos