1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

generic: nuke 2.6.33 specific stuff, is not used by any platform

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24644 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
juhosg
2010-12-17 17:10:04 +00:00
parent 579e608a9b
commit 97b250affa
174 changed files with 0 additions and 53909 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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;
+}

View File

@@ -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);

View File

@@ -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
+};
+

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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
@@ -121,6 +121,9 @@ config DECOMPRESS_LZO
select LZO_DECOMPRESS
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

View File

@@ -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.

View File

@@ -1,21 +0,0 @@
--- a/Makefile
+++ b/Makefile
@@ -529,7 +529,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
@@ -567,6 +567,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,)

View File

@@ -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:

View File

@@ -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;

View File

@@ -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
@@ -93,6 +93,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
@@ -851,6 +851,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
@@ -98,6 +98,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
*/

View File

@@ -1,28 +0,0 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -854,6 +854,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

View File

@@ -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__ */

View File

@@ -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);

View File

@@ -1,161 +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
@@ -839,6 +839,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
@@ -58,7 +58,11 @@
#define __mips 4
/* Function which emulates a floating point instruction. */
+#ifdef CONFIG_DEBUG_FS
+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
+#endif
+#ifdef CONFIG_MIPS_FPU_EMU
static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
mips_instruction);
@@ -69,10 +73,6 @@ static int fpux_emu(struct pt_regs *,
/* Further private data for which no space exists in mips_fpu_struct */
-#ifdef CONFIG_DEBUG_FS
-DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
-#endif
-
/* Control registers */
#define FPCREG_RID 0 /* $0 = revision id */
@@ -1284,7 +1284,6 @@ int fpu_emulator_cop1Handler(struct pt_r
return sig;
}
-
#ifdef CONFIG_DEBUG_FS
static int fpuemu_stat_get(void *data, u64 *val)
@@ -1333,4 +1332,11 @@ static int __init debugfs_fpuemu(void)
return 0;
}
__initcall(debugfs_fpuemu);
-#endif
+#endif /* CONFIG_DEBUGFS */
+#else
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ int has_fpu)
+{
+ return 0;
+}
+#endif /* CONFIG_MIPS_FPU_EMU */
--- 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 */

View File

@@ -1,368 +0,0 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -93,7 +93,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
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);

View File

@@ -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 SYMBOL_PREFIX
#define VMLINUX_SYMBOL(sym) sym
#else
@@ -258,35 +279,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) = .; \
} \
\
@@ -327,7 +348,7 @@
\
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
- *(__ksymtab_strings) \
+ SYMTAB_KEEP_STR \
} \
\
/* __*init sections */ \
@@ -642,6 +663,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
@@ -194,16 +194,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) \

View File

@@ -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)) {

View File

@@ -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.
@@ -1908,7 +1909,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)
{
@@ -2543,6 +2546,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)

View File

@@ -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
@@ -802,3 +802,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
@@ -185,3 +185,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 */

View File

@@ -1,430 +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: Sat Feb 20 14:16:15 2010
+# Last update: Sat Aug 14 08:06:22 2010
#
# 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_foundation MACH_HYNET_INE HYNET_INE 1319
hynet_app MACH_HYNET_APP HYNET_APP 1320
msm7200 MACH_MSM7200 MSM7200 1321
msm7600 MACH_MSM7600 MSM7600 1322
@@ -1777,7 +1777,7 @@ wdg002 MACH_WDG002 WDG002 1785
sg560adsl MACH_SG560ADSL SG560ADSL 1786
nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787
dove_db MACH_DOVE_DB DOVE_DB 1788
-marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789
+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
@@ -1994,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
@@ -2308,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
@@ -2374,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
@@ -2498,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
@@ -2561,7 +2561,7 @@ magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 25
emxx MACH_EMXX EMXX 2574
outlaw MACH_OUTLAW OUTLAW 2575
riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
-riot_vox MACH_RIOT_VOX RIOT_VOX 2577
+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
@@ -2582,7 +2582,7 @@ omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_
pca101 MACH_PCA101 PCA101 2595
buzzc MACH_BUZZC BUZZC 2596
sasie2 MACH_SASIE2 SASIE2 2597
-davinci_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
+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
@@ -2609,7 +2609,7 @@ fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1
lexikon MACH_LEXIKON LEXIKON 2622
mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
icontrol MACH_ICONTROL ICONTROL 2624
-sheevad MACH_SHEEVAD SHEEVAD 2625
+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
@@ -2663,7 +2663,7 @@ 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
-surf7x30 MACH_SURF7X30 SURF7X30 2679
+msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
micro2440 MACH_MICRO2440 MICRO2440 2680
am2440 MACH_AM2440 AM2440 2681
tq2440 MACH_TQ2440 TQ2440 2682
@@ -2678,3 +2678,328 @@ 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 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
+vmc300 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_harmony 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 MACH_UNIVERSAL UNIVERSAL 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
+tegra_seaboard MACH_TEGRA_SEABOARD TEGRA_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

View File

@@ -1,30 +0,0 @@
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1299,6 +1299,8 @@ struct block_device_operations {
unsigned long long);
int (*revalidate_disk) (struct gendisk *);
int (*getgeo)(struct block_device *, struct hd_geometry *);
+ /* this callback is with swap_lock and sometimes page table lock held */
+ void (*swap_slot_free_notify) (struct block_device *, unsigned long);
struct module *owner;
};
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -574,6 +574,7 @@ static unsigned char swap_entry_free(str
/* free if no reference */
if (!usage) {
+ struct gendisk *disk = p->bdev->bd_disk;
if (offset < p->lowest_bit)
p->lowest_bit = offset;
if (offset > p->highest_bit)
@@ -583,6 +584,8 @@ static unsigned char swap_entry_free(str
swap_list.next = p->type;
nr_swap_pages++;
p->inuse_pages--;
+ if (disk->fops->swap_slot_free_notify)
+ disk->fops->swap_slot_free_notify(p->bdev, offset);
}
return usage;

View File

@@ -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
@@ -248,6 +248,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:

View File

@@ -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
@@ -637,6 +637,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)
{

View File

@@ -1,625 +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,150 @@ 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;
+ int split_offset = 0;
+ int ret;
+
+ ret = split_squashfs(master, part->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 -= split_offset - dpart->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 +664,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 +672,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 +694,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', 23)
/*
* Obsolete legacy interface. Keep it in order not to break userspace

View File

@@ -1,10 +0,0 @@
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -268,6 +268,7 @@ static int _open_bdev(struct block2mtd_d
/* We might not have rootfs mounted at this point. Try
to resolve the device name by other means. */
+ wait_for_device_probe();
dev_t devt = name_to_dev_t(dev->devname);
if (devt) {
bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);

View File

@@ -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);

View File

@@ -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:

View File

@@ -1,32 +0,0 @@
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -491,6 +491,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
@@ -91,7 +91,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)) {
err = -ENXIO;
goto out;
}

View File

@@ -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

View File

@@ -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 *);

View File

@@ -1,12 +0,0 @@
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -507,8 +507,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);

View File

@@ -1,39 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -40,6 +40,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_PMC 0xd7 /* Erase 4KiB block on PMC chips*/
#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 M25P_NO_ERASE 0x02 /* No erase command needed */
+#define SECT_4K_PMC 0x04 /* OPCODE_BE_4K_PMC works uniformly */
};
#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
@@ -645,6 +647,10 @@ static const struct spi_device_id m25p_i
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ /* PMC -- pm25x "blocks" are 32K, sectors are 4K */
+ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
+ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
+
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
@@ -857,6 +863,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_PMC) {
+ flash->erase_opcode = OPCODE_BE_4K_PMC;
+ flash->mtd.erasesize = 4096;
} else {
flash->erase_opcode = OPCODE_SE;
flash->mtd.erasesize = info->sector_size;

View File

@@ -1,13 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -647,6 +647,10 @@ static const struct spi_device_id m25p_i
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ /* EON -- en25pxx */
+ { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
+ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
+
/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
{ "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },

View File

@@ -1,28 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -651,6 +651,11 @@ static const struct spi_device_id m25p_i
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
+ /* Numonyx -- xxxs33b */
+ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
+ { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) },
+ { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) },
+
/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
{ "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
@@ -835,11 +840,12 @@ static int __devinit m25p_probe(struct s
dev_set_drvdata(&spi->dev, flash);
/*
- * Atmel and SST serial flash tend to power
+ * Atmel, SST and Intel/Numonyx serial flash tend to power
* up with the software protection bits set
*/
if (info->jedec_id >> 16 == 0x1f ||
+ info->jedec_id >> 16 == 0x89 ||
info->jedec_id >> 16 == 0xbf) {
write_enable(flash);
write_sr(flash, 0);

View File

@@ -1,10 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -708,6 +708,7 @@ static const struct spi_device_id m25p_i
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
+ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
/* Catalyst / On Semiconductor -- non-JEDEC */

View File

@@ -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

View File

@@ -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)

View File

@@ -1,12 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -647,7 +647,8 @@ static const struct spi_device_id m25p_i
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
- /* EON -- en25pxx */
+ /* EON -- en25xxx */
+ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },

View File

@@ -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){

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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
@@ -505,7 +504,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

File diff suppressed because it is too large Load Diff

View File

@@ -1,795 +0,0 @@
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -173,8 +173,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");

View File

@@ -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 */

View File

@@ -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);
+

View File

@@ -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)

View File

@@ -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;

View File

@@ -1,56 +0,0 @@
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1373,11 +1373,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)
@@ -1467,9 +1474,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;
}
@@ -1552,7 +1559,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
@@ -339,9 +339,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;

View File

@@ -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 */

View File

@@ -1,48 +0,0 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -49,7 +49,9 @@ ifneq ($(SUBARCH),$(ARCH))
endif
ifndef CONFIG_FUNCTION_TRACER
-cflags-y := -ffunction-sections
+ ifndef CONFIG_PROFILING
+ cflags-y := -ffunction-sections
+ endif
endif
ifdef CONFIG_FUNCTION_GRAPH_TRACER
ifndef KBUILD_MCOUNT_RA_ADDRESS
--- 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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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) */

View File

@@ -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);

View File

@@ -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");

View File

@@ -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)

View File

@@ -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:

View File

@@ -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 */

View 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;

View File

@@ -1,11 +0,0 @@
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -8,7 +8,7 @@ config SND_PCM
select GCD
config SND_HWDEP
- tristate
+ tristate "Sound hardware support"
config SND_RAWMIDI
tristate

View File

@@ -1,11 +0,0 @@
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1165,7 +1165,7 @@ static unsigned long vma_dump_size(struc
if (FILTER(ELF_HEADERS) &&
vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
u32 __user *header = (u32 __user *) vma->vm_start;
- u32 word;
+ u32 word = 0;
mm_segment_t fs = get_fs();
/*
* Doing it this way gets the constant folded by GCC.

View File

@@ -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 {

View File

@@ -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,
+ int 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,
+ int 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,
+ int 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,
+ int 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,

View File

@@ -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
@@ -29,6 +29,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 */
@@ -46,6 +48,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 {
unsigned int tp_packets;
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -205,6 +205,7 @@ struct packet_sock {
unsigned int tp_loss:1;
#endif
struct packet_type prot_hook ____cacheline_aligned_in_smp;
+ unsigned int pkt_type;
};
struct packet_skb_cb {
@@ -343,6 +344,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
@@ -350,6 +352,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
@@ -362,7 +365,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 (!net_eq(dev_net(dev), sock_net(sk)))
@@ -538,12 +541,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 (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
@@ -659,12 +662,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 (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
@@ -1386,6 +1389,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;
@@ -1731,6 +1735,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:
@@ -1876,6 +1890,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))

View File

@@ -1,20 +0,0 @@
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -862,7 +862,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;
@@ -870,7 +870,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;

View File

@@ -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) */

View File

@@ -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;
@@ -2359,8 +2361,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;
@@ -2415,5 +2420,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
@@ -9552,4 +9554,6 @@ static struct hash_testvec crc32c_tv_tem
},
};
+#endif /* CONFIG_CRYPTO_MANAGER_NO_TESTS */
+
#endif /* _CRYPTO_TESTMGR_H */

View File

@@ -1,41 +0,0 @@
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1106,6 +1106,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);
@@ -1159,8 +1171,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
@@ -1310,8 +1321,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

View File

@@ -1,12 +0,0 @@
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2884,7 +2884,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)) {

View File

@@ -1,18 +0,0 @@
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -337,4 +337,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
@@ -44,3 +44,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

View File

@@ -1,21 +0,0 @@
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -341,4 +341,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
@@ -45,3 +45,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

View File

@@ -1,31 +0,0 @@
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -319,4 +319,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

View File

@@ -1,25 +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
@@ -597,6 +597,7 @@ struct input_absinfo {
#define KEY_NUMERIC_POUND 0x20b
#define KEY_CAMERA_FOCUS 0x210
+#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

View File

@@ -1,27 +0,0 @@
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1016,6 +1016,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
@@ -95,6 +95,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

View File

@@ -1,17 +0,0 @@
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -149,10 +149,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 */
};

View File

@@ -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/

View File

@@ -1,81 +0,0 @@
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -299,6 +299,50 @@ int phy_ethtool_gset(struct phy_device *
}
EXPORT_SYMBOL(phy_ethtool_gset);
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
+{
+ u32 cmd;
+ int tmp;
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_value edata = { ETHTOOL_GLINK };
+
+ if (get_user(cmd, (u32 *) useraddr))
+ return -EFAULT;
+
+ switch (cmd) {
+ case ETHTOOL_GSET:
+ phy_ethtool_gset(phydev, &ecmd);
+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+
+ case ETHTOOL_SSET:
+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+ return -EFAULT;
+ return phy_ethtool_sset(phydev, &ecmd);
+
+ case ETHTOOL_NWAY_RST:
+ /* if autoneg is off, it's an error */
+ tmp = phy_read(phydev, MII_BMCR);
+ if (tmp & BMCR_ANENABLE) {
+ tmp |= (BMCR_ANRESTART);
+ phy_write(phydev, MII_BMCR, tmp);
+ return 0;
+ }
+ return -EINVAL;
+
+ case ETHTOOL_GLINK:
+ edata.data = (phy_read(phydev,
+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(phy_ethtool_ioctl);
+
/**
* phy_mii_ioctl - generic PHY MII ioctl interface
* @phydev: the phy_device struct
@@ -352,7 +396,7 @@ int phy_mii_ioctl(struct phy_device *phy
}
phy_write(phydev, mii_data->reg_num, val);
-
+
if (mii_data->reg_num == MII_BMCR &&
val & BMCR_RESET &&
phydev->drv->config_init) {
@@ -466,7 +510,7 @@ static void phy_force_reduction(struct p
int idx;
idx = phy_find_setting(phydev->speed, phydev->duplex);
-
+
idx++;
idx = phy_find_valid(idx, phydev->supported);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -491,6 +491,7 @@ void phy_start_machine(struct phy_device
void phy_stop_machine(struct phy_device *phydev);
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
int phy_mii_ioctl(struct phy_device *phydev,
struct mii_ioctl_data *mii_data, int cmd);
int phy_start_interrupts(struct phy_device *phydev);

View File

@@ -1,45 +0,0 @@
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -379,9 +379,18 @@ struct phy_driver {
*/
int (*config_aneg)(struct phy_device *phydev);
+ /* Determine if autonegotiation is done */
+ int (*aneg_done)(struct phy_device *phydev);
+
/* Determines the negotiated speed and duplex */
int (*read_status)(struct phy_device *phydev);
+ /*
+ * Update the value in phydev->link to reflect the
+ * current link value
+ */
+ int (*update_link)(struct phy_device *phydev);
+
/* Clears any pending interrupts */
int (*ack_interrupt)(struct phy_device *phydev);
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -682,6 +682,9 @@ int genphy_update_link(struct phy_device
{
int status;
+ if (phydev->drv->update_link)
+ return phydev->drv->update_link(phydev);
+
/* Do a fake read */
status = phy_read(phydev, MII_BMSR);
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -107,6 +107,9 @@ static inline int phy_aneg_done(struct p
{
int retval;
+ if (phydev->drv->aneg_done)
+ return phydev->drv->aneg_done(phydev);
+
retval = phy_read(phydev, MII_BMSR);
return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);

View File

@@ -1,24 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -88,6 +88,11 @@ config LSI_ET1011C_PHY
---help---
Supports the LSI ET1011C PHY.
+config ADM6996_PHY
+ tristate "Driver for ADM6996 switches"
+ ---help---
+ Currently supports the ADM6996F switch
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

View File

@@ -1,63 +0,0 @@
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -146,6 +146,18 @@ int phy_scan_fixups(struct phy_device *p
}
EXPORT_SYMBOL(phy_scan_fixups);
+static int generic_receive_skb(struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ return netif_receive_skb(skb);
+}
+
+static int generic_rx(struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ return netif_rx(skb);
+}
+
struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
{
struct phy_device *dev;
@@ -175,6 +187,8 @@ struct phy_device* phy_device_create(str
dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
dev->state = PHY_DOWN;
+ dev->netif_receive_skb = &generic_receive_skb;
+ dev->netif_rx = &generic_rx;
mutex_init(&dev->lock);
INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -325,6 +325,20 @@ struct phy_device {
void (*adjust_link)(struct net_device *dev);
void (*adjust_state)(struct net_device *dev);
+
+ /*
+ * By default these point to the original functions
+ * with the same name. adding them to the phy_device
+ * allows the phy driver to override them for packet
+ * mangling if the ethernet driver supports it
+ * This is required to support some really horrible
+ * switches such as the Marvell 88E6060
+ */
+ int (*netif_receive_skb)(struct sk_buff *skb);
+ int (*netif_rx)(struct sk_buff *skb);
+
+ /* alignment offset for packets */
+ int pkt_align;
};
#define to_phy_device(d) container_of(d, struct phy_device, dev)
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -844,6 +844,7 @@ struct net_device {
void *ax25_ptr; /* AX.25 specific data */
struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
assign before registering */
+ void *phy_ptr; /* PHY device specific data */
/*
* Cache line mostly used on receive path (including eth_type_trans())

View File

@@ -1,25 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -13,6 +13,12 @@ menuconfig PHYLIB
if PHYLIB
+config SWCONFIG
+ tristate "Switch configuration API"
+ ---help---
+ Switch configuration API using netlink. This allows
+ you to configure the VLAN features of certain switches.
+
comment "MII PHY device drivers"
config MARVELL_PHY
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -3,6 +3,7 @@
libphy-objs := phy.o phy_device.o mdio_bus.o
obj-$(CONFIG_PHYLIB) += libphy.o
+obj-$(CONFIG_SWCONFIG) += swconfig.o
obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_DAVICOM_PHY) += davicom.o
obj-$(CONFIG_CICADA_PHY) += cicada.o

View File

@@ -1,22 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -99,6 +99,9 @@ config ADM6996_PHY
---help---
Currently supports the ADM6996F switch
+config MVSWITCH_PHY
+ tristate "Driver for Marvell 88E6060 switches"
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
+obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

View File

@@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -102,6 +102,10 @@ config ADM6996_PHY
config MVSWITCH_PHY
tristate "Driver for Marvell 88E6060 switches"
+config IP17XX_PHY
+ tristate "Driver for IC+ IP17xx switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

View File

@@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -106,6 +106,10 @@ config IP17XX_PHY
tristate "Driver for IC+ IP17xx switches"
select SWCONFIG
+config AR8216_PHY
+ tristate "Driver for Atheros AR8216 switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
+obj-$(CONFIG_AR8216_PHY) += ar8216.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o

View File

@@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -110,6 +110,10 @@ config AR8216_PHY
tristate "Driver for Atheros AR8216 switches"
select SWCONFIG
+config RTL8306_PHY
+ tristate "Driver for Realtek RTL8306S switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o
+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o

View File

@@ -1,44 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -152,4 +152,29 @@ config MDIO_OCTEON
If in doubt, say Y.
+config RTL8366_SMI
+ tristate "Driver for the RTL8366 SMI interface"
+ depends on GENERIC_GPIO
+ ---help---
+ This module implements the SMI interface protocol which is used
+ by some RTL8366 ethernet switch devices via the generic GPIO API.
+
+if RTL8366_SMI
+
+config RTL8366S_PHY
+ tristate "Driver for the Realtek RTL8366S switch"
+ select SWCONFIG
+
+config RTL8366RB_PHY
+ tristate "Driver for the Realtek RTL8366RB switch"
+ select SWCONFIG
+
+config RTL8366S_PHY_DEBUG_FS
+ bool "RTL8366 switch driver DEBUG_FS support"
+ depends on RTL8366S_PHY || RTL8366RB_PHY
+ depends on DEBUG_FS
+ default n
+
+endif # RTL8366_SMI
+
endif # PHYLIB
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -20,6 +20,9 @@ obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o
obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o

View File

@@ -1,23 +0,0 @@
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
+obj-$(CONFIG_PSB6970_PHY) += psb6970.o
obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -99,6 +99,10 @@ config ADM6996_PHY
---help---
Currently supports the ADM6996F switch
+config PSB6970_PHY
+ tristate "Driver for Lantiq PSB6970 (Tantos) switch"
+ select SWCONFIG
+
config MVSWITCH_PHY
tristate "Driver for Marvell 88E6060 switches"

View File

@@ -1,250 +0,0 @@
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -608,6 +608,15 @@ config RTC_DRV_NUC900
If you say yes here you get support for the RTC subsystem of the
NUC910/NUC920 used in embedded systems.
+config RTC_DRV_RTC7301
+ tristate "Epson RTC-7301 SF/DG"
+ help
+ If you say Y here you will get support for the
+ Epson RTC-7301 SF/DG RTC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-7301.
+
comment "on-CPU RTC drivers"
config RTC_DRV_OMAP
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
+obj-$(CONFIG_RTC_DRV_RTC7301) += rtc-rtc7301.o
obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o
obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o
obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
--- /dev/null
+++ b/drivers/rtc/rtc-rtc7301.c
@@ -0,0 +1,219 @@
+/*
+ * Driver for Epson RTC-7301SF/DG
+ *
+ * Copyright (C) 2009 Jose Vasconcellos
+ *
+ * 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/module.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/bcd.h>
+
+#define RTC_NAME "rtc7301"
+#define RTC_VERSION "0.1"
+
+/* Epson RTC-7301 register addresses */
+#define RTC7301_SEC 0x00
+#define RTC7301_SEC10 0x01
+#define RTC7301_MIN 0x02
+#define RTC7301_MIN10 0x03
+#define RTC7301_HOUR 0x04
+#define RTC7301_HOUR10 0x05
+#define RTC7301_WEEKDAY 0x06
+#define RTC7301_DAY 0x07
+#define RTC7301_DAY10 0x08
+#define RTC7301_MON 0x09
+#define RTC7301_MON10 0x0A
+#define RTC7301_YEAR 0x0B
+#define RTC7301_YEAR10 0x0C
+#define RTC7301_YEAR100 0x0D
+#define RTC7301_YEAR1000 0x0E
+#define RTC7301_CTRLREG 0x0F
+
+static uint8_t __iomem *rtc7301_base;
+
+#define read_reg(offset) (readb(rtc7301_base + offset) & 0xf)
+#define write_reg(offset, data) writeb(data, rtc7301_base + (offset))
+
+#define rtc7301_isbusy() (read_reg(RTC7301_CTRLREG) & 1)
+
+static void rtc7301_init_settings(void)
+{
+ int i;
+
+ write_reg(RTC7301_CTRLREG, 2);
+ write_reg(RTC7301_YEAR1000, 2);
+ udelay(122);
+
+ /* bank 1 */
+ write_reg(RTC7301_CTRLREG, 6);
+ for (i=0; i<15; i++)
+ write_reg(i, 0);
+
+ /* bank 2 */
+ write_reg(RTC7301_CTRLREG, 14);
+ for (i=0; i<15; i++)
+ write_reg(i, 0);
+ write_reg(RTC7301_CTRLREG, 0);
+}
+
+static int rtc7301_get_datetime(struct device *dev, struct rtc_time *dt)
+{
+ int cnt;
+ uint8_t buf[16];
+
+ cnt = 0;
+ while (rtc7301_isbusy()) {
+ udelay(244);
+ if (cnt++ > 100) {
+ dev_err(dev, "%s: timeout error %x\n", __func__, rtc7301_base[RTC7301_CTRLREG]);
+ return -EIO;
+ }
+ }
+
+ for (cnt=0; cnt<16; cnt++)
+ buf[cnt] = read_reg(cnt);
+
+ if (buf[RTC7301_SEC10] & 8) {
+ dev_err(dev, "%s: RTC not set\n", __func__);
+ return -EINVAL;
+ }
+
+ memset(dt, 0, sizeof(*dt));
+
+ dt->tm_sec = buf[RTC7301_SEC] + buf[RTC7301_SEC10]*10;
+ dt->tm_min = buf[RTC7301_MIN] + buf[RTC7301_MIN10]*10;
+ dt->tm_hour = buf[RTC7301_HOUR] + buf[RTC7301_HOUR10]*10;
+
+ dt->tm_mday = buf[RTC7301_DAY] + buf[RTC7301_DAY10]*10;
+ dt->tm_mon = buf[RTC7301_MON] + buf[RTC7301_MON10]*10 - 1;
+ dt->tm_year = buf[RTC7301_YEAR] + buf[RTC7301_YEAR10]*10 +
+ buf[RTC7301_YEAR100]*100 +
+ ((buf[RTC7301_YEAR1000] & 3)*1000) - 1900;
+
+ /* the rtc device may contain illegal values on power up
+ * according to the data sheet. make sure they are valid.
+ */
+
+ return rtc_valid_tm(dt);
+}
+
+static int rtc7301_set_datetime(struct device *dev, struct rtc_time *dt)
+{
+ int data;
+
+ data = dt->tm_year + 1900;
+ if (data >= 2100 || data < 1900)
+ return -EINVAL;
+
+ write_reg(RTC7301_CTRLREG, 2);
+ udelay(122);
+
+ data = bin2bcd(dt->tm_sec);
+ write_reg(RTC7301_SEC, data);
+ write_reg(RTC7301_SEC10, (data >> 4));
+
+ data = bin2bcd(dt->tm_min);
+ write_reg(RTC7301_MIN, data );
+ write_reg(RTC7301_MIN10, (data >> 4));
+
+ data = bin2bcd(dt->tm_hour);
+ write_reg(RTC7301_HOUR, data);
+ write_reg(RTC7301_HOUR10, (data >> 4));
+
+ data = bin2bcd(dt->tm_mday);
+ write_reg(RTC7301_DAY, data);
+ write_reg(RTC7301_DAY10, (data>> 4));
+
+ data = bin2bcd(dt->tm_mon + 1);
+ write_reg(RTC7301_MON, data);
+ write_reg(RTC7301_MON10, (data >> 4));
+
+ data = bin2bcd(dt->tm_year % 100);
+ write_reg(RTC7301_YEAR, data);
+ write_reg(RTC7301_YEAR10, (data >> 4));
+ data = bin2bcd((1900 + dt->tm_year) / 100);
+ write_reg(RTC7301_YEAR100, data);
+
+ data = bin2bcd(dt->tm_wday);
+ write_reg(RTC7301_WEEKDAY, data);
+
+ write_reg(RTC7301_CTRLREG, 0);
+
+ return 0;
+}
+
+static const struct rtc_class_ops rtc7301_rtc_ops = {
+ .read_time = rtc7301_get_datetime,
+ .set_time = rtc7301_set_datetime,
+};
+
+static int __devinit rtc7301_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc;
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ rtc7301_base = ioremap_nocache(res->start, 0x1000 /*res->end - res->start + 1*/);
+ if (!rtc7301_base)
+ return -EINVAL;
+
+ rtc = rtc_device_register(RTC_NAME, &pdev->dev,
+ &rtc7301_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ iounmap(rtc7301_base);
+ return PTR_ERR(rtc);
+ }
+
+ platform_set_drvdata(pdev, rtc);
+
+ rtc7301_init_settings();
+ return 0;
+}
+
+static int __devexit rtc7301_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+ if (rtc7301_base)
+ iounmap(rtc7301_base);
+ return 0;
+}
+
+static struct platform_driver rtc7301_driver = {
+ .driver = {
+ .name = RTC_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = rtc7301_probe,
+ .remove = __devexit_p(rtc7301_remove),
+};
+
+static __init int rtc7301_init(void)
+{
+ return platform_driver_register(&rtc7301_driver);
+}
+module_init(rtc7301_init);
+
+static __exit void rtc7301_exit(void)
+{
+ platform_driver_unregister(&rtc7301_driver);
+}
+module_exit(rtc7301_exit);
+
+MODULE_DESCRIPTION("Epson 7301 RTC driver");
+MODULE_AUTHOR("Jose Vasconcellos <jvasco@verizon.net>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" RTC_NAME);
+MODULE_VERSION(RTC_VERSION);

View File

@@ -1,21 +0,0 @@
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -124,6 +124,7 @@ struct dentry;
#define FB_ACCEL_TRIDENT_BLADE3D 52 /* Trident Blade3D */
#define FB_ACCEL_TRIDENT_BLADEXP 53 /* Trident BladeXP */
#define FB_ACCEL_CIRRUS_ALPINE 53 /* Cirrus Logic 543x/544x/5480 */
+#define FB_ACCEL_GLAMO 50 /* SMedia Glamo */
#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -76,6 +76,8 @@ header-y += genetlink.h
header-y += gen_stats.h
header-y += gfs2_ondisk.h
header-y += gigaset_dev.h
+header-y += glamofb.h
+header-y += glamo-engine.h
header-y += hysdn_if.h
header-y += i2o-dev.h
header-y += i8k.h

View File

@@ -1,25 +0,0 @@
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -61,6 +61,7 @@ static struct usb_driver usb_serial_driv
drivers depend on it.
*/
+static ushort maxSize = 0;
static int debug;
/* initially all NULL */
static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
@@ -914,7 +915,7 @@ int usb_serial_probe(struct usb_interfac
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
}
- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ buffer_size = (endpoint->wMaxPacketSize > maxSize) ? endpoint->wMaxPacketSize : maxSize;
port->bulk_in_size = buffer_size;
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
@@ -1356,3 +1357,5 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(maxSize, ushort,0);
+MODULE_PARM_DESC(maxSize,"User specified USB endpoint size");

View File

@@ -1,11 +0,0 @@
--- a/init/main.c
+++ b/init/main.c
@@ -807,7 +807,7 @@ static noinline int init_post(void)
numa_default_policy();
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
- printk(KERN_WARNING "Warning: unable to open an initial console.\n");
+ printk(KERN_WARNING "Please be patient, while OpenWrt loads ...\n");
(void) sys_dup(0);
(void) sys_dup(0);

View File

@@ -1,102 +0,0 @@
--- a/scripts/genksyms/parse.c_shipped
+++ b/scripts/genksyms/parse.c_shipped
@@ -160,7 +160,9 @@
#include <assert.h>
+#ifndef __APPLE__
#include <malloc.h>
+#endif
#include "genksyms.h"
static int is_typedef;
--- a/scripts/genksyms/parse.y
+++ b/scripts/genksyms/parse.y
@@ -24,7 +24,9 @@
%{
#include <assert.h>
+#ifndef __APPLE__
#include <malloc.h>
+#endif
#include "genksyms.h"
static int is_typedef;
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -22,6 +22,35 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#ifdef __APPLE__
+/* Darwin has no memmem implementation, this one is ripped of the uClibc-0.9.28 source */
+void *memmem (const void *haystack, size_t haystack_len,
+ const void *needle, size_t needle_len)
+{
+ const char *begin;
+ const char *const last_possible
+ = (const char *) haystack + haystack_len - needle_len;
+
+ if (needle_len == 0)
+ /* The first occurrence of the empty string is deemed to occur at
+ the beginning of the string. */
+ return (void *) haystack;
+
+ /* Sanity check, otherwise the loop might search through the whole
+ memory. */
+ if (__builtin_expect (haystack_len < needle_len, 0))
+ return NULL;
+
+ for (begin = (const char *) haystack; begin <= last_possible; ++begin)
+ if (begin[0] == ((const char *) needle)[0] &&
+ !memcmp ((const void *) &begin[1],
+ (const void *) ((const char *) needle + 1),
+ needle_len - 1))
+ return (void *) begin;
+
+ return NULL;
+}
+#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -130,6 +130,9 @@ check-lxdialog := $(srctree)/$(src)/lxd
# we really need to do so. (Do not call gcc as part of make mrproper)
HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+ifeq ($(shell uname -s),Darwin)
+HOST_LOADLIBES += -lncurses
+endif
HOST_EXTRACFLAGS += -DLOCALE
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -1,7 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifndef __APPLE__
#include <elf.h>
+#else
+#include "../../../../../tools/sstrip/include/elf.h"
+#endif
int
main(int argc, char **argv)
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -7,7 +7,11 @@
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
+#if !(defined(__APPLE__) || defined(__CYGWIN__))
#include <elf.h>
+#else
+#include "../../../../../tools/sstrip/include/elf.h"
+#endif
#include "elfconfig.h"

Some files were not shown because too many files have changed in this diff Show More