Initial patches commit
This commit is contained in:
commit
a902c236c9
@ -0,0 +1,553 @@
|
|||||||
|
From dc13dec93dbd04bfa7a9ba67df1b8ed3431d8d48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
|
Date: Wed, 10 Aug 2011 22:02:39 -0700
|
||||||
|
Subject: [PATCH 1/3] AppArmor: compatibility patch for v5 network controll
|
||||||
|
|
||||||
|
Add compatibility for v5 network rules.
|
||||||
|
|
||||||
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
---
|
||||||
|
include/linux/lsm_audit.h | 4 +
|
||||||
|
security/apparmor/Makefile | 19 ++++-
|
||||||
|
security/apparmor/include/net.h | 40 +++++++++
|
||||||
|
security/apparmor/include/policy.h | 3 +
|
||||||
|
security/apparmor/lsm.c | 112 +++++++++++++++++++++++
|
||||||
|
security/apparmor/net.c | 170 ++++++++++++++++++++++++++++++++++++
|
||||||
|
security/apparmor/policy.c | 1 +
|
||||||
|
security/apparmor/policy_unpack.c | 48 ++++++++++-
|
||||||
|
8 files changed, 394 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 security/apparmor/include/net.h
|
||||||
|
create mode 100644 security/apparmor/net.c
|
||||||
|
|
||||||
|
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
|
||||||
|
index 88e78de..c63979a 100644
|
||||||
|
--- a/include/linux/lsm_audit.h
|
||||||
|
+++ b/include/linux/lsm_audit.h
|
||||||
|
@@ -124,6 +124,10 @@ struct common_audit_data {
|
||||||
|
u32 denied;
|
||||||
|
uid_t ouid;
|
||||||
|
} fs;
|
||||||
|
+ struct {
|
||||||
|
+ int type, protocol;
|
||||||
|
+ struct sock *sk;
|
||||||
|
+ } net;
|
||||||
|
};
|
||||||
|
} apparmor_audit_data;
|
||||||
|
#endif
|
||||||
|
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||||
|
index 2dafe50..7cefef9 100644
|
||||||
|
--- a/security/apparmor/Makefile
|
||||||
|
+++ b/security/apparmor/Makefile
|
||||||
|
@@ -4,9 +4,9 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||||
|
|
||||||
|
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||||
|
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||||
|
- resource.o sid.o file.o
|
||||||
|
+ resource.o sid.o file.o net.o
|
||||||
|
|
||||||
|
-clean-files := capability_names.h rlim_names.h
|
||||||
|
+clean-files := capability_names.h rlim_names.h af_names.h
|
||||||
|
|
||||||
|
|
||||||
|
# Build a lower case string table of capability names
|
||||||
|
@@ -44,9 +44,24 @@ cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ;\
|
||||||
|
sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
|
||||||
|
echo "};" >> $@
|
||||||
|
|
||||||
|
+# Build a lower case string table of address family names.
|
||||||
|
+# Transform lines from
|
||||||
|
+# #define AF_INET 2 /* Internet IP Protocol */
|
||||||
|
+# to
|
||||||
|
+# [2] = "inet",
|
||||||
|
+quiet_cmd_make-af = GEN $@
|
||||||
|
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
|
||||||
|
+ sed $< >> $@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
|
||||||
|
+ 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+).*/[\2] = "\L\1",/p';\
|
||||||
|
+ echo "};" >> $@
|
||||||
|
+
|
||||||
|
+
|
||||||
|
$(obj)/capability.o : $(obj)/capability_names.h
|
||||||
|
$(obj)/resource.o : $(obj)/rlim_names.h
|
||||||
|
+$(obj)/net.o : $(obj)/af_names.h
|
||||||
|
$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
|
||||||
|
$(call cmd,make-caps)
|
||||||
|
$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h
|
||||||
|
$(call cmd,make-rlim)
|
||||||
|
+$(obj)/af_names.h : $(srctree)/include/linux/socket.h
|
||||||
|
+ $(call cmd,make-af)
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3c7d599
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/security/apparmor/include/net.h
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+/*
|
||||||
|
+ * AppArmor security module
|
||||||
|
+ *
|
||||||
|
+ * This file contains AppArmor network mediation definitions.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||||
|
+ * Copyright 2009-2010 Canonical Ltd.
|
||||||
|
+ *
|
||||||
|
+ * 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, version 2 of the
|
||||||
|
+ * License.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __AA_NET_H
|
||||||
|
+#define __AA_NET_H
|
||||||
|
+
|
||||||
|
+#include <net/sock.h>
|
||||||
|
+
|
||||||
|
+/* struct aa_net - network confinement data
|
||||||
|
+ * @allowed: basic network families permissions
|
||||||
|
+ * @audit_network: which network permissions to force audit
|
||||||
|
+ * @quiet_network: which network permissions to quiet rejects
|
||||||
|
+ */
|
||||||
|
+struct aa_net {
|
||||||
|
+ u16 allow[AF_MAX];
|
||||||
|
+ u16 audit[AF_MAX];
|
||||||
|
+ u16 quiet[AF_MAX];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
|
||||||
|
+ int type, int protocol, struct sock *sk);
|
||||||
|
+extern int aa_revalidate_sk(int op, struct sock *sk);
|
||||||
|
+
|
||||||
|
+static inline void aa_free_net_rules(struct aa_net *new)
|
||||||
|
+{
|
||||||
|
+ /* NOP */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* __AA_NET_H */
|
||||||
|
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
|
||||||
|
index aeda5cf..6776929 100644
|
||||||
|
--- a/security/apparmor/include/policy.h
|
||||||
|
+++ b/security/apparmor/include/policy.h
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include "capability.h"
|
||||||
|
#include "domain.h"
|
||||||
|
#include "file.h"
|
||||||
|
+#include "net.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
extern const char *profile_mode_names[];
|
||||||
|
@@ -145,6 +146,7 @@ struct aa_namespace {
|
||||||
|
* @size: the memory consumed by this profiles rules
|
||||||
|
* @file: The set of rules governing basic file access and domain transitions
|
||||||
|
* @caps: capabilities for the profile
|
||||||
|
+ * @net: network controls for the profile
|
||||||
|
* @rlimits: rlimits for the profile
|
||||||
|
*
|
||||||
|
* The AppArmor profile contains the basic confinement data. Each profile
|
||||||
|
@@ -181,6 +183,7 @@ struct aa_profile {
|
||||||
|
|
||||||
|
struct aa_file_rules file;
|
||||||
|
struct aa_caps caps;
|
||||||
|
+ struct aa_net net;
|
||||||
|
struct aa_rlimit rlimits;
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||||
|
index 3d2fd14..aa293ae 100644
|
||||||
|
--- a/security/apparmor/lsm.c
|
||||||
|
+++ b/security/apparmor/lsm.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include "include/context.h"
|
||||||
|
#include "include/file.h"
|
||||||
|
#include "include/ipc.h"
|
||||||
|
+#include "include/net.h"
|
||||||
|
#include "include/path.h"
|
||||||
|
#include "include/policy.h"
|
||||||
|
#include "include/procattr.h"
|
||||||
|
@@ -621,6 +622,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile;
|
||||||
|
+ int error = 0;
|
||||||
|
+
|
||||||
|
+ if (kern)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ profile = __aa_current_profile();
|
||||||
|
+ if (!unconfined(profile))
|
||||||
|
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
|
||||||
|
+ NULL);
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_bind(struct socket *sock,
|
||||||
|
+ struct sockaddr *address, int addrlen)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_BIND, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_connect(struct socket *sock,
|
||||||
|
+ struct sockaddr *address, int addrlen)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_CONNECT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_listen(struct socket *sock, int backlog)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_LISTEN, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_ACCEPT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_sendmsg(struct socket *sock,
|
||||||
|
+ struct msghdr *msg, int size)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_SENDMSG, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_recvmsg(struct socket *sock,
|
||||||
|
+ struct msghdr *msg, int size, int flags)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_RECVMSG, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_getsockname(struct socket *sock)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_getpeername(struct socket *sock)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
|
||||||
|
+ int optname)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
|
||||||
|
+ int optname)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_shutdown(struct socket *sock, int how)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct security_operations apparmor_ops = {
|
||||||
|
.name = "apparmor",
|
||||||
|
|
||||||
|
@@ -652,6 +751,19 @@ static struct security_operations apparmor_ops = {
|
||||||
|
.getprocattr = apparmor_getprocattr,
|
||||||
|
.setprocattr = apparmor_setprocattr,
|
||||||
|
|
||||||
|
+ .socket_create = apparmor_socket_create,
|
||||||
|
+ .socket_bind = apparmor_socket_bind,
|
||||||
|
+ .socket_connect = apparmor_socket_connect,
|
||||||
|
+ .socket_listen = apparmor_socket_listen,
|
||||||
|
+ .socket_accept = apparmor_socket_accept,
|
||||||
|
+ .socket_sendmsg = apparmor_socket_sendmsg,
|
||||||
|
+ .socket_recvmsg = apparmor_socket_recvmsg,
|
||||||
|
+ .socket_getsockname = apparmor_socket_getsockname,
|
||||||
|
+ .socket_getpeername = apparmor_socket_getpeername,
|
||||||
|
+ .socket_getsockopt = apparmor_socket_getsockopt,
|
||||||
|
+ .socket_setsockopt = apparmor_socket_setsockopt,
|
||||||
|
+ .socket_shutdown = apparmor_socket_shutdown,
|
||||||
|
+
|
||||||
|
.cred_alloc_blank = apparmor_cred_alloc_blank,
|
||||||
|
.cred_free = apparmor_cred_free,
|
||||||
|
.cred_prepare = apparmor_cred_prepare,
|
||||||
|
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1765901
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/security/apparmor/net.c
|
||||||
|
@@ -0,0 +1,170 @@
|
||||||
|
+/*
|
||||||
|
+ * AppArmor security module
|
||||||
|
+ *
|
||||||
|
+ * This file contains AppArmor network mediation
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||||
|
+ * Copyright 2009-2010 Canonical Ltd.
|
||||||
|
+ *
|
||||||
|
+ * 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, version 2 of the
|
||||||
|
+ * License.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "include/apparmor.h"
|
||||||
|
+#include "include/audit.h"
|
||||||
|
+#include "include/context.h"
|
||||||
|
+#include "include/net.h"
|
||||||
|
+#include "include/policy.h"
|
||||||
|
+
|
||||||
|
+#include "af_names.h"
|
||||||
|
+
|
||||||
|
+static const char *sock_type_names[] = {
|
||||||
|
+ "unknown(0)",
|
||||||
|
+ "stream",
|
||||||
|
+ "dgram",
|
||||||
|
+ "raw",
|
||||||
|
+ "rdm",
|
||||||
|
+ "seqpacket",
|
||||||
|
+ "dccp",
|
||||||
|
+ "unknown(7)",
|
||||||
|
+ "unknown(8)",
|
||||||
|
+ "unknown(9)",
|
||||||
|
+ "packet",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* audit callback for net specific fields */
|
||||||
|
+static void audit_cb(struct audit_buffer *ab, void *va)
|
||||||
|
+{
|
||||||
|
+ struct common_audit_data *sa = va;
|
||||||
|
+
|
||||||
|
+ audit_log_format(ab, " family=");
|
||||||
|
+ if (address_family_names[sa->u.net.family]) {
|
||||||
|
+ audit_log_string(ab, address_family_names[sa->u.net.family]);
|
||||||
|
+ } else {
|
||||||
|
+ audit_log_format(ab, " \"unknown(%d)\"", sa->u.net.family);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ audit_log_format(ab, " sock_type=");
|
||||||
|
+ if (sock_type_names[sa->aad.net.type]) {
|
||||||
|
+ audit_log_string(ab, sock_type_names[sa->aad.net.type]);
|
||||||
|
+ } else {
|
||||||
|
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad.net.type);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ audit_log_format(ab, " protocol=%d", sa->aad.net.protocol);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * audit_net - audit network access
|
||||||
|
+ * @profile: profile being enforced (NOT NULL)
|
||||||
|
+ * @op: operation being checked
|
||||||
|
+ * @family: network family
|
||||||
|
+ * @type: network type
|
||||||
|
+ * @protocol: network protocol
|
||||||
|
+ * @sk: socket auditing is being applied to
|
||||||
|
+ * @error: error code for failure else 0
|
||||||
|
+ *
|
||||||
|
+ * Returns: %0 or sa->error else other errorcode on failure
|
||||||
|
+ */
|
||||||
|
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||||
|
+ int protocol, struct sock *sk, int error)
|
||||||
|
+{
|
||||||
|
+ int audit_type = AUDIT_APPARMOR_AUTO;
|
||||||
|
+ struct common_audit_data sa;
|
||||||
|
+ if (sk) {
|
||||||
|
+ COMMON_AUDIT_DATA_INIT(&sa, NET);
|
||||||
|
+ } else {
|
||||||
|
+ COMMON_AUDIT_DATA_INIT(&sa, NONE);
|
||||||
|
+ }
|
||||||
|
+ /* todo fill in socket addr info */
|
||||||
|
+
|
||||||
|
+ sa.aad.op = op,
|
||||||
|
+ sa.u.net.family = family;
|
||||||
|
+ sa.u.net.sk = sk;
|
||||||
|
+ sa.aad.net.type = type;
|
||||||
|
+ sa.aad.net.protocol = protocol;
|
||||||
|
+ sa.aad.error = error;
|
||||||
|
+
|
||||||
|
+ if (likely(!sa.aad.error)) {
|
||||||
|
+ u16 audit_mask = profile->net.audit[sa.u.net.family];
|
||||||
|
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
|
||||||
|
+ !(1 << sa.aad.net.type & audit_mask)))
|
||||||
|
+ return 0;
|
||||||
|
+ audit_type = AUDIT_APPARMOR_AUDIT;
|
||||||
|
+ } else {
|
||||||
|
+ u16 quiet_mask = profile->net.quiet[sa.u.net.family];
|
||||||
|
+ u16 kill_mask = 0;
|
||||||
|
+ u16 denied = (1 << sa.aad.net.type) & ~quiet_mask;
|
||||||
|
+
|
||||||
|
+ if (denied & kill_mask)
|
||||||
|
+ audit_type = AUDIT_APPARMOR_KILL;
|
||||||
|
+
|
||||||
|
+ if ((denied & quiet_mask) &&
|
||||||
|
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
|
||||||
|
+ AUDIT_MODE(profile) != AUDIT_ALL)
|
||||||
|
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad.error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * aa_net_perm - very course network access check
|
||||||
|
+ * @op: operation being checked
|
||||||
|
+ * @profile: profile being enforced (NOT NULL)
|
||||||
|
+ * @family: network family
|
||||||
|
+ * @type: network type
|
||||||
|
+ * @protocol: network protocol
|
||||||
|
+ *
|
||||||
|
+ * Returns: %0 else error if permission denied
|
||||||
|
+ */
|
||||||
|
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
|
||||||
|
+ int protocol, struct sock *sk)
|
||||||
|
+{
|
||||||
|
+ u16 family_mask;
|
||||||
|
+ int error;
|
||||||
|
+
|
||||||
|
+ if ((family < 0) || (family >= AF_MAX))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ if ((type < 0) || (type >= SOCK_MAX))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* unix domain and netlink sockets are handled by ipc */
|
||||||
|
+ if (family == AF_UNIX || family == AF_NETLINK)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ family_mask = profile->net.allow[family];
|
||||||
|
+
|
||||||
|
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
|
||||||
|
+
|
||||||
|
+ return audit_net(profile, op, family, type, protocol, sk, error);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * aa_revalidate_sk - Revalidate access to a sock
|
||||||
|
+ * @op: operation being checked
|
||||||
|
+ * @sk: sock being revalidated (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: %0 else error if permission denied
|
||||||
|
+ */
|
||||||
|
+int aa_revalidate_sk(int op, struct sock *sk)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile;
|
||||||
|
+ int error = 0;
|
||||||
|
+
|
||||||
|
+ /* aa_revalidate_sk should not be called from interrupt context
|
||||||
|
+ * don't mediate these calls as they are not task related
|
||||||
|
+ */
|
||||||
|
+ if (in_interrupt())
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ profile = __aa_current_profile();
|
||||||
|
+ if (!unconfined(profile))
|
||||||
|
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
|
||||||
|
+ sk->sk_protocol, sk);
|
||||||
|
+
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||||
|
index 4f0eade..4d5ce13 100644
|
||||||
|
--- a/security/apparmor/policy.c
|
||||||
|
+++ b/security/apparmor/policy.c
|
||||||
|
@@ -745,6 +745,7 @@ static void free_profile(struct aa_profile *profile)
|
||||||
|
|
||||||
|
aa_free_file_rules(&profile->file);
|
||||||
|
aa_free_cap_rules(&profile->caps);
|
||||||
|
+ aa_free_net_rules(&profile->net);
|
||||||
|
aa_free_rlimit_rules(&profile->rlimits);
|
||||||
|
|
||||||
|
aa_free_sid(profile->sid);
|
||||||
|
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||||
|
index d6d9a57..f4874c4 100644
|
||||||
|
--- a/security/apparmor/policy_unpack.c
|
||||||
|
+++ b/security/apparmor/policy_unpack.c
|
||||||
|
@@ -190,6 +190,19 @@ fail:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||||
|
+{
|
||||||
|
+ if (unpack_nameX(e, AA_U16, name)) {
|
||||||
|
+ if (!inbounds(e, sizeof(u16)))
|
||||||
|
+ return 0;
|
||||||
|
+ if (data)
|
||||||
|
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||||
|
+ e->pos += sizeof(u16);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||||
|
{
|
||||||
|
if (unpack_nameX(e, AA_U32, name)) {
|
||||||
|
@@ -468,7 +481,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||||
|
{
|
||||||
|
struct aa_profile *profile = NULL;
|
||||||
|
const char *name = NULL;
|
||||||
|
- int error = -EPROTO;
|
||||||
|
+ size_t size = 0;
|
||||||
|
+ int i, error = -EPROTO;
|
||||||
|
kernel_cap_t tmpcap;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
@@ -559,6 +573,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||||
|
if (!unpack_rlimits(e, profile))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
+ size = unpack_array(e, "net_allowed_af");
|
||||||
|
+ if (size) {
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < size; i++) {
|
||||||
|
+ /* discard extraneous rules that this kernel will
|
||||||
|
+ * never request
|
||||||
|
+ */
|
||||||
|
+ if (i >= AF_MAX) {
|
||||||
|
+ u16 tmp;
|
||||||
|
+ if (!unpack_u16(e, &tmp, NULL) ||
|
||||||
|
+ !unpack_u16(e, &tmp, NULL) ||
|
||||||
|
+ !unpack_u16(e, &tmp, NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ /*
|
||||||
|
+ * allow unix domain and netlink sockets they are handled
|
||||||
|
+ * by IPC
|
||||||
|
+ */
|
||||||
|
+ }
|
||||||
|
+ profile->net.allow[AF_UNIX] = 0xffff;
|
||||||
|
+ profile->net.allow[AF_NETLINK] = 0xffff;
|
||||||
|
+
|
||||||
|
/* get file rules */
|
||||||
|
profile->file.dfa = unpack_dfa(e);
|
||||||
|
if (IS_ERR(profile->file.dfa)) {
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
@ -0,0 +1,299 @@
|
|||||||
|
From f9072731bedac6f6373dd75798b5a801ce614c02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Arianna Avanzini <avanzini.arianna@gmail.com>
|
||||||
|
Date: Mon, 19 Dec 2011 16:33:41 +0100
|
||||||
|
Subject: [PATCH 1/3] block: prepare I/O context code for BFQ-v5 for 3.2
|
||||||
|
|
||||||
|
BFQ uses struct cfq_io_context to store its per-process per-device data,
|
||||||
|
reusing the same code for cic handling of CFQ. The code is not shared
|
||||||
|
ATM to minimize the impact of these patches.
|
||||||
|
|
||||||
|
This patch introduces a new hlist to each io_context to store all the
|
||||||
|
cic's allocated by BFQ to allow calling the right destructor on module
|
||||||
|
unload; the radix tree used for cic lookup needs to be duplicated
|
||||||
|
because it can contain dead keys inserted by a scheduler and later
|
||||||
|
retrieved by the other one.
|
||||||
|
|
||||||
|
Update the io_context exit and free paths to take care also of
|
||||||
|
the BFQ cic's.
|
||||||
|
|
||||||
|
Change the type of cfqq inside struct cfq_io_context to void *
|
||||||
|
to use it also for BFQ per-queue data.
|
||||||
|
|
||||||
|
A new bfq-specific ioprio_changed field is necessary, too, to avoid
|
||||||
|
clobbering cfq's one, so switch ioprio_changed to a bitmap, with one
|
||||||
|
element per scheduler.
|
||||||
|
|
||||||
|
Signed-off-by: Fabio Checconi <fabio@gandalf.sssup.it>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
|
||||||
|
Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
|
||||||
|
---
|
||||||
|
block/Kconfig.iosched | 26 ++++++++++++++++++++++++++
|
||||||
|
block/blk-ioc.c | 30 +++++++++++++++++-------------
|
||||||
|
block/cfq-iosched.c | 10 +++++++---
|
||||||
|
fs/ioprio.c | 9 +++++++--
|
||||||
|
include/linux/iocontext.h | 18 +++++++++++++++---
|
||||||
|
5 files changed, 72 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
|
||||||
|
index 3199b76..5905452 100644
|
||||||
|
--- a/block/Kconfig.iosched
|
||||||
|
+++ b/block/Kconfig.iosched
|
||||||
|
@@ -43,6 +43,28 @@ config CFQ_GROUP_IOSCHED
|
||||||
|
---help---
|
||||||
|
Enable group IO scheduling in CFQ.
|
||||||
|
|
||||||
|
+config IOSCHED_BFQ
|
||||||
|
+ tristate "BFQ I/O scheduler"
|
||||||
|
+ depends on EXPERIMENTAL
|
||||||
|
+ default n
|
||||||
|
+ ---help---
|
||||||
|
+ The BFQ I/O scheduler tries to distribute bandwidth among
|
||||||
|
+ all processes according to their weights.
|
||||||
|
+ It aims at distributing the bandwidth as desired, independently of
|
||||||
|
+ the disk parameters and with any workload. It also tries to
|
||||||
|
+ guarantee low latency to interactive and soft real-time
|
||||||
|
+ applications. If compiled built-in (saying Y here), BFQ can
|
||||||
|
+ be configured to support hierarchical scheduling.
|
||||||
|
+
|
||||||
|
+config CGROUP_BFQIO
|
||||||
|
+ bool "BFQ hierarchical scheduling support"
|
||||||
|
+ depends on CGROUPS && IOSCHED_BFQ=y
|
||||||
|
+ default n
|
||||||
|
+ ---help---
|
||||||
|
+ Enable hierarchical scheduling in BFQ, using the cgroups
|
||||||
|
+ filesystem interface. The name of the subsystem will be
|
||||||
|
+ bfqio.
|
||||||
|
+
|
||||||
|
choice
|
||||||
|
prompt "Default I/O scheduler"
|
||||||
|
default DEFAULT_CFQ
|
||||||
|
@@ -56,6 +78,9 @@ choice
|
||||||
|
config DEFAULT_CFQ
|
||||||
|
bool "CFQ" if IOSCHED_CFQ=y
|
||||||
|
|
||||||
|
+ config DEFAULT_BFQ
|
||||||
|
+ bool "BFQ" if IOSCHED_BFQ=y
|
||||||
|
+
|
||||||
|
config DEFAULT_NOOP
|
||||||
|
bool "No-op"
|
||||||
|
|
||||||
|
@@ -65,6 +90,7 @@ config DEFAULT_IOSCHED
|
||||||
|
string
|
||||||
|
default "deadline" if DEFAULT_DEADLINE
|
||||||
|
default "cfq" if DEFAULT_CFQ
|
||||||
|
+ default "bfq" if DEFAULT_BFQ
|
||||||
|
default "noop" if DEFAULT_NOOP
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
|
||||||
|
index 6f9bbd9..d0d16d4 100644
|
||||||
|
--- a/block/blk-ioc.c
|
||||||
|
+++ b/block/blk-ioc.c
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/bio.h>
|
||||||
|
+#include <linux/bitmap.h>
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/bootmem.h> /* for max_pfn/max_low_pfn */
|
||||||
|
#include <linux/slab.h>
|
||||||
|
@@ -16,13 +17,12 @@
|
||||||
|
*/
|
||||||
|
static struct kmem_cache *iocontext_cachep;
|
||||||
|
|
||||||
|
-static void cfq_dtor(struct io_context *ioc)
|
||||||
|
+static void hlist_sched_dtor(struct io_context *ioc, struct hlist_head *list)
|
||||||
|
{
|
||||||
|
- if (!hlist_empty(&ioc->cic_list)) {
|
||||||
|
+ if (!hlist_empty(list)) {
|
||||||
|
struct cfq_io_context *cic;
|
||||||
|
|
||||||
|
- cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
|
||||||
|
- cic_list);
|
||||||
|
+ cic = hlist_entry(list->first, struct cfq_io_context, cic_list);
|
||||||
|
cic->dtor(ioc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -40,7 +40,9 @@ int put_io_context(struct io_context *ioc)
|
||||||
|
|
||||||
|
if (atomic_long_dec_and_test(&ioc->refcount)) {
|
||||||
|
rcu_read_lock();
|
||||||
|
- cfq_dtor(ioc);
|
||||||
|
+
|
||||||
|
+ hlist_sched_dtor(ioc, &ioc->cic_list);
|
||||||
|
+ hlist_sched_dtor(ioc, &ioc->bfq_cic_list);
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
kmem_cache_free(iocontext_cachep, ioc);
|
||||||
|
@@ -50,15 +52,14 @@ int put_io_context(struct io_context *ioc)
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(put_io_context);
|
||||||
|
|
||||||
|
-static void cfq_exit(struct io_context *ioc)
|
||||||
|
+static void hlist_sched_exit(struct io_context *ioc, struct hlist_head *list)
|
||||||
|
{
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
- if (!hlist_empty(&ioc->cic_list)) {
|
||||||
|
+ if (!hlist_empty(list)) {
|
||||||
|
struct cfq_io_context *cic;
|
||||||
|
|
||||||
|
- cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
|
||||||
|
- cic_list);
|
||||||
|
+ cic = hlist_entry(list->first, struct cfq_io_context, cic_list);
|
||||||
|
cic->exit(ioc);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
@@ -74,9 +75,10 @@ void exit_io_context(struct task_struct *task)
|
||||||
|
task->io_context = NULL;
|
||||||
|
task_unlock(task);
|
||||||
|
|
||||||
|
- if (atomic_dec_and_test(&ioc->nr_tasks))
|
||||||
|
- cfq_exit(ioc);
|
||||||
|
-
|
||||||
|
+ if (atomic_dec_and_test(&ioc->nr_tasks)) {
|
||||||
|
+ hlist_sched_exit(ioc, &ioc->cic_list);
|
||||||
|
+ hlist_sched_exit(ioc, &ioc->bfq_cic_list);
|
||||||
|
+ }
|
||||||
|
put_io_context(ioc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -89,12 +91,14 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
|
||||||
|
atomic_long_set(&ioc->refcount, 1);
|
||||||
|
atomic_set(&ioc->nr_tasks, 1);
|
||||||
|
spin_lock_init(&ioc->lock);
|
||||||
|
- ioc->ioprio_changed = 0;
|
||||||
|
+ bitmap_zero(ioc->ioprio_changed, IOC_IOPRIO_CHANGED_BITS);
|
||||||
|
ioc->ioprio = 0;
|
||||||
|
ioc->last_waited = 0; /* doesn't matter... */
|
||||||
|
ioc->nr_batch_requests = 0; /* because this is 0 */
|
||||||
|
INIT_RADIX_TREE(&ioc->radix_root, GFP_ATOMIC | __GFP_HIGH);
|
||||||
|
INIT_HLIST_HEAD(&ioc->cic_list);
|
||||||
|
+ INIT_RADIX_TREE(&ioc->bfq_radix_root, GFP_ATOMIC | __GFP_HIGH);
|
||||||
|
+ INIT_HLIST_HEAD(&ioc->bfq_cic_list);
|
||||||
|
ioc->ioc_data = NULL;
|
||||||
|
#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
|
||||||
|
ioc->cgroup_changed = 0;
|
||||||
|
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
|
||||||
|
index 3548705..a120a31 100644
|
||||||
|
--- a/block/cfq-iosched.c
|
||||||
|
+++ b/block/cfq-iosched.c
|
||||||
|
@@ -2946,7 +2946,6 @@ static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic)
|
||||||
|
static void cfq_ioc_set_ioprio(struct io_context *ioc)
|
||||||
|
{
|
||||||
|
call_for_each_cic(ioc, changed_ioprio);
|
||||||
|
- ioc->ioprio_changed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
|
||||||
|
@@ -3238,8 +3237,13 @@ retry:
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
out:
|
||||||
|
- smp_read_barrier_depends();
|
||||||
|
- if (unlikely(ioc->ioprio_changed))
|
||||||
|
+ /*
|
||||||
|
+ * test_and_clear_bit() implies a memory barrier, paired with
|
||||||
|
+ * the wmb() in fs/ioprio.c, so the value seen for ioprio is the
|
||||||
|
+ * new one.
|
||||||
|
+ */
|
||||||
|
+ if (unlikely(test_and_clear_bit(IOC_CFQ_IOPRIO_CHANGED,
|
||||||
|
+ ioc->ioprio_changed)))
|
||||||
|
cfq_ioc_set_ioprio(ioc);
|
||||||
|
|
||||||
|
#ifdef CONFIG_CFQ_GROUP_IOSCHED
|
||||||
|
diff --git a/fs/ioprio.c b/fs/ioprio.c
|
||||||
|
index f79dab8..6b0cb885 100644
|
||||||
|
--- a/fs/ioprio.c
|
||||||
|
+++ b/fs/ioprio.c
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
|
||||||
|
int set_task_ioprio(struct task_struct *task, int ioprio)
|
||||||
|
{
|
||||||
|
- int err;
|
||||||
|
+ int err, i;
|
||||||
|
struct io_context *ioc;
|
||||||
|
const struct cred *cred = current_cred(), *tcred;
|
||||||
|
|
||||||
|
@@ -61,12 +61,17 @@ int set_task_ioprio(struct task_struct *task, int ioprio)
|
||||||
|
err = -ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ /* let other ioc users see the new values */
|
||||||
|
+ smp_wmb();
|
||||||
|
task->io_context = ioc;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
ioc->ioprio = ioprio;
|
||||||
|
- ioc->ioprio_changed = 1;
|
||||||
|
+ /* make sure schedulers see the new ioprio value */
|
||||||
|
+ wmb();
|
||||||
|
+ for (i = 0; i < IOC_IOPRIO_CHANGED_BITS; i++)
|
||||||
|
+ set_bit(i, ioc->ioprio_changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
task_unlock(task);
|
||||||
|
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
|
||||||
|
index 5037a0a..69fdd58 100644
|
||||||
|
--- a/include/linux/iocontext.h
|
||||||
|
+++ b/include/linux/iocontext.h
|
||||||
|
@@ -1,10 +1,10 @@
|
||||||
|
#ifndef IOCONTEXT_H
|
||||||
|
#define IOCONTEXT_H
|
||||||
|
|
||||||
|
+#include <linux/bitmap.h>
|
||||||
|
#include <linux/radix-tree.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
|
||||||
|
-struct cfq_queue;
|
||||||
|
struct cfq_ttime {
|
||||||
|
unsigned long last_end_request;
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@ struct cfq_ttime {
|
||||||
|
struct cfq_io_context {
|
||||||
|
void *key;
|
||||||
|
|
||||||
|
- struct cfq_queue *cfqq[2];
|
||||||
|
+ void *cfqq[2];
|
||||||
|
|
||||||
|
struct io_context *ioc;
|
||||||
|
|
||||||
|
@@ -32,6 +32,16 @@ struct cfq_io_context {
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * Indexes into the ioprio_changed bitmap. A bit set indicates that
|
||||||
|
+ * the corresponding I/O scheduler needs to see a ioprio update.
|
||||||
|
+ */
|
||||||
|
+enum {
|
||||||
|
+ IOC_CFQ_IOPRIO_CHANGED,
|
||||||
|
+ IOC_BFQ_IOPRIO_CHANGED,
|
||||||
|
+ IOC_IOPRIO_CHANGED_BITS
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* I/O subsystem state of the associated processes. It is refcounted
|
||||||
|
* and kmalloc'ed. These could be shared between processes.
|
||||||
|
*/
|
||||||
|
@@ -43,7 +53,7 @@ struct io_context {
|
||||||
|
spinlock_t lock;
|
||||||
|
|
||||||
|
unsigned short ioprio;
|
||||||
|
- unsigned short ioprio_changed;
|
||||||
|
+ DECLARE_BITMAP(ioprio_changed, IOC_IOPRIO_CHANGED_BITS);
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
|
||||||
|
unsigned short cgroup_changed;
|
||||||
|
@@ -57,6 +67,8 @@ struct io_context {
|
||||||
|
|
||||||
|
struct radix_tree_root radix_root;
|
||||||
|
struct hlist_head cic_list;
|
||||||
|
+ struct radix_tree_root bfq_radix_root;
|
||||||
|
+ struct hlist_head bfq_cic_list;
|
||||||
|
void __rcu *ioc_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10.4
|
||||||
|
|
391
3.2.34/0002-AppArmor-compatibility-patch-for-v5-interface.patch
Normal file
391
3.2.34/0002-AppArmor-compatibility-patch-for-v5-interface.patch
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
From a2515f25ad5a7833ddc5a032d34eee6a5ddee3a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
|
Date: Wed, 10 Aug 2011 22:02:40 -0700
|
||||||
|
Subject: [PATCH 2/3] AppArmor: compatibility patch for v5 interface
|
||||||
|
|
||||||
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
---
|
||||||
|
security/apparmor/Kconfig | 9 +
|
||||||
|
security/apparmor/Makefile | 1 +
|
||||||
|
security/apparmor/apparmorfs-24.c | 287 ++++++++++++++++++++++++++++++++
|
||||||
|
security/apparmor/apparmorfs.c | 18 ++-
|
||||||
|
security/apparmor/include/apparmorfs.h | 6 +
|
||||||
|
5 files changed, 319 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 security/apparmor/apparmorfs-24.c
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
|
||||||
|
index 9b9013b..51ebf96 100644
|
||||||
|
--- a/security/apparmor/Kconfig
|
||||||
|
+++ b/security/apparmor/Kconfig
|
||||||
|
@@ -29,3 +29,12 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
|
||||||
|
boot.
|
||||||
|
|
||||||
|
If you are unsure how to answer this question, answer 1.
|
||||||
|
+
|
||||||
|
+config SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ bool "Enable AppArmor 2.4 compatability"
|
||||||
|
+ depends on SECURITY_APPARMOR
|
||||||
|
+ default y
|
||||||
|
+ help
|
||||||
|
+ This option enables compatability with AppArmor 2.4. It is
|
||||||
|
+ recommended if compatability with older versions of AppArmor
|
||||||
|
+ is desired.
|
||||||
|
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||||
|
index 7cefef9..0bb604b 100644
|
||||||
|
--- a/security/apparmor/Makefile
|
||||||
|
+++ b/security/apparmor/Makefile
|
||||||
|
@@ -5,6 +5,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||||
|
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||||
|
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||||
|
resource.o sid.o file.o net.o
|
||||||
|
+apparmor-$(CONFIG_SECURITY_APPARMOR_COMPAT_24) += apparmorfs-24.o
|
||||||
|
|
||||||
|
clean-files := capability_names.h rlim_names.h af_names.h
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/apparmorfs-24.c b/security/apparmor/apparmorfs-24.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..dc8c744
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/security/apparmor/apparmorfs-24.c
|
||||||
|
@@ -0,0 +1,287 @@
|
||||||
|
+/*
|
||||||
|
+ * AppArmor security module
|
||||||
|
+ *
|
||||||
|
+ * This file contains AppArmor /sys/kernel/secrutiy/apparmor interface functions
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||||
|
+ * Copyright 2009-2010 Canonical Ltd.
|
||||||
|
+ *
|
||||||
|
+ * 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, version 2 of the
|
||||||
|
+ * License.
|
||||||
|
+ *
|
||||||
|
+ *
|
||||||
|
+ * This file contain functions providing an interface for <= AppArmor 2.4
|
||||||
|
+ * compatibility. It is dependent on CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ * being set (see Makefile).
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/security.h>
|
||||||
|
+#include <linux/vmalloc.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/seq_file.h>
|
||||||
|
+#include <linux/uaccess.h>
|
||||||
|
+#include <linux/namei.h>
|
||||||
|
+
|
||||||
|
+#include "include/apparmor.h"
|
||||||
|
+#include "include/audit.h"
|
||||||
|
+#include "include/context.h"
|
||||||
|
+#include "include/policy.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* apparmor/matching */
|
||||||
|
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
|
||||||
|
+ size_t size, loff_t *ppos)
|
||||||
|
+{
|
||||||
|
+ const char matching[] = "pattern=aadfa audit perms=crwxamlk/ "
|
||||||
|
+ "user::other";
|
||||||
|
+
|
||||||
|
+ return simple_read_from_buffer(buf, size, ppos, matching,
|
||||||
|
+ sizeof(matching) - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct file_operations aa_fs_matching_fops = {
|
||||||
|
+ .read = aa_matching_read,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* apparmor/features */
|
||||||
|
+static ssize_t aa_features_read(struct file *file, char __user *buf,
|
||||||
|
+ size_t size, loff_t *ppos)
|
||||||
|
+{
|
||||||
|
+ const char features[] = "file=3.1 capability=2.0 network=1.0 "
|
||||||
|
+ "change_hat=1.5 change_profile=1.1 " "aanamespaces=1.1 rlimit=1.1";
|
||||||
|
+
|
||||||
|
+ return simple_read_from_buffer(buf, size, ppos, features,
|
||||||
|
+ sizeof(features) - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct file_operations aa_fs_features_fops = {
|
||||||
|
+ .read = aa_features_read,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * __next_namespace - find the next namespace to list
|
||||||
|
+ * @root: root namespace to stop search at (NOT NULL)
|
||||||
|
+ * @ns: current ns position (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Find the next namespace from @ns under @root and handle all locking needed
|
||||||
|
+ * while switching current namespace.
|
||||||
|
+ *
|
||||||
|
+ * Returns: next namespace or NULL if at last namespace under @root
|
||||||
|
+ * NOTE: will not unlock root->lock
|
||||||
|
+ */
|
||||||
|
+static struct aa_namespace *__next_namespace(struct aa_namespace *root,
|
||||||
|
+ struct aa_namespace *ns)
|
||||||
|
+{
|
||||||
|
+ struct aa_namespace *parent;
|
||||||
|
+
|
||||||
|
+ /* is next namespace a child */
|
||||||
|
+ if (!list_empty(&ns->sub_ns)) {
|
||||||
|
+ struct aa_namespace *next;
|
||||||
|
+ next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
|
||||||
|
+ read_lock(&next->lock);
|
||||||
|
+ return next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check if the next ns is a sibling, parent, gp, .. */
|
||||||
|
+ parent = ns->parent;
|
||||||
|
+ while (parent) {
|
||||||
|
+ read_unlock(&ns->lock);
|
||||||
|
+ list_for_each_entry_continue(ns, &parent->sub_ns, base.list) {
|
||||||
|
+ read_lock(&ns->lock);
|
||||||
|
+ return ns;
|
||||||
|
+ }
|
||||||
|
+ if (parent == root)
|
||||||
|
+ return NULL;
|
||||||
|
+ ns = parent;
|
||||||
|
+ parent = parent->parent;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * __first_profile - find the first profile in a namespace
|
||||||
|
+ * @root: namespace that is root of profiles being displayed (NOT NULL)
|
||||||
|
+ * @ns: namespace to start in (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: unrefcounted profile or NULL if no profile
|
||||||
|
+ */
|
||||||
|
+static struct aa_profile *__first_profile(struct aa_namespace *root,
|
||||||
|
+ struct aa_namespace *ns)
|
||||||
|
+{
|
||||||
|
+ for ( ; ns; ns = __next_namespace(root, ns)) {
|
||||||
|
+ if (!list_empty(&ns->base.profiles))
|
||||||
|
+ return list_first_entry(&ns->base.profiles,
|
||||||
|
+ struct aa_profile, base.list);
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * __next_profile - step to the next profile in a profile tree
|
||||||
|
+ * @profile: current profile in tree (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Perform a depth first taversal on the profile tree in a namespace
|
||||||
|
+ *
|
||||||
|
+ * Returns: next profile or NULL if done
|
||||||
|
+ * Requires: profile->ns.lock to be held
|
||||||
|
+ */
|
||||||
|
+static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *parent;
|
||||||
|
+ struct aa_namespace *ns = p->ns;
|
||||||
|
+
|
||||||
|
+ /* is next profile a child */
|
||||||
|
+ if (!list_empty(&p->base.profiles))
|
||||||
|
+ return list_first_entry(&p->base.profiles, typeof(*p),
|
||||||
|
+ base.list);
|
||||||
|
+
|
||||||
|
+ /* is next profile a sibling, parent sibling, gp, subling, .. */
|
||||||
|
+ parent = p->parent;
|
||||||
|
+ while (parent) {
|
||||||
|
+ list_for_each_entry_continue(p, &parent->base.profiles,
|
||||||
|
+ base.list)
|
||||||
|
+ return p;
|
||||||
|
+ p = parent;
|
||||||
|
+ parent = parent->parent;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* is next another profile in the namespace */
|
||||||
|
+ list_for_each_entry_continue(p, &ns->base.profiles, base.list)
|
||||||
|
+ return p;
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * next_profile - step to the next profile in where ever it may be
|
||||||
|
+ * @root: root namespace (NOT NULL)
|
||||||
|
+ * @profile: current profile (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: next profile or NULL if there isn't one
|
||||||
|
+ */
|
||||||
|
+static struct aa_profile *next_profile(struct aa_namespace *root,
|
||||||
|
+ struct aa_profile *profile)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *next = __next_profile(profile);
|
||||||
|
+ if (next)
|
||||||
|
+ return next;
|
||||||
|
+
|
||||||
|
+ /* finished all profiles in namespace move to next namespace */
|
||||||
|
+ return __first_profile(root, __next_namespace(root, profile->ns));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * p_start - start a depth first traversal of profile tree
|
||||||
|
+ * @f: seq_file to fill
|
||||||
|
+ * @pos: current position
|
||||||
|
+ *
|
||||||
|
+ * Returns: first profile under current namespace or NULL if none found
|
||||||
|
+ *
|
||||||
|
+ * acquires first ns->lock
|
||||||
|
+ */
|
||||||
|
+static void *p_start(struct seq_file *f, loff_t *pos)
|
||||||
|
+ __acquires(root->lock)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = NULL;
|
||||||
|
+ struct aa_namespace *root = aa_current_profile()->ns;
|
||||||
|
+ loff_t l = *pos;
|
||||||
|
+ f->private = aa_get_namespace(root);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /* find the first profile */
|
||||||
|
+ read_lock(&root->lock);
|
||||||
|
+ profile = __first_profile(root, root);
|
||||||
|
+
|
||||||
|
+ /* skip to position */
|
||||||
|
+ for (; profile && l > 0; l--)
|
||||||
|
+ profile = next_profile(root, profile);
|
||||||
|
+
|
||||||
|
+ return profile;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * p_next - read the next profile entry
|
||||||
|
+ * @f: seq_file to fill
|
||||||
|
+ * @p: profile previously returned
|
||||||
|
+ * @pos: current position
|
||||||
|
+ *
|
||||||
|
+ * Returns: next profile after @p or NULL if none
|
||||||
|
+ *
|
||||||
|
+ * may acquire/release locks in namespace tree as necessary
|
||||||
|
+ */
|
||||||
|
+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = p;
|
||||||
|
+ struct aa_namespace *root = f->private;
|
||||||
|
+ (*pos)++;
|
||||||
|
+
|
||||||
|
+ return next_profile(root, profile);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * p_stop - stop depth first traversal
|
||||||
|
+ * @f: seq_file we are filling
|
||||||
|
+ * @p: the last profile writen
|
||||||
|
+ *
|
||||||
|
+ * Release all locking done by p_start/p_next on namespace tree
|
||||||
|
+ */
|
||||||
|
+static void p_stop(struct seq_file *f, void *p)
|
||||||
|
+ __releases(root->lock)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = p;
|
||||||
|
+ struct aa_namespace *root = f->private, *ns;
|
||||||
|
+
|
||||||
|
+ if (profile) {
|
||||||
|
+ for (ns = profile->ns; ns && ns != root; ns = ns->parent)
|
||||||
|
+ read_unlock(&ns->lock);
|
||||||
|
+ }
|
||||||
|
+ read_unlock(&root->lock);
|
||||||
|
+ aa_put_namespace(root);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * seq_show_profile - show a profile entry
|
||||||
|
+ * @f: seq_file to file
|
||||||
|
+ * @p: current position (profile) (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: error on failure
|
||||||
|
+ */
|
||||||
|
+static int seq_show_profile(struct seq_file *f, void *p)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = (struct aa_profile *)p;
|
||||||
|
+ struct aa_namespace *root = f->private;
|
||||||
|
+
|
||||||
|
+ if (profile->ns != root)
|
||||||
|
+ seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
|
||||||
|
+ seq_printf(f, "%s (%s)\n", profile->base.hname,
|
||||||
|
+ COMPLAIN_MODE(profile) ? "complain" : "enforce");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct seq_operations aa_fs_profiles_op = {
|
||||||
|
+ .start = p_start,
|
||||||
|
+ .next = p_next,
|
||||||
|
+ .stop = p_stop,
|
||||||
|
+ .show = seq_show_profile,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int profiles_open(struct inode *inode, struct file *file)
|
||||||
|
+{
|
||||||
|
+ return seq_open(file, &aa_fs_profiles_op);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int profiles_release(struct inode *inode, struct file *file)
|
||||||
|
+{
|
||||||
|
+ return seq_release(inode, file);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct file_operations aa_fs_profiles_fops = {
|
||||||
|
+ .open = profiles_open,
|
||||||
|
+ .read = seq_read,
|
||||||
|
+ .llseek = seq_lseek,
|
||||||
|
+ .release = profiles_release,
|
||||||
|
+};
|
||||||
|
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||||
|
index 0848292..28c52ac 100644
|
||||||
|
--- a/security/apparmor/apparmorfs.c
|
||||||
|
+++ b/security/apparmor/apparmorfs.c
|
||||||
|
@@ -187,7 +187,11 @@ void __init aa_destroy_aafs(void)
|
||||||
|
aafs_remove(".remove");
|
||||||
|
aafs_remove(".replace");
|
||||||
|
aafs_remove(".load");
|
||||||
|
-
|
||||||
|
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ aafs_remove("profiles");
|
||||||
|
+ aafs_remove("matching");
|
||||||
|
+ aafs_remove("features");
|
||||||
|
+#endif
|
||||||
|
securityfs_remove(aa_fs_dentry);
|
||||||
|
aa_fs_dentry = NULL;
|
||||||
|
}
|
||||||
|
@@ -218,7 +222,17 @@ int __init aa_create_aafs(void)
|
||||||
|
aa_fs_dentry = NULL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ error = aafs_create("matching", 0444, &aa_fs_matching_fops);
|
||||||
|
+ if (error)
|
||||||
|
+ goto error;
|
||||||
|
+ error = aafs_create("features", 0444, &aa_fs_features_fops);
|
||||||
|
+ if (error)
|
||||||
|
+ goto error;
|
||||||
|
+#endif
|
||||||
|
+ error = aafs_create("profiles", 0440, &aa_fs_profiles_fops);
|
||||||
|
+ if (error)
|
||||||
|
+ goto error;
|
||||||
|
error = aafs_create(".load", 0640, &aa_fs_profile_load);
|
||||||
|
if (error)
|
||||||
|
goto error;
|
||||||
|
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
|
||||||
|
index cb1e93a..14f955c 100644
|
||||||
|
--- a/security/apparmor/include/apparmorfs.h
|
||||||
|
+++ b/security/apparmor/include/apparmorfs.h
|
||||||
|
@@ -17,4 +17,10 @@
|
||||||
|
|
||||||
|
extern void __init aa_destroy_aafs(void);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+extern const struct file_operations aa_fs_matching_fops;
|
||||||
|
+extern const struct file_operations aa_fs_features_fops;
|
||||||
|
+extern const struct file_operations aa_fs_profiles_fops;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#endif /* __AA_APPARMORFS_H */
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From 9396d61706a827dfc4dcdfdc8f687e0e9e24f53d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Arianna Avanzini <avanzini.arianna@gmail.com>
|
||||||
|
Date: Mon, 19 Dec 2011 16:34:01 +0100
|
||||||
|
Subject: [PATCH 2/3] block: cgroups, kconfig, build bits for BFQ-v5-3.2
|
||||||
|
|
||||||
|
Add a Kconfig option and do the related Makefile changes to compile
|
||||||
|
the BFQ I/O scheduler. Also let the cgroups subsystem know about the
|
||||||
|
BFQ I/O controller.
|
||||||
|
|
||||||
|
Signed-off-by: Fabio Checconi <fabio@gandalf.sssup.it>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
|
||||||
|
Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
|
||||||
|
---
|
||||||
|
block/Makefile | 1 +
|
||||||
|
include/linux/cgroup_subsys.h | 6 ++++++
|
||||||
|
2 files changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/block/Makefile b/block/Makefile
|
||||||
|
index 514c6e4..653d27b 100644
|
||||||
|
--- a/block/Makefile
|
||||||
|
+++ b/block/Makefile
|
||||||
|
@@ -14,6 +14,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o
|
||||||
|
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
|
||||||
|
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
|
||||||
|
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
|
||||||
|
+obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
|
||||||
|
obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
|
||||||
|
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
|
||||||
|
index ac663c1..c966638 100644
|
||||||
|
--- a/include/linux/cgroup_subsys.h
|
||||||
|
+++ b/include/linux/cgroup_subsys.h
|
||||||
|
@@ -64,3 +64,9 @@ SUBSYS(perf)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_CGROUP_BFQIO
|
||||||
|
+SUBSYS(bfqio)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* */
|
||||||
|
--
|
||||||
|
1.7.10.4
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
From 7a10d093f9779f42cb8d6affcb6a4436d3ebd6d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
|
Date: Wed, 10 Aug 2011 22:02:41 -0700
|
||||||
|
Subject: [PATCH 3/3] AppArmor: Allow dfa backward compatibility with broken
|
||||||
|
userspace
|
||||||
|
|
||||||
|
The apparmor_parser when compiling policy could generate invalid dfas
|
||||||
|
that did not have sufficient padding to avoid invalid references, when
|
||||||
|
used by the kernel. The kernels check to verify the next/check table
|
||||||
|
size was broken meaning invalid dfas were being created by userspace
|
||||||
|
and not caught.
|
||||||
|
|
||||||
|
To remain compatible with old tools that are not fixed, pad the loaded
|
||||||
|
dfas next/check table. The dfa's themselves are valid except for the
|
||||||
|
high padding for potentially invalid transitions (high bounds error),
|
||||||
|
which have a maximimum is 256 entries. So just allocate an extra null filled
|
||||||
|
256 entries for the next/check tables. This will guarentee all bounds
|
||||||
|
are good and invalid transitions go to the null (0) state.
|
||||||
|
|
||||||
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
---
|
||||||
|
security/apparmor/match.c | 17 +++++++++++++++++
|
||||||
|
1 files changed, 17 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||||
|
index 94de6b4..081491e 100644
|
||||||
|
--- a/security/apparmor/match.c
|
||||||
|
+++ b/security/apparmor/match.c
|
||||||
|
@@ -57,8 +57,17 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||||
|
if (bsize < tsize)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
+ /* Pad table allocation for next/check by 256 entries to remain
|
||||||
|
+ * backwards compatible with old (buggy) tools and remain safe without
|
||||||
|
+ * run time checks
|
||||||
|
+ */
|
||||||
|
+ if (th.td_id == YYTD_ID_NXT || th.td_id == YYTD_ID_CHK)
|
||||||
|
+ tsize += 256 * th.td_flags;
|
||||||
|
+
|
||||||
|
table = kvmalloc(tsize);
|
||||||
|
if (table) {
|
||||||
|
+ /* ensure the pad is clear, else there will be errors */
|
||||||
|
+ memset(table, 0, tsize);
|
||||||
|
*table = th;
|
||||||
|
if (th.td_flags == YYTD_DATA8)
|
||||||
|
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
|
||||||
|
@@ -134,11 +143,19 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (flags & DFA_FLAG_VERIFY_STATES) {
|
||||||
|
+ int warning = 0;
|
||||||
|
for (i = 0; i < state_count; i++) {
|
||||||
|
if (DEFAULT_TABLE(dfa)[i] >= state_count)
|
||||||
|
goto out;
|
||||||
|
/* TODO: do check that DEF state recursion terminates */
|
||||||
|
if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
|
||||||
|
+ if (warning)
|
||||||
|
+ continue;
|
||||||
|
+ printk(KERN_WARNING "AppArmor DFA next/check "
|
||||||
|
+ "upper bounds error fixed, upgrade "
|
||||||
|
+ "user space tools \n");
|
||||||
|
+ warning = 1;
|
||||||
|
+ } else if (BASE_TABLE(dfa)[i] >= trans_count) {
|
||||||
|
printk(KERN_ERR "AppArmor DFA next/check upper "
|
||||||
|
"bounds error\n");
|
||||||
|
goto out;
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
5986
3.2.34/0003-block-introduce-the-BFQ-v5-I-O-sched-for-3.2.patch
Normal file
5986
3.2.34/0003-block-introduce-the-BFQ-v5-I-O-sched-for-3.2.patch
Normal file
File diff suppressed because it is too large
Load Diff
174
3.2.34/01patch-2.6.33_atopcnt.patch
Normal file
174
3.2.34/01patch-2.6.33_atopcnt.patch
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
diff --git a/block/blk-core.c b/block/blk-core.c
|
||||||
|
index d1a9a0a..8b54acb 100644
|
||||||
|
--- a/block/blk-core.c
|
||||||
|
+++ b/block/blk-core.c
|
||||||
|
@@ -73,6 +73,17 @@ static void drive_stat_acct(struct request *rq, int new_io)
|
||||||
|
part_inc_in_flight(part, rw);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ switch (rw) { /* ATOP */
|
||||||
|
+ case READ: /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_rio += new_io; /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_rsz += blk_rq_sectors(rq); /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case WRITE: /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_wio += new_io; /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_wsz += blk_rq_sectors(rq); /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+
|
||||||
|
part_stat_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/fs/proc/array.c b/fs/proc/array.c
|
||||||
|
index 13b5d07..cac522e 100644
|
||||||
|
--- a/fs/proc/array.c
|
||||||
|
+++ b/fs/proc/array.c
|
||||||
|
@@ -515,6 +515,25 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
|
||||||
|
(unsigned long long)delayacct_blkio_ticks(task),
|
||||||
|
cputime_to_clock_t(gtime),
|
||||||
|
cputime_to_clock_t(cgtime));
|
||||||
|
+
|
||||||
|
+ seq_printf(m, /* ATOP */
|
||||||
|
+ "%lu %llu %lu %llu %lu %llu %lu " /* ATOP */
|
||||||
|
+ "%llu %lu %llu %lu %llu %lu %lu\n", /* ATOP */
|
||||||
|
+ task->stat.dsk_rio, /* ATOP */
|
||||||
|
+ task->stat.dsk_rsz, /* ATOP */
|
||||||
|
+ task->stat.dsk_wio, /* ATOP */
|
||||||
|
+ task->stat.dsk_wsz, /* ATOP */
|
||||||
|
+ task->stat.tcp_snd, /* ATOP */
|
||||||
|
+ task->stat.tcp_ssz, /* ATOP */
|
||||||
|
+ task->stat.tcp_rcv, /* ATOP */
|
||||||
|
+ task->stat.tcp_rsz, /* ATOP */
|
||||||
|
+ task->stat.udp_snd, /* ATOP */
|
||||||
|
+ task->stat.udp_ssz, /* ATOP */
|
||||||
|
+ task->stat.udp_rcv, /* ATOP */
|
||||||
|
+ task->stat.udp_rsz, /* ATOP */
|
||||||
|
+ task->stat.raw_snd, /* ATOP */
|
||||||
|
+ task->stat.raw_rcv); /* ATOP */
|
||||||
|
+
|
||||||
|
if (mm)
|
||||||
|
mmput(mm);
|
||||||
|
return 0;
|
||||||
|
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||||
|
index 78efe7c..22391bf 100644
|
||||||
|
--- a/include/linux/sched.h
|
||||||
|
+++ b/include/linux/sched.h
|
||||||
|
@@ -1512,6 +1512,17 @@ struct task_struct {
|
||||||
|
#endif
|
||||||
|
atomic_t fs_excl; /* holding fs exclusive resources */
|
||||||
|
struct rcu_head rcu;
|
||||||
|
+
|
||||||
|
+ struct { /* ATOP */
|
||||||
|
+ unsigned long dsk_rio, dsk_wio; /* ATOP */
|
||||||
|
+ unsigned long long dsk_rsz, dsk_wsz; /* ATOP */
|
||||||
|
+ unsigned long tcp_snd, tcp_rcv; /* ATOP */
|
||||||
|
+ unsigned long long tcp_ssz, tcp_rsz; /* ATOP */
|
||||||
|
+ unsigned long udp_snd, udp_rcv; /* ATOP */
|
||||||
|
+ unsigned long long udp_ssz, udp_rsz; /* ATOP */
|
||||||
|
+ unsigned long raw_snd, raw_rcv; /* ATOP */
|
||||||
|
+ } stat; /* ATOP */
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cache last used pipe for splice
|
||||||
|
diff --git a/kernel/acct.c b/kernel/acct.c
|
||||||
|
index a6605ca..d5df53a 100644
|
||||||
|
--- a/kernel/acct.c
|
||||||
|
+++ b/kernel/acct.c
|
||||||
|
@@ -565,7 +565,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
|
||||||
|
ac.ac_exitcode = pacct->ac_exitcode;
|
||||||
|
spin_unlock_irq(¤t->sighand->siglock);
|
||||||
|
ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
|
||||||
|
- ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
|
||||||
|
+ ac.ac_rw = encode_comp_t(current->stat.dsk_rio + current->stat.dsk_wio); /* ATOP */
|
||||||
|
ac.ac_swaps = encode_comp_t(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||||
|
index f88bd98..bab2085 100644
|
||||||
|
--- a/kernel/fork.c
|
||||||
|
+++ b/kernel/fork.c
|
||||||
|
@@ -683,6 +683,14 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
|
||||||
|
|
||||||
|
tsk->min_flt = tsk->maj_flt = 0;
|
||||||
|
tsk->nvcsw = tsk->nivcsw = 0;
|
||||||
|
+ tsk->stat.dsk_rio = tsk->stat.dsk_wio = 0; /* ATOP */
|
||||||
|
+ tsk->stat.dsk_rsz = tsk->stat.dsk_wsz = 0; /* ATOP */
|
||||||
|
+ tsk->stat.tcp_snd = tsk->stat.tcp_rcv = 0; /* ATOP */
|
||||||
|
+ tsk->stat.tcp_ssz = tsk->stat.tcp_rsz = 0; /* ATOP */
|
||||||
|
+ tsk->stat.udp_snd = tsk->stat.udp_rcv = 0; /* ATOP */
|
||||||
|
+ tsk->stat.udp_ssz = tsk->stat.udp_rsz = 0; /* ATOP */
|
||||||
|
+ tsk->stat.raw_snd = tsk->stat.raw_rcv = 0; /* ATOP */
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_DETECT_HUNG_TASK
|
||||||
|
tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
|
||||||
|
#endif
|
||||||
|
diff --git a/net/socket.c b/net/socket.c
|
||||||
|
index 769c386..3ba19f6 100644
|
||||||
|
--- a/net/socket.c
|
||||||
|
+++ b/net/socket.c
|
||||||
|
@@ -547,10 +547,28 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
|
si->size = size;
|
||||||
|
|
||||||
|
err = security_socket_sendmsg(sock, msg, size);
|
||||||
|
- if (err)
|
||||||
|
- return err;
|
||||||
|
-
|
||||||
|
- return sock->ops->sendmsg(iocb, sock, msg, size);
|
||||||
|
+ if (!err)
|
||||||
|
+ err = sock->ops->sendmsg(iocb, sock, msg, size);
|
||||||
|
+
|
||||||
|
+ if (err >= 0 && sock->sk) { /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_family) { /* ATOP */
|
||||||
|
+ case PF_INET: /* ATOP */
|
||||||
|
+ case PF_INET6: /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_type) { /* ATOP */
|
||||||
|
+ case SOCK_STREAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_snd++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_ssz+=size;/* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_DGRAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_snd++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_ssz+=size;/* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_RAW: /* ATOP */
|
||||||
|
+ current->group_leader->stat.raw_snd++; /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
|
||||||
|
@@ -682,7 +700,29 @@ static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
|
{
|
||||||
|
int err = security_socket_recvmsg(sock, msg, size, flags);
|
||||||
|
|
||||||
|
- return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
|
||||||
|
+ if (!err)
|
||||||
|
+ err = __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
|
||||||
|
+
|
||||||
|
+ if (err >= 0 && sock->sk) { /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_family) { /* ATOP */
|
||||||
|
+ case PF_INET: /* ATOP */
|
||||||
|
+ case PF_INET6: /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_type) { /* ATOP */
|
||||||
|
+ case SOCK_STREAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_rcv++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_rsz+=err; /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_DGRAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_rcv++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_rsz+=err; /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_RAW: /* ATOP */
|
||||||
|
+ current->group_leader->stat.raw_rcv++; /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
125
3.2.34/02patch-2.6.33_atopacct.patch
Normal file
125
3.2.34/02patch-2.6.33_atopacct.patch
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
Index: linux-2.6.28/include/linux/acct.h
|
||||||
|
===================================================================
|
||||||
|
--- linux-2.6.28.orig/include/linux/acct.h 2009-01-14 13:02:24.000000000 +0100
|
||||||
|
+++ linux-2.6.28/include/linux/acct.h 2009-01-14 13:03:33.000000000 +0100
|
||||||
|
@@ -97,6 +97,54 @@
|
||||||
|
char ac_comm[ACCT_COMM]; /* Command Name */
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct acct_atop
|
||||||
|
+{
|
||||||
|
+ char ac_flag; /* Flags */
|
||||||
|
+ char ac_version; /* Always set to ACCT_VERSION */
|
||||||
|
+ __u32 ac_pid; /* Process ID */
|
||||||
|
+ __u32 ac_ppid; /* Parent Process ID */
|
||||||
|
+ __u16 ac_uid16; /* LSB of Real User ID */
|
||||||
|
+ __u16 ac_gid16; /* LSB of Real Group ID */
|
||||||
|
+ __u16 ac_tty; /* Control Terminal */
|
||||||
|
+ __u32 ac_btime; /* Process Creation Time */
|
||||||
|
+ comp_t ac_utime; /* User Time */
|
||||||
|
+ comp_t ac_stime; /* System Time */
|
||||||
|
+ comp_t ac_etime; /* Elapsed Time */
|
||||||
|
+ comp_t ac_mem; /* Virtual Memory */
|
||||||
|
+ comp_t ac_rss; /* Resident Memory */
|
||||||
|
+ comp_t ac_io; /* Chars Transferred */
|
||||||
|
+ comp_t ac_rw; /* Blocks Read or Written */
|
||||||
|
+ comp_t ac_bread; /* Blocks Read */
|
||||||
|
+ comp_t ac_bwrite; /* Blocks Written */
|
||||||
|
+ comp2_t ac_dskrsz; /* Cum. blocks read */
|
||||||
|
+ comp2_t ac_dskwsz; /* Cum. blocks written */
|
||||||
|
+ comp_t ac_tcpsnd; /* TCP send requests */
|
||||||
|
+ comp_t ac_tcprcv; /* TCP recv requests */
|
||||||
|
+ comp2_t ac_tcpssz; /* TCP cum. length */
|
||||||
|
+ comp2_t ac_tcprsz; /* TCP cum. length */
|
||||||
|
+ comp_t ac_udpsnd; /* UDP send requests */
|
||||||
|
+ comp_t ac_udprcv; /* UDP recv requests */
|
||||||
|
+ comp2_t ac_udpssz; /* UDP cum. length */
|
||||||
|
+ comp2_t ac_udprsz; /* UDP cum. length */
|
||||||
|
+ comp_t ac_rawsnd; /* RAW send requests */
|
||||||
|
+ comp_t ac_rawrcv; /* RAW recv requests */
|
||||||
|
+ comp_t ac_minflt; /* Minor Pagefaults */
|
||||||
|
+ comp_t ac_majflt; /* Major Pagefaults */
|
||||||
|
+ comp_t ac_swaps; /* Number of Swaps */
|
||||||
|
+/* m68k had no padding here. */
|
||||||
|
+#if !defined(CONFIG_M68K) || !defined(__KERNEL__)
|
||||||
|
+ __u16 ac_ahz; /* AHZ */
|
||||||
|
+#endif
|
||||||
|
+ __u32 ac_exitcode; /* Exitcode */
|
||||||
|
+ char ac_comm[ACCT_COMM + 1]; /* Command Name */
|
||||||
|
+ __u8 ac_etime_hi; /* Elapsed Time MSB */
|
||||||
|
+ __u16 ac_etime_lo; /* Elapsed Time LSB */
|
||||||
|
+ __u32 ac_uid; /* Real User ID */
|
||||||
|
+ __u32 ac_gid; /* Real Group ID */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* accounting flags
|
||||||
|
*/
|
||||||
|
@@ -146,7 +194,13 @@
|
||||||
|
* 5: new binary incompatible format (128 bytes, second half)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
+#define CONFIG_PROCESS_ACCT_ATOP
|
||||||
|
|
||||||
|
+#ifdef CONFIG_PROCESS_ACCT_ATOP
|
||||||
|
+#define ACCT_VERSION 6
|
||||||
|
+#define AHZ (USER_HZ)
|
||||||
|
+typedef struct acct_atop acct_t;
|
||||||
|
+#else
|
||||||
|
#ifdef CONFIG_BSD_PROCESS_ACCT_V3
|
||||||
|
#define ACCT_VERSION 3
|
||||||
|
#define AHZ 100
|
||||||
|
@@ -160,6 +214,7 @@
|
||||||
|
#define AHZ (USER_HZ)
|
||||||
|
typedef struct acct acct_t;
|
||||||
|
#endif
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define ACCT_VERSION 2
|
||||||
|
Index: linux-2.6.28/kernel/acct.c
|
||||||
|
===================================================================
|
||||||
|
--- linux-2.6.28.orig/kernel/acct.c 2009-01-14 13:03:31.000000000 +0100
|
||||||
|
+++ linux-2.6.28/kernel/acct.c 2009-01-14 13:03:33.000000000 +0100
|
||||||
|
@@ -405,7 +405,7 @@
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if ACCT_VERSION==1 || ACCT_VERSION==2
|
||||||
|
+#if ACCT_VERSION==1 || ACCT_VERSION==2 || ACCT_VERSION==6
|
||||||
|
/*
|
||||||
|
* encode an u64 into a comp2_t (24 bits)
|
||||||
|
*
|
||||||
|
@@ -552,6 +552,30 @@
|
||||||
|
ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns);
|
||||||
|
rcu_read_unlock();
|
||||||
|
#endif
|
||||||
|
+#if ACCT_VERSION==6 /* ATOP */
|
||||||
|
+ ac.ac_pid = current->pid;
|
||||||
|
+ ac.ac_ppid = current->parent->pid;
|
||||||
|
+ ac.ac_uid16 = ac.ac_uid;
|
||||||
|
+ ac.ac_gid16 = ac.ac_gid;
|
||||||
|
+ ac.ac_ahz = AHZ;
|
||||||
|
+ ac.ac_bread = encode_comp_t(current->stat.dsk_rio);
|
||||||
|
+ ac.ac_bwrite = encode_comp_t(current->stat.dsk_wio);
|
||||||
|
+ ac.ac_dskrsz = encode_comp2_t(current->stat.dsk_rsz);
|
||||||
|
+ ac.ac_dskwsz = encode_comp2_t(current->stat.dsk_wsz);
|
||||||
|
+ ac.ac_tcpsnd = encode_comp_t(current->stat.tcp_snd);
|
||||||
|
+ ac.ac_tcprcv = encode_comp_t(current->stat.tcp_rcv);
|
||||||
|
+ ac.ac_tcpssz = encode_comp2_t(current->stat.tcp_ssz);
|
||||||
|
+ ac.ac_tcprsz = encode_comp2_t(current->stat.tcp_rsz);
|
||||||
|
+ ac.ac_udpsnd = encode_comp_t(current->stat.udp_snd);
|
||||||
|
+ ac.ac_udprcv = encode_comp_t(current->stat.udp_rcv);
|
||||||
|
+ ac.ac_udpssz = encode_comp2_t(current->stat.udp_ssz);
|
||||||
|
+ ac.ac_udprsz = encode_comp2_t(current->stat.udp_rsz);
|
||||||
|
+ ac.ac_rawsnd = encode_comp_t(current->stat.raw_snd);
|
||||||
|
+ ac.ac_rawrcv = encode_comp_t(current->stat.raw_rcv);
|
||||||
|
+ ac.ac_rss = current->mm ?
|
||||||
|
+ encode_comp_t(get_mm_rss(current->mm)<<(PAGE_SHIFT-10)) :
|
||||||
|
+ encode_comp_t(0);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
spin_lock_irq(¤t->sighand->siglock);
|
||||||
|
tty = current->signal->tty; /* Safe as we hold the siglock */
|
9093
3.2.34/3.2.0-ck1.patch
Normal file
9093
3.2.34/3.2.0-ck1.patch
Normal file
File diff suppressed because it is too large
Load Diff
181
3.2.34/3rd-3rdparty-1.0-tree.patch
Normal file
181
3.2.34/3rd-3rdparty-1.0-tree.patch
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
|
||||||
|
3rdparty/mkbuild.pl | 92 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
Documentation/3rdparty.txt | 76 +++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 168 insertions(+)
|
||||||
|
|
||||||
|
diff -Nurp linux-2.6.37/3rdparty/mkbuild.pl 3rdparty/mkbuild.pl
|
||||||
|
--- linux-2.6.37/3rdparty/mkbuild.pl 1970-01-01 02:00:00.000000000 +0200
|
||||||
|
+++ 3rdparty/mkbuild.pl 2004-04-23 14:59:03.000000000 +0300
|
||||||
|
@@ -0,0 +1,92 @@
|
||||||
|
+#!/usr/bin/perl -w
|
||||||
|
+#
|
||||||
|
+# Version 1.0
|
||||||
|
+#
|
||||||
|
+# Copyright 2001 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||||
|
+# Copyright 2002 Juan Quintela <quintela@mandrakesoft.com>
|
||||||
|
+# Copyright 2003 Nicolas Planel <nplanel@mandrakesoft.com>
|
||||||
|
+#
|
||||||
|
+# This software may be used and distributed according to the terms
|
||||||
|
+# of the GNU General Public License, incorporated herein by reference.
|
||||||
|
+#
|
||||||
|
+#
|
||||||
|
+# Run "mkbuild.pl"
|
||||||
|
+#
|
||||||
|
+# This program generates the following files
|
||||||
|
+# Makefile
|
||||||
|
+# Makefile.drivers
|
||||||
|
+# Config.in
|
||||||
|
+# using the information in the subdirs of this directory.
|
||||||
|
+#
|
||||||
|
+# subdirs need to have:
|
||||||
|
+# a Config.in file
|
||||||
|
+# a Makefile with a O_TARGET/L_TARGET targets
|
||||||
|
+# The config.in should set a CONFIG_<module_dir_name> to m/y.
|
||||||
|
+
|
||||||
|
+use strict;
|
||||||
|
+
|
||||||
|
+opendir(THISDIR, ".");
|
||||||
|
+# get dirs without . and .. garbage
|
||||||
|
+my (@modules) = grep(!/\.\.?$/,grep(-d, readdir(THISDIR)));
|
||||||
|
+closedir(THISDIR);
|
||||||
|
+
|
||||||
|
+generate_kconfig(@modules);
|
||||||
|
+generate_makefile(@modules);
|
||||||
|
+exit(0);
|
||||||
|
+
|
||||||
|
+##########################################################################
|
||||||
|
+
|
||||||
|
+sub generate_makefile {
|
||||||
|
+ my (@modules) = @_;
|
||||||
|
+
|
||||||
|
+ local *F;
|
||||||
|
+ open F, "> Makefile" or die "Cannot create new Makefile: $!\n";
|
||||||
|
+ print F <<'EOM';
|
||||||
|
+#
|
||||||
|
+# THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+EOM
|
||||||
|
+ printf F "obj- := 3rdparty.o # Dummy rule to force built-in.o to be made\n";
|
||||||
|
+ printf F "obj-\$(%s) += %s\n", to_CONFIG($_), $_ . '/' foreach @modules;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+sub generate_kconfig {
|
||||||
|
+ my (@modules) = @_;
|
||||||
|
+
|
||||||
|
+ local *F;
|
||||||
|
+ open F, "> Kconfig" or die "Cannot create Kconfig: $!\n";
|
||||||
|
+ print F <<"EOM";
|
||||||
|
+#
|
||||||
|
+# THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+menu "Unofficial 3rd party kernel additions"
|
||||||
|
+
|
||||||
|
+EOM
|
||||||
|
+
|
||||||
|
+ foreach (@modules) {
|
||||||
|
+ die "No Kconfig in $_.\n" if ! -r "$_/Kconfig";
|
||||||
|
+ print F "source 3rdparty/$_/Kconfig\n";
|
||||||
|
+ }
|
||||||
|
+ print F "\n\nendmenu\n";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+sub to_CONFIG {
|
||||||
|
+ local $_ = $_[0];
|
||||||
|
+ tr/a-z/A-Z/;
|
||||||
|
+ s/[\-\. ]/_/g;
|
||||||
|
+ "CONFIG_$_";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+sub find_target {
|
||||||
|
+ my ($module_dir) = @_;
|
||||||
|
+
|
||||||
|
+ local *F;
|
||||||
|
+ open(F, "$module_dir/Makefile") or die "$module_dir/Makefile: $!\n";
|
||||||
|
+ while (<F>) {
|
||||||
|
+ chomp;
|
||||||
|
+ return $1 if (/[LO]_TARGET.*:=\s+(\S+)/);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff -Nurp linux-2.6.37/Documentation/3rdparty.txt Documentation/3rdparty.txt
|
||||||
|
--- linux-2.6.37/Documentation/3rdparty.txt 1970-01-01 02:00:00.000000000 +0200
|
||||||
|
+++ Documentation/3rdparty.txt 2003-11-22 01:07:26.000000000 +0200
|
||||||
|
@@ -0,0 +1,76 @@
|
||||||
|
+
|
||||||
|
+Third-Party Kernel Source Module Support, or
|
||||||
|
+an easy way to add modules to your kernel build.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Vendors quite often add additional drivers and features to the kernel
|
||||||
|
+which require nothing more than modifying Kconfig, Makefile, and
|
||||||
|
+adding one or more files to a sub-directory. As a single discrete task,
|
||||||
|
+this is not a problem. However, using patches to add modules to the
|
||||||
|
+kernel very often results in patch conflicts, resulting in needless time
|
||||||
|
+wastage as developers regenerate an otherwise working kernel patch.
|
||||||
|
+
|
||||||
|
+This is designed as a solution to these problems. It is NOT designed as
|
||||||
|
+a replacement for the kernel build system, but merely as a tool for
|
||||||
|
+vendors and system administrators to ease the pain of patch management.
|
||||||
|
+
|
||||||
|
+The key feature of this system is the distinct lack of patches. Drivers
|
||||||
|
+are installed via unpacking a tarball.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Adding a directory to the build (usually from a tarball)
|
||||||
|
+--------------------------------------------------------
|
||||||
|
+If a directory exists inside the 3rdparty sub-directory that contains a
|
||||||
|
+proper Makefile, it can be added to the build. It also needs a
|
||||||
|
+Kconfig file.
|
||||||
|
+
|
||||||
|
+ cd /usr/src/linux-2.4.3/3rdparty
|
||||||
|
+ bzcat /tmp/my-driver2.tar.bz2 | tar xf - # creates "my2" dir
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Limitations
|
||||||
|
+-----------
|
||||||
|
+There are some limitations to this system. This system is only
|
||||||
|
+designed to support a very common case. If you find yourself running
|
||||||
|
+into limitations (kernel build experts can spot them right off),
|
||||||
|
+then you should probably be patching the kernel instead of using
|
||||||
|
+mkbuild.pl for that particular module.
|
||||||
|
+
|
||||||
|
+FIXME: actually list the limitations
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Other notes
|
||||||
|
+-----------
|
||||||
|
+Link order is controlled by the order of mkbuild.pl executions.
|
||||||
|
+
|
||||||
|
+"make mrproper" will erase Makefile.meta, and empty Kconfig, Makefile,
|
||||||
|
+and Makefile.drivers.
|
||||||
|
+
|
||||||
|
+IMPORTANT NOTE: Because this feature modifies the kernel's makefiles and
|
||||||
|
+configuration system, you MUST complete all mkbuild.pl runs before
|
||||||
|
+running any "make" command.
|
||||||
|
+
|
||||||
|
+Building in the 3rdparty dir
|
||||||
|
+----------------------------
|
||||||
|
+
|
||||||
|
+If you use modules that:
|
||||||
|
+ - are contained in one subdir with the name of the module
|
||||||
|
+ - has a Makefile
|
||||||
|
+ - has a Kconfig file
|
||||||
|
+
|
||||||
|
+The system calls the ./mkbuild.pl script. It will search for
|
||||||
|
+subdirectories, and will try to build each of them as a module.
|
||||||
|
+Things to note:
|
||||||
|
+
|
||||||
|
+ The dependencies will be done in a module called:
|
||||||
|
+
|
||||||
|
+ 3rdparty/<module_dir_name>/<module_name>
|
||||||
|
+
|
||||||
|
+depending of CONFIG_<module_name_in_uppercase>.
|
||||||
|
+
|
||||||
|
+<module_name> is the value of O_TARGET/L_TARGET.
|
||||||
|
+
|
||||||
|
+
|
372
3.2.34/3rd-3rdparty-button_hotplug-0.4.1.patch
Normal file
372
3.2.34/3rd-3rdparty-button_hotplug-0.4.1.patch
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
Submitted By: Mario Fetka (mario dot fetka at gmail dot com)
|
||||||
|
Date: 2012-11-18
|
||||||
|
Initial Package Version: 3.2.33
|
||||||
|
Origin: openwtr.org packages/system/button-hotplug
|
||||||
|
Upstream Status: unknown
|
||||||
|
Description: create uevents from button usage
|
||||||
|
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/button_hotplug/Kconfig 3rdparty/button_hotplug/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/button_hotplug/Kconfig 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/button_hotplug/Kconfig 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+config BUTTON_HOTPLUG
|
||||||
|
+ tristate "Button Hotplug driver"
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/button_hotplug/Makefile 3rdparty/button_hotplug/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/button_hotplug/Makefile 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/button_hotplug/Makefile 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+obj-${CONFIG_BUTTON_HOTPLUG} += button-hotplug.o
|
||||||
|
\ No newline at end of file
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/button_hotplug/button-hotplug.c 3rdparty/button_hotplug/button-hotplug.c
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/button_hotplug/button-hotplug.c 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/button_hotplug/button-hotplug.c 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1,349 @@
|
||||||
|
+/*
|
||||||
|
+ * Button Hotplug driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * Based on the diag.c - GPIO interface driver for Broadcom boards
|
||||||
|
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
|
||||||
|
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
+ * Copyright (C) 2008 Andy Boyett <agb@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/module.h>
|
||||||
|
+#include <linux/version.h>
|
||||||
|
+#include <linux/kmod.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+
|
||||||
|
+#include <linux/workqueue.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/netlink.h>
|
||||||
|
+#include <linux/kobject.h>
|
||||||
|
+
|
||||||
|
+#define DRV_NAME "button-hotplug"
|
||||||
|
+#define DRV_VERSION "0.4.1"
|
||||||
|
+#define DRV_DESC "Button Hotplug driver"
|
||||||
|
+
|
||||||
|
+#define BH_SKB_SIZE 2048
|
||||||
|
+
|
||||||
|
+#define PFX DRV_NAME ": "
|
||||||
|
+
|
||||||
|
+#undef BH_DEBUG
|
||||||
|
+
|
||||||
|
+#ifdef BH_DEBUG
|
||||||
|
+#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+#else
|
||||||
|
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+
|
||||||
|
+#ifndef BIT_MASK
|
||||||
|
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+struct bh_priv {
|
||||||
|
+ unsigned long *seen;
|
||||||
|
+ struct input_handle handle;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_event {
|
||||||
|
+ const char *name;
|
||||||
|
+ char *action;
|
||||||
|
+ unsigned long seen;
|
||||||
|
+
|
||||||
|
+ struct sk_buff *skb;
|
||||||
|
+ struct work_struct work;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_map {
|
||||||
|
+ unsigned int code;
|
||||||
|
+ const char *name;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern u64 uevent_next_seqnum(void);
|
||||||
|
+
|
||||||
|
+#define BH_MAP(_code, _name) \
|
||||||
|
+ { \
|
||||||
|
+ .code = (_code), \
|
||||||
|
+ .name = (_name), \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+static struct bh_map button_map[] = {
|
||||||
|
+ BH_MAP(BTN_0, "BTN_0"),
|
||||||
|
+ BH_MAP(BTN_1, "BTN_1"),
|
||||||
|
+ BH_MAP(BTN_2, "BTN_2"),
|
||||||
|
+ BH_MAP(BTN_3, "BTN_3"),
|
||||||
|
+ BH_MAP(BTN_4, "BTN_4"),
|
||||||
|
+ BH_MAP(BTN_5, "BTN_5"),
|
||||||
|
+ BH_MAP(BTN_6, "BTN_6"),
|
||||||
|
+ BH_MAP(BTN_7, "BTN_7"),
|
||||||
|
+ BH_MAP(BTN_8, "BTN_8"),
|
||||||
|
+ BH_MAP(BTN_9, "BTN_9"),
|
||||||
|
+ BH_MAP(KEY_RESTART, "reset"),
|
||||||
|
+#ifdef KEY_WPS_BUTTON
|
||||||
|
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
|
||||||
|
+#endif /* KEY_WPS_BUTTON */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||||
|
+ const char *format, ...)
|
||||||
|
+{
|
||||||
|
+ static char buf[128];
|
||||||
|
+ char *s;
|
||||||
|
+ va_list args;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ if (argv)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ va_start(args, format);
|
||||||
|
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||||
|
+ va_end(args);
|
||||||
|
+
|
||||||
|
+ if (len >= sizeof(buf)) {
|
||||||
|
+ BH_ERR("buffer size too small\n");
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = skb_put(event->skb, len + 1);
|
||||||
|
+ strcpy(s, buf);
|
||||||
|
+
|
||||||
|
+ BH_DBG("added variable '%s'\n", s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_fill_event(struct bh_event *event)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||||
|
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void button_hotplug_work(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||||
|
+ if (!event->skb)
|
||||||
|
+ goto out_free_event;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "%s@", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ ret = button_hotplug_fill_event(event);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||||
|
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ out_free_skb:
|
||||||
|
+ if (ret) {
|
||||||
|
+ BH_ERR("work error %d\n", ret);
|
||||||
|
+ kfree_skb(event->skb);
|
||||||
|
+ }
|
||||||
|
+ out_free_event:
|
||||||
|
+ kfree(event);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_create_event(const char *name, unsigned long seen,
|
||||||
|
+ int pressed)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event;
|
||||||
|
+
|
||||||
|
+ BH_DBG("create event, name=%s, seen=%lu, pressed=%d\n",
|
||||||
|
+ name, seen, pressed);
|
||||||
|
+
|
||||||
|
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||||
|
+ if (!event)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ event->name = name;
|
||||||
|
+ event->seen = seen;
|
||||||
|
+ event->action = pressed ? "pressed" : "released";
|
||||||
|
+
|
||||||
|
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
|
||||||
|
+ schedule_work(&event->work);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_HOTPLUG
|
||||||
|
+static int button_get_index(unsigned int code)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
|
||||||
|
+ if (button_map[i].code == code)
|
||||||
|
+ return i;
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+static void button_hotplug_event(struct input_handle *handle,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv = handle->private;
|
||||||
|
+ unsigned long seen = jiffies;
|
||||||
|
+ int btn;
|
||||||
|
+
|
||||||
|
+ BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value);
|
||||||
|
+
|
||||||
|
+ if (type != EV_KEY)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ btn = button_get_index(code);
|
||||||
|
+ if (btn < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ button_hotplug_create_event(button_map[btn].name,
|
||||||
|
+ (seen - priv->seen[btn]) / HZ, value);
|
||||||
|
+ priv->seen[btn] = seen;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static void button_hotplug_event(struct input_handle *handle,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif /* CONFIG_HOTPLUG */
|
||||||
|
+
|
||||||
|
+static int button_hotplug_connect(struct input_handler *handler,
|
||||||
|
+ struct input_dev *dev, const struct input_device_id *id)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv;
|
||||||
|
+ int ret;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
|
||||||
|
+ if (test_bit(button_map[i].code, dev->keybit))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (i == ARRAY_SIZE(button_map))
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ priv = kzalloc(sizeof(*priv) +
|
||||||
|
+ (sizeof(unsigned long) * ARRAY_SIZE(button_map)),
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!priv)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ priv->seen = (unsigned long *) &priv[1];
|
||||||
|
+ priv->handle.private = priv;
|
||||||
|
+ priv->handle.dev = dev;
|
||||||
|
+ priv->handle.handler = handler;
|
||||||
|
+ priv->handle.name = DRV_NAME;
|
||||||
|
+
|
||||||
|
+ ret = input_register_handle(&priv->handle);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto err_free_priv;
|
||||||
|
+
|
||||||
|
+ ret = input_open_device(&priv->handle);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto err_unregister_handle;
|
||||||
|
+
|
||||||
|
+ BH_DBG("connected to %s\n", dev->name);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ err_unregister_handle:
|
||||||
|
+ input_unregister_handle(&priv->handle);
|
||||||
|
+
|
||||||
|
+ err_free_priv:
|
||||||
|
+ kfree(priv);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void button_hotplug_disconnect(struct input_handle *handle)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv = handle->private;
|
||||||
|
+
|
||||||
|
+ input_close_device(handle);
|
||||||
|
+ input_unregister_handle(handle);
|
||||||
|
+
|
||||||
|
+ kfree(priv);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct input_device_id button_hotplug_ids[] = {
|
||||||
|
+ {
|
||||||
|
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
|
||||||
|
+ .evbit = { BIT_MASK(EV_KEY) },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ /* Terminating entry */
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+MODULE_DEVICE_TABLE(input, button_hotplug_ids);
|
||||||
|
+
|
||||||
|
+static struct input_handler button_hotplug_handler = {
|
||||||
|
+ .event = button_hotplug_event,
|
||||||
|
+ .connect = button_hotplug_connect,
|
||||||
|
+ .disconnect = button_hotplug_disconnect,
|
||||||
|
+ .name = DRV_NAME,
|
||||||
|
+ .id_table = button_hotplug_ids,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+static int __init button_hotplug_init(void)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
|
||||||
|
+ ret = input_register_handler(&button_hotplug_handler);
|
||||||
|
+ if (ret)
|
||||||
|
+ BH_ERR("unable to register input handler\n");
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+module_init(button_hotplug_init);
|
||||||
|
+
|
||||||
|
+static void __exit button_hotplug_exit(void)
|
||||||
|
+{
|
||||||
|
+ input_unregister_handler(&button_hotplug_handler);
|
||||||
|
+}
|
||||||
|
+module_exit(button_hotplug_exit);
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION(DRV_DESC);
|
||||||
|
+MODULE_VERSION(DRV_VERSION);
|
||||||
|
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+
|
472
3.2.34/3rd-3rdparty-gpio_button_hotplug-0.1.patch
Normal file
472
3.2.34/3rd-3rdparty-gpio_button_hotplug-0.1.patch
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
Submitted By: Mario Fetka (mario dot fetka at gmail dot com)
|
||||||
|
Date: 2012-11-18
|
||||||
|
Initial Package Version: 3.2.33
|
||||||
|
Origin: openwtr.org packages/system/gpio-button-hotplug
|
||||||
|
Upstream Status: unknown
|
||||||
|
Description: gpio button uevent
|
||||||
|
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Kconfig 3rdparty/gpio_button_hotplug/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Kconfig 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/gpio_button_hotplug/Kconfig 2012-11-18 18:41:43.048939468 +0000
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+config GPIO_BUTTON_HOTPLUG
|
||||||
|
+ tristate "GPIO Button Hotplug driver"
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Makefile 3rdparty/gpio_button_hotplug/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Makefile 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/gpio_button_hotplug/Makefile 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+obj-${CONFIG_GPIO_BUTTON_HOTPLUG} += gpio-button-hotplug.o
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/gpio-button-hotplug.c 3rdparty/gpio_button_hotplug/gpio-button-hotplug.c
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/gpio-button-hotplug.c 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/gpio_button_hotplug/gpio-button-hotplug.c 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1,450 @@
|
||||||
|
+/*
|
||||||
|
+ * GPIO Button Hotplug driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * Based on the diag.c - GPIO interface driver for Broadcom boards
|
||||||
|
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
|
||||||
|
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
+ * Copyright (C) 2008 Andy Boyett <agb@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/module.h>
|
||||||
|
+#include <linux/version.h>
|
||||||
|
+#include <linux/kmod.h>
|
||||||
|
+
|
||||||
|
+#include <linux/workqueue.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/netlink.h>
|
||||||
|
+#include <linux/kobject.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+
|
||||||
|
+#define DRV_NAME "gpio-keys-polled"
|
||||||
|
+
|
||||||
|
+#define BH_SKB_SIZE 2048
|
||||||
|
+
|
||||||
|
+#define PFX DRV_NAME ": "
|
||||||
|
+
|
||||||
|
+#undef BH_DEBUG
|
||||||
|
+
|
||||||
|
+#ifdef BH_DEBUG
|
||||||
|
+#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+#else
|
||||||
|
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+
|
||||||
|
+struct bh_priv {
|
||||||
|
+ unsigned long seen;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_event {
|
||||||
|
+ const char *name;
|
||||||
|
+ char *action;
|
||||||
|
+ unsigned long seen;
|
||||||
|
+
|
||||||
|
+ struct sk_buff *skb;
|
||||||
|
+ struct work_struct work;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_map {
|
||||||
|
+ unsigned int code;
|
||||||
|
+ const char *name;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct gpio_keys_button_data {
|
||||||
|
+ struct delayed_work work;
|
||||||
|
+ struct bh_priv bh;
|
||||||
|
+ int last_state;
|
||||||
|
+ int count;
|
||||||
|
+ int threshold;
|
||||||
|
+ int can_sleep;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern u64 uevent_next_seqnum(void);
|
||||||
|
+
|
||||||
|
+#define BH_MAP(_code, _name) \
|
||||||
|
+ { \
|
||||||
|
+ .code = (_code), \
|
||||||
|
+ .name = (_name), \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+static struct bh_map button_map[] = {
|
||||||
|
+ BH_MAP(BTN_0, "BTN_0"),
|
||||||
|
+ BH_MAP(BTN_1, "BTN_1"),
|
||||||
|
+ BH_MAP(BTN_2, "BTN_2"),
|
||||||
|
+ BH_MAP(BTN_3, "BTN_3"),
|
||||||
|
+ BH_MAP(BTN_4, "BTN_4"),
|
||||||
|
+ BH_MAP(BTN_5, "BTN_5"),
|
||||||
|
+ BH_MAP(BTN_6, "BTN_6"),
|
||||||
|
+ BH_MAP(BTN_7, "BTN_7"),
|
||||||
|
+ BH_MAP(BTN_8, "BTN_8"),
|
||||||
|
+ BH_MAP(BTN_9, "BTN_9"),
|
||||||
|
+ BH_MAP(KEY_RESTART, "reset"),
|
||||||
|
+#ifdef KEY_WPS_BUTTON
|
||||||
|
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
|
||||||
|
+#endif /* KEY_WPS_BUTTON */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||||
|
+ const char *format, ...)
|
||||||
|
+{
|
||||||
|
+ static char buf[128];
|
||||||
|
+ char *s;
|
||||||
|
+ va_list args;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ if (argv)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ va_start(args, format);
|
||||||
|
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||||
|
+ va_end(args);
|
||||||
|
+
|
||||||
|
+ if (len >= sizeof(buf)) {
|
||||||
|
+ BH_ERR("buffer size too small\n");
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = skb_put(event->skb, len + 1);
|
||||||
|
+ strcpy(s, buf);
|
||||||
|
+
|
||||||
|
+ BH_DBG("added variable '%s'\n", s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_fill_event(struct bh_event *event)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||||
|
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void button_hotplug_work(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||||
|
+ if (!event->skb)
|
||||||
|
+ goto out_free_event;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "%s@", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ ret = button_hotplug_fill_event(event);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||||
|
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ out_free_skb:
|
||||||
|
+ if (ret) {
|
||||||
|
+ BH_ERR("work error %d\n", ret);
|
||||||
|
+ kfree_skb(event->skb);
|
||||||
|
+ }
|
||||||
|
+ out_free_event:
|
||||||
|
+ kfree(event);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_create_event(const char *name, unsigned long seen,
|
||||||
|
+ int pressed)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event;
|
||||||
|
+
|
||||||
|
+ BH_DBG("create event, name=%s, seen=%lu, pressed=%d\n",
|
||||||
|
+ name, seen, pressed);
|
||||||
|
+
|
||||||
|
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||||
|
+ if (!event)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ event->name = name;
|
||||||
|
+ event->seen = seen;
|
||||||
|
+ event->action = pressed ? "pressed" : "released";
|
||||||
|
+
|
||||||
|
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
|
||||||
|
+ schedule_work(&event->work);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_HOTPLUG
|
||||||
|
+static int button_get_index(unsigned int code)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
|
||||||
|
+ if (button_map[i].code == code)
|
||||||
|
+ return i;
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+static void button_hotplug_event(struct gpio_keys_button_data *data,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv = &data->bh;
|
||||||
|
+ unsigned long seen = jiffies;
|
||||||
|
+ int btn;
|
||||||
|
+
|
||||||
|
+ BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value);
|
||||||
|
+
|
||||||
|
+ if (type != EV_KEY)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ btn = button_get_index(code);
|
||||||
|
+ if (btn < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ button_hotplug_create_event(button_map[btn].name,
|
||||||
|
+ (seen - priv->seen) / HZ, value);
|
||||||
|
+ priv->seen = seen;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static void button_hotplug_event(struct gpio_keys_button_data *data,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif /* CONFIG_HOTPLUG */
|
||||||
|
+
|
||||||
|
+struct gpio_keys_polled_dev {
|
||||||
|
+ struct delayed_work work;
|
||||||
|
+
|
||||||
|
+ struct device *dev;
|
||||||
|
+ struct gpio_keys_platform_data *pdata;
|
||||||
|
+ struct gpio_keys_button_data data[0];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void gpio_keys_polled_check_state(struct gpio_keys_button *button,
|
||||||
|
+ struct gpio_keys_button_data *bdata)
|
||||||
|
+{
|
||||||
|
+ int state;
|
||||||
|
+
|
||||||
|
+ if (bdata->can_sleep)
|
||||||
|
+ state = !!gpio_get_value_cansleep(button->gpio);
|
||||||
|
+ else
|
||||||
|
+ state = !!gpio_get_value(button->gpio);
|
||||||
|
+
|
||||||
|
+ state = !!(state ^ button->active_low);
|
||||||
|
+ if (state != bdata->last_state) {
|
||||||
|
+ unsigned int type = button->type ?: EV_KEY;
|
||||||
|
+
|
||||||
|
+ button_hotplug_event(bdata, type, button->code, state);
|
||||||
|
+ bdata->count = 0;
|
||||||
|
+ bdata->last_state = state;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void gpio_keys_polled_queue_work(struct gpio_keys_polled_dev *bdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ unsigned long delay = msecs_to_jiffies(pdata->poll_interval);
|
||||||
|
+
|
||||||
|
+ if (delay >= HZ)
|
||||||
|
+ delay = round_jiffies_relative(delay);
|
||||||
|
+ schedule_delayed_work(&bdev->work, delay);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void gpio_keys_polled_poll(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_polled_dev *bdev =
|
||||||
|
+ container_of(work, struct gpio_keys_polled_dev, work.work);
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < bdev->pdata->nbuttons; i++) {
|
||||||
|
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
|
||||||
|
+
|
||||||
|
+ if (bdata->count < bdata->threshold)
|
||||||
|
+ bdata->count++;
|
||||||
|
+ else
|
||||||
|
+ gpio_keys_polled_check_state(&pdata->buttons[i], bdata);
|
||||||
|
+ }
|
||||||
|
+ gpio_keys_polled_queue_work(bdev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __devinit gpio_keys_polled_open(struct gpio_keys_polled_dev *bdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (pdata->enable)
|
||||||
|
+ pdata->enable(bdev->dev);
|
||||||
|
+
|
||||||
|
+ /* report initial state of the buttons */
|
||||||
|
+ for (i = 0; i < pdata->nbuttons; i++)
|
||||||
|
+ gpio_keys_polled_check_state(&pdata->buttons[i], &bdev->data[i]);
|
||||||
|
+
|
||||||
|
+ gpio_keys_polled_queue_work(bdev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __devexit gpio_keys_polled_close(struct gpio_keys_polled_dev *bdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+
|
||||||
|
+ cancel_delayed_work_sync(&bdev->work);
|
||||||
|
+
|
||||||
|
+ if (pdata->disable)
|
||||||
|
+ pdata->disable(bdev->dev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __devinit gpio_keys_polled_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ struct gpio_keys_polled_dev *bdev;
|
||||||
|
+ int error;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (!pdata || !pdata->poll_interval)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) +
|
||||||
|
+ pdata->nbuttons * sizeof(struct gpio_keys_button_data),
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!bdev) {
|
||||||
|
+ dev_err(dev, "no memory for private data\n");
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < pdata->nbuttons; i++) {
|
||||||
|
+ struct gpio_keys_button *button = &pdata->buttons[i];
|
||||||
|
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
|
||||||
|
+ unsigned int gpio = button->gpio;
|
||||||
|
+
|
||||||
|
+ if (button->wakeup) {
|
||||||
|
+ dev_err(dev, DRV_NAME " does not support wakeup\n");
|
||||||
|
+ error = -EINVAL;
|
||||||
|
+ goto err_free_gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ error = gpio_request(gpio,
|
||||||
|
+ button->desc ? button->desc : DRV_NAME);
|
||||||
|
+ if (error) {
|
||||||
|
+ dev_err(dev, "unable to claim gpio %u, err=%d\n",
|
||||||
|
+ gpio, error);
|
||||||
|
+ goto err_free_gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ error = gpio_direction_input(gpio);
|
||||||
|
+ if (error) {
|
||||||
|
+ dev_err(dev,
|
||||||
|
+ "unable to set direction on gpio %u, err=%d\n",
|
||||||
|
+ gpio, error);
|
||||||
|
+ goto err_free_gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bdata->can_sleep = gpio_cansleep(gpio);
|
||||||
|
+ bdata->last_state = 0;
|
||||||
|
+ bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
|
||||||
|
+ pdata->poll_interval);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bdev->dev = &pdev->dev;
|
||||||
|
+ bdev->pdata = pdata;
|
||||||
|
+ platform_set_drvdata(pdev, bdev);
|
||||||
|
+
|
||||||
|
+ INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll);
|
||||||
|
+
|
||||||
|
+ gpio_keys_polled_open(bdev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+err_free_gpio:
|
||||||
|
+ while (--i >= 0)
|
||||||
|
+ gpio_free(pdata->buttons[i].gpio);
|
||||||
|
+
|
||||||
|
+ kfree(bdev);
|
||||||
|
+ platform_set_drvdata(pdev, NULL);
|
||||||
|
+
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __devexit gpio_keys_polled_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev);
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ int i = pdata->nbuttons;
|
||||||
|
+
|
||||||
|
+ gpio_keys_polled_close(bdev);
|
||||||
|
+
|
||||||
|
+ while (--i >= 0)
|
||||||
|
+ gpio_free(pdata->buttons[i].gpio);
|
||||||
|
+
|
||||||
|
+ kfree(bdev);
|
||||||
|
+ platform_set_drvdata(pdev, NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct platform_driver gpio_keys_polled_driver = {
|
||||||
|
+ .probe = gpio_keys_polled_probe,
|
||||||
|
+ .remove = __devexit_p(gpio_keys_polled_remove),
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = DRV_NAME,
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init gpio_keys_polled_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_register(&gpio_keys_polled_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit gpio_keys_polled_exit(void)
|
||||||
|
+{
|
||||||
|
+ platform_driver_unregister(&gpio_keys_polled_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(gpio_keys_polled_init);
|
||||||
|
+module_exit(gpio_keys_polled_exit);
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||||
|
+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
|
||||||
|
+MODULE_DESCRIPTION("Polled GPIO Buttons hotplug driver");
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+MODULE_ALIAS("platform:" DRV_NAME);
|
1354
3.2.34/3rd-3rdparty-gpio_event_drv-0.1.patch
Normal file
1354
3.2.34/3rd-3rdparty-gpio_event_drv-0.1.patch
Normal file
File diff suppressed because it is too large
Load Diff
156
3.2.34/3rd-3rdparty-merge.patch
Normal file
156
3.2.34/3rd-3rdparty-merge.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
diff -uNr linux-3.2.33-go.orig/arch/alpha/Kconfig linux-3.2.33-go/arch/alpha/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/alpha/Kconfig 2012-11-15 22:08:02.768806792 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/alpha/Kconfig 2012-11-15 22:08:29.937483632 +0100
|
||||||
|
@@ -673,3 +673,4 @@
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/Kconfig linux-3.2.33-go/arch/arm/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/Kconfig 2012-11-15 22:07:59.952839378 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/Kconfig 2012-11-15 22:14:01.950566716 +0100
|
||||||
|
@@ -2259,3 +2259,5 @@
|
||||||
|
source "crypto/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/ia64/Kconfig linux-3.2.33-go/arch/ia64/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/ia64/Kconfig 2012-11-15 22:08:00.893828523 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/ia64/Kconfig 2012-11-15 22:08:29.938483621 +0100
|
||||||
|
@@ -669,3 +669,5 @@
|
||||||
|
|
||||||
|
config IOMMU_HELPER
|
||||||
|
def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB)
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/mips/Kconfig linux-3.2.33-go/arch/mips/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/mips/Kconfig 2012-11-15 22:08:02.698807597 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/mips/Kconfig 2012-11-15 22:08:29.939483610 +0100
|
||||||
|
@@ -2485,3 +2485,5 @@
|
||||||
|
source "crypto/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/powerpc/Kconfig linux-3.2.33-go/arch/powerpc/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/powerpc/Kconfig 2012-11-15 22:08:01.893816938 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/powerpc/Kconfig 2012-11-15 22:08:29.940483598 +0100
|
||||||
|
@@ -980,3 +980,5 @@
|
||||||
|
bool
|
||||||
|
|
||||||
|
source "arch/powerpc/kvm/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/sparc/Kconfig linux-3.2.33-go/arch/sparc/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/sparc/Kconfig 2012-11-15 22:08:00.130837331 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/sparc/Kconfig 2012-11-15 22:08:29.941483586 +0100
|
||||||
|
@@ -605,3 +605,5 @@
|
||||||
|
source "crypto/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/x86/Kconfig linux-3.2.33-go/arch/x86/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/x86/Kconfig 2012-11-15 22:08:00.435833823 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/x86/Kconfig 2012-11-15 22:08:29.945483540 +0100
|
||||||
|
@@ -2179,3 +2179,5 @@
|
||||||
|
source "arch/x86/kvm/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/Makefile linux-3.2.33-go/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/Makefile 2012-11-15 22:08:03.435799123 +0100
|
||||||
|
+++ linux-3.2.33-go/Makefile 2012-11-15 22:08:29.946483529 +0100
|
||||||
|
@@ -507,7 +507,7 @@
|
||||||
|
|
||||||
|
# Objects we will link into vmlinux / subdirs we need to visit
|
||||||
|
init-y := init/
|
||||||
|
-drivers-y := drivers/ sound/ firmware/
|
||||||
|
+drivers-y := drivers/ sound/ firmware/ 3rdparty/
|
||||||
|
net-y := net/
|
||||||
|
libs-y := lib/
|
||||||
|
core-y := usr/
|
||||||
|
diff -uNr linux-3.2.33-go.orig/scripts/kconfig/Makefile linux-3.2.33-go/scripts/kconfig/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/scripts/kconfig/Makefile 2012-11-15 22:07:58.064861094 +0100
|
||||||
|
+++ linux-3.2.33-go/scripts/kconfig/Makefile 2012-11-15 22:08:55.603180188 +0100
|
||||||
|
@@ -11,29 +11,29 @@
|
||||||
|
Kconfig := Kconfig
|
||||||
|
endif
|
||||||
|
|
||||||
|
-xconfig: $(obj)/qconf
|
||||||
|
+xconfig: $(obj)/qconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-gconfig: $(obj)/gconf
|
||||||
|
+gconfig: $(obj)/gconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-menuconfig: $(obj)/mconf
|
||||||
|
+menuconfig: $(obj)/mconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-config: $(obj)/conf
|
||||||
|
+config: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --oldaskconfig $(Kconfig)
|
||||||
|
|
||||||
|
-nconfig: $(obj)/nconf
|
||||||
|
+nconfig: $(obj)/nconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-oldconfig: $(obj)/conf
|
||||||
|
+oldconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
|
||||||
|
-silentoldconfig: $(obj)/conf
|
||||||
|
+silentoldconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$(Q)mkdir -p include/generated
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
|
||||||
|
-localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
|
||||||
|
+localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 3rdparty/Makefile
|
||||||
|
$(Q)mkdir -p include/generated
|
||||||
|
$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
|
||||||
|
$(Q)if [ -f .config ]; then \
|
||||||
|
@@ -90,18 +90,18 @@
|
||||||
|
*) cat $(CLONECONFIG) > .config.running ;; \
|
||||||
|
esac && \
|
||||||
|
echo -e "Cloning configuration file $(CLONECONFIG)\n"
|
||||||
|
- $(Q)$< --defconfig=.config.running arch/$(SRCARCH)/Kconfig
|
||||||
|
+ $(Q)$< --defconfig=.config.running arch/$(SRCARCH)/Kconfig 3rdparty/Makefile
|
||||||
|
|
||||||
|
|
||||||
|
PHONY += listnewconfig oldnoconfig savedefconfig defconfig
|
||||||
|
|
||||||
|
-listnewconfig oldnoconfig: $(obj)/conf
|
||||||
|
+listnewconfig oldnoconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
|
||||||
|
-savedefconfig: $(obj)/conf
|
||||||
|
+savedefconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --$@=defconfig $(Kconfig)
|
||||||
|
|
||||||
|
-defconfig: $(obj)/conf
|
||||||
|
+defconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
ifeq ($(KBUILD_DEFCONFIG),)
|
||||||
|
$< --defconfig $(Kconfig)
|
||||||
|
else
|
||||||
|
@@ -109,7 +109,7 @@
|
||||||
|
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-%_defconfig: $(obj)/conf
|
||||||
|
+%_defconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
|
||||||
|
|
||||||
|
# Help text used by make help
|
||||||
|
@@ -186,6 +186,8 @@
|
||||||
|
gconf-target := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
+3rdparty/Makefile:
|
||||||
|
+ pushd $(srctree)/3rdparty ; $(PERL) ./mkbuild.pl ; popd
|
||||||
|
|
||||||
|
ifeq ($(qconf-target),1)
|
||||||
|
hostprogs-y += qconf
|
1769
3.2.34/3rd-3rdparty-netatop-0.1.1.patch
Normal file
1769
3.2.34/3rd-3rdparty-netatop-0.1.1.patch
Normal file
File diff suppressed because it is too large
Load Diff
21
3.2.34/910-kobject_uevent.patch
Normal file
21
3.2.34/910-kobject_uevent.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
--- a/lib/kobject_uevent.c
|
||||||
|
+++ b/lib/kobject_uevent.c
|
||||||
|
@@ -50,6 +50,18 @@ static const char *kobject_actions[] = {
|
||||||
|
[KOBJ_OFFLINE] = "offline",
|
||||||
|
};
|
||||||
|
|
||||||
|
+u64 uevent_next_seqnum(void)
|
||||||
|
+{
|
||||||
|
+ u64 seq;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&uevent_sock_mutex);
|
||||||
|
+ seq = ++uevent_seqnum;
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
+
|
||||||
|
+ return seq;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* kobject_action_type - translate action string to numeric type
|
||||||
|
*
|
85
3.2.34/911-kobject_add_broadcast_uevent.patch
Normal file
85
3.2.34/911-kobject_add_broadcast_uevent.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
--- a/include/linux/kobject.h
|
||||||
|
+++ b/include/linux/kobject.h
|
||||||
|
@@ -31,6 +31,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[];
|
||||||
|
|
||||||
|
@@ -213,6 +215,10 @@ int add_uevent_var(struct kobj_uevent_en
|
||||||
|
|
||||||
|
int kobject_action_type(const char *buf, size_t count,
|
||||||
|
enum kobject_action *type);
|
||||||
|
+
|
||||||
|
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation);
|
||||||
|
+
|
||||||
|
#else
|
||||||
|
static inline int kobject_uevent(struct kobject *kobj,
|
||||||
|
enum kobject_action action)
|
||||||
|
@@ -229,6 +235,16 @@ int add_uevent_var(struct kobj_uevent_en
|
||||||
|
static inline int kobject_action_type(const char *buf, size_t count,
|
||||||
|
enum kobject_action *type)
|
||||||
|
{ return -EINVAL; }
|
||||||
|
+
|
||||||
|
+void kfree_skb(struct sk_buff *);
|
||||||
|
+
|
||||||
|
+static inline int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation)
|
||||||
|
+{
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _KOBJECT_H_ */
|
||||||
|
--- a/lib/kobject_uevent.c
|
||||||
|
+++ b/lib/kobject_uevent.c
|
||||||
|
@@ -381,6 +381,43 @@ int add_uevent_var(struct kobj_uevent_en
|
||||||
|
EXPORT_SYMBOL_GPL(add_uevent_var);
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET)
|
||||||
|
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation)
|
||||||
|
+{
|
||||||
|
+ struct uevent_sock *ue_sk;
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ /* send netlink message */
|
||||||
|
+ mutex_lock(&uevent_sock_mutex);
|
||||||
|
+ list_for_each_entry(ue_sk, &uevent_sock_list, list) {
|
||||||
|
+ struct sock *uevent_sock = ue_sk->sk;
|
||||||
|
+ struct sk_buff *skb2;
|
||||||
|
+
|
||||||
|
+ skb2 = skb_clone(skb, allocation);
|
||||||
|
+ if (!skb2)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ err = netlink_broadcast(uevent_sock, skb2, pid, group,
|
||||||
|
+ allocation);
|
||||||
|
+ if (err)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
+
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation)
|
||||||
|
+{
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+EXPORT_SYMBOL_GPL(broadcast_uevent);
|
||||||
|
+
|
||||||
|
+#if defined(CONFIG_NET)
|
||||||
|
static int uevent_net_init(struct net *net)
|
||||||
|
{
|
||||||
|
struct uevent_sock *ue_sk;
|
145
3.2.34/Add_CONFIG_VFAT_FS_DUALNAMES_option.patch
Normal file
145
3.2.34/Add_CONFIG_VFAT_FS_DUALNAMES_option.patch
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig
|
||||||
|
index 182f9ff..907a5de 100644
|
||||||
|
--- a/fs/fat/Kconfig
|
||||||
|
+++ b/fs/fat/Kconfig
|
||||||
|
@@ -74,6 +74,26 @@ config VFAT_FS
|
||||||
|
To compile this as a module, choose M here: the module will be called
|
||||||
|
vfat.
|
||||||
|
|
||||||
|
+config VFAT_FS_DUALNAMES
|
||||||
|
+ bool "VFAT dual names support"
|
||||||
|
+ depends on VFAT_FS
|
||||||
|
+ help
|
||||||
|
+ This option provides support for dual filenames on VFAT filesystems.
|
||||||
|
+ If this option is disabled then file creation will either put
|
||||||
|
+ a short (8.3) name or a long name on the file, but never both.
|
||||||
|
+ The field where a shortname would normally go is filled with
|
||||||
|
+ invalid characters such that it cannot be considered a valid
|
||||||
|
+ short filename.
|
||||||
|
+
|
||||||
|
+ That means that long filenames created with this option
|
||||||
|
+ disabled will not be accessible at all to operating systems
|
||||||
|
+ that do not understand the VFAT extensions.
|
||||||
|
+
|
||||||
|
+ Users considering enabling this option should consider the implications
|
||||||
|
+ of any patents that may exist on dual filenames in VFAT.
|
||||||
|
+
|
||||||
|
+ If unsure, say N
|
||||||
|
+
|
||||||
|
config FAT_DEFAULT_CODEPAGE
|
||||||
|
int "Default codepage for FAT"
|
||||||
|
depends on MSDOS_FS || VFAT_FS
|
||||||
|
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
|
||||||
|
index 38ff75a..cd5d3ec 100644
|
||||||
|
--- a/fs/fat/dir.c
|
||||||
|
+++ b/fs/fat/dir.c
|
||||||
|
@@ -415,14 +415,13 @@
|
||||||
|
}
|
||||||
|
i += chl;
|
||||||
|
}
|
||||||
|
- if (!last_u)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- /* Compare shortname */
|
||||||
|
- bufuname[last_u] = 0x0000;
|
||||||
|
- len = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname));
|
||||||
|
- if (fat_name_match(sbi, name, name_len, bufname, len))
|
||||||
|
- goto found;
|
||||||
|
+ if (last_u) {
|
||||||
|
+ /* Compare shortname */
|
||||||
|
+ bufuname[last_u] = 0x0000;
|
||||||
|
+ len = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname));
|
||||||
|
+ if (fat_name_match(sbi, name, name_len, bufname, len))
|
||||||
|
+ goto found;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (nr_slots) {
|
||||||
|
void *longname = unicode + FAT_MAX_UNI_CHARS;
|
||||||
|
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
|
||||||
|
index 73471b7..894f44d 100644
|
||||||
|
--- a/fs/fat/namei_vfat.c
|
||||||
|
+++ b/fs/fat/namei_vfat.c
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include <linux/smp_lock.h>
|
||||||
|
#include <linux/buffer_head.h>
|
||||||
|
#include <linux/namei.h>
|
||||||
|
+#include <linux/random.h>
|
||||||
|
#include "fat.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -586,6 +587,59 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifndef CONFIG_VFAT_FS_DUALNAMES
|
||||||
|
+/*
|
||||||
|
+ * build a 11 byte 8.3 buffer which is not a short filename. We want 11
|
||||||
|
+ * bytes which:
|
||||||
|
+ * - will be seen as a constant string to all APIs on Linux and Windows
|
||||||
|
+ * - cannot be matched with wildcard patterns
|
||||||
|
+ * - cannot be used to access the file
|
||||||
|
+ * - has a low probability of collision within a directory
|
||||||
|
+ * - has an invalid 3 byte extension
|
||||||
|
+ * - contains at least one non-space and non-nul byte
|
||||||
|
+ */
|
||||||
|
+static void vfat_build_dummy_83_buffer(struct inode *dir, char *msdos_name)
|
||||||
|
+{
|
||||||
|
+ u32 rand_num = random32() & 0x3FFFFFFF;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ /* a value of zero would leave us with only nul and spaces,
|
||||||
|
+ * which would not work with older linux systems
|
||||||
|
+ */
|
||||||
|
+ if (rand_num == 0)
|
||||||
|
+ rand_num = 1;
|
||||||
|
+
|
||||||
|
+ /* we start with a space followed by nul as spaces at the
|
||||||
|
+ * start of an entry are trimmed in FAT, which means that
|
||||||
|
+ * starting the 11 bytes with 0x20 0x00 gives us a value which
|
||||||
|
+ * cannot be used to access the file. It also means that the
|
||||||
|
+ * value as seen from all Windows and Linux APIs is a constant
|
||||||
|
+ */
|
||||||
|
+ msdos_name[0] = ' ';
|
||||||
|
+ msdos_name[1] = 0;
|
||||||
|
+
|
||||||
|
+ /* we use / and 2 nul bytes for the extension. These are
|
||||||
|
+ * invalid in FAT and mean that utilities that show the
|
||||||
|
+ * directory show no extension, but still work via the long
|
||||||
|
+ * name for old Linux kernels
|
||||||
|
+ */
|
||||||
|
+ msdos_name[8] = '/';
|
||||||
|
+ msdos_name[9] = 0;
|
||||||
|
+ msdos_name[10] = 0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * fill the remaining 6 bytes with random invalid values
|
||||||
|
+ * This gives us a low collision rate, which means a low
|
||||||
|
+ * chance of problems with chkdsk.exe and WindowsXP
|
||||||
|
+ */
|
||||||
|
+ for (i = 2; i < 8; i++) {
|
||||||
|
+ msdos_name[i] = rand_num & 0x1F;
|
||||||
|
+ rand_num >>= 5;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static int vfat_build_slots(struct inode *dir, const unsigned char *name,
|
||||||
|
int len, int is_dir, int cluster,
|
||||||
|
struct timespec *ts,
|
||||||
|
@@ -628,6 +682,11 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
|
||||||
|
goto shortname;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifndef CONFIG_VFAT_FS_DUALNAMES
|
||||||
|
+ vfat_build_dummy_83_buffer(dir, msdos_name);
|
||||||
|
+ lcase = 0;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* build the entry of long file name */
|
||||||
|
cksum = fat_checksum(msdos_name);
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.0.4
|
||||||
|
|
||||||
|
|
1036
3.2.34/accessfs-3.2-0.26.patch
Normal file
1036
3.2.34/accessfs-3.2-0.26.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
|||||||
|
>From 9f04e51293b130474504216a477bb2a73cbf59e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anssi Hannula <anssi.hannula@iki.fi>
|
||||||
|
Date: Thu, 22 Mar 2012 22:29:11 +0200
|
||||||
|
Subject: [PATCH] ata: prefer ata drivers over ide drivers when both are built
|
||||||
|
|
||||||
|
Currently the old IDE drivers are preferred over ATA drivers when both
|
||||||
|
are built, since ide/ is listed first in drivers/Makefile and therefore
|
||||||
|
the IDE drivers end up before ATA drivers in modules.order which is used
|
||||||
|
by depmod/modprobe for module ordering.
|
||||||
|
|
||||||
|
Change it so that ATA drivers are preferred over IDE driver by moving
|
||||||
|
the ide/ entry under ata/ in drivers/Makefile.
|
||||||
|
|
||||||
|
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
|
||||||
|
---
|
||||||
|
drivers/Makefile | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/Makefile b/drivers/Makefile
|
||||||
|
index 932e8bf..e8df3d0 100644
|
||||||
|
--- a/drivers/Makefile
|
||||||
|
+++ b/drivers/Makefile
|
||||||
|
@@ -47,9 +47,9 @@ obj-$(CONFIG_PARPORT) += parport/
|
||||||
|
obj-y += base/ block/ misc/ mfd/ nfc/
|
||||||
|
obj-$(CONFIG_NUBUS) += nubus/
|
||||||
|
obj-y += macintosh/
|
||||||
|
-obj-$(CONFIG_IDE) += ide/
|
||||||
|
obj-$(CONFIG_SCSI) += scsi/
|
||||||
|
obj-$(CONFIG_ATA) += ata/
|
||||||
|
+obj-$(CONFIG_IDE) += ide/
|
||||||
|
obj-$(CONFIG_TARGET_CORE) += target/
|
||||||
|
obj-$(CONFIG_MTD) += mtd/
|
||||||
|
obj-$(CONFIG_SPI) += spi/
|
||||||
|
--
|
||||||
|
1.7.9.3
|
||||||
|
|
30657
3.2.34/aufs3-standalone-3.2.patch
Normal file
30657
3.2.34/aufs3-standalone-3.2.patch
Normal file
File diff suppressed because it is too large
Load Diff
1245
3.2.34/bump/1021_linux-3.2.22.patch
Normal file
1245
3.2.34/bump/1021_linux-3.2.22.patch
Normal file
File diff suppressed because it is too large
Load Diff
1862
3.2.34/bump/1022_linux-3.2.23.patch
Normal file
1862
3.2.34/bump/1022_linux-3.2.23.patch
Normal file
File diff suppressed because it is too large
Load Diff
4684
3.2.34/bump/1023_linux-3.2.24.patch
Normal file
4684
3.2.34/bump/1023_linux-3.2.24.patch
Normal file
File diff suppressed because it is too large
Load Diff
4503
3.2.34/bump/1024_linux-3.2.25.patch
Normal file
4503
3.2.34/bump/1024_linux-3.2.25.patch
Normal file
File diff suppressed because it is too large
Load Diff
238
3.2.34/bump/1025_linux-3.2.26.patch
Normal file
238
3.2.34/bump/1025_linux-3.2.26.patch
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index e13e4e7..fa5acc83 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
VERSION = 3
|
||||||
|
PATCHLEVEL = 2
|
||||||
|
-SUBLEVEL = 25
|
||||||
|
+SUBLEVEL = 26
|
||||||
|
EXTRAVERSION =
|
||||||
|
NAME = Saber-toothed Squirrel
|
||||||
|
|
||||||
|
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
|
||||||
|
index bb3ee36..f7c89e2 100644
|
||||||
|
--- a/arch/x86/include/asm/processor.h
|
||||||
|
+++ b/arch/x86/include/asm/processor.h
|
||||||
|
@@ -99,7 +99,6 @@ struct cpuinfo_x86 {
|
||||||
|
u16 apicid;
|
||||||
|
u16 initial_apicid;
|
||||||
|
u16 x86_clflush_size;
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
/* number of cores as seen by the OS: */
|
||||||
|
u16 booted_cores;
|
||||||
|
/* Physical processor id: */
|
||||||
|
@@ -110,7 +109,6 @@ struct cpuinfo_x86 {
|
||||||
|
u8 compute_unit_id;
|
||||||
|
/* Index into per_cpu list: */
|
||||||
|
u16 cpu_index;
|
||||||
|
-#endif
|
||||||
|
u32 microcode;
|
||||||
|
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
|
||||||
|
|
||||||
|
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
|
||||||
|
index bae1efe..be16854 100644
|
||||||
|
--- a/arch/x86/kernel/amd_nb.c
|
||||||
|
+++ b/arch/x86/kernel/amd_nb.c
|
||||||
|
@@ -154,16 +154,14 @@ int amd_get_subcaches(int cpu)
|
||||||
|
{
|
||||||
|
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
|
||||||
|
unsigned int mask;
|
||||||
|
- int cuid = 0;
|
||||||
|
+ int cuid;
|
||||||
|
|
||||||
|
if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pci_read_config_dword(link, 0x1d4, &mask);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
cuid = cpu_data(cpu).compute_unit_id;
|
||||||
|
-#endif
|
||||||
|
return (mask >> (4 * cuid)) & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -172,7 +170,7 @@ int amd_set_subcaches(int cpu, int mask)
|
||||||
|
static unsigned int reset, ban;
|
||||||
|
struct amd_northbridge *nb = node_to_amd_nb(amd_get_nb_id(cpu));
|
||||||
|
unsigned int reg;
|
||||||
|
- int cuid = 0;
|
||||||
|
+ int cuid;
|
||||||
|
|
||||||
|
if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf)
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -190,9 +188,7 @@ int amd_set_subcaches(int cpu, int mask)
|
||||||
|
pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
cuid = cpu_data(cpu).compute_unit_id;
|
||||||
|
-#endif
|
||||||
|
mask <<= 4 * cuid;
|
||||||
|
mask |= (0xf ^ (1 << cuid)) << 26;
|
||||||
|
|
||||||
|
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
|
||||||
|
index 3524e1f..ff8557e 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/amd.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/amd.c
|
||||||
|
@@ -148,7 +148,6 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
|
||||||
|
|
||||||
|
static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
|
||||||
|
{
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
/* calling is from identify_secondary_cpu() ? */
|
||||||
|
if (!c->cpu_index)
|
||||||
|
return;
|
||||||
|
@@ -192,7 +191,6 @@ static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
|
||||||
|
|
||||||
|
valid_k7:
|
||||||
|
;
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
|
||||||
|
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
||||||
|
index aa003b1..ca93cc7 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/common.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/common.c
|
||||||
|
@@ -676,9 +676,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
|
||||||
|
if (this_cpu->c_early_init)
|
||||||
|
this_cpu->c_early_init(c);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
c->cpu_index = 0;
|
||||||
|
-#endif
|
||||||
|
filter_cpuid_features(c, false);
|
||||||
|
|
||||||
|
setup_smep(c);
|
||||||
|
@@ -764,10 +762,7 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
|
||||||
|
c->apicid = c->initial_apicid;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
-
|
||||||
|
-#ifdef CONFIG_X86_HT
|
||||||
|
c->phys_proc_id = c->initial_apicid;
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_smep(c);
|
||||||
|
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
|
||||||
|
index 5231312..3e6ff6c 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/intel.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/intel.c
|
||||||
|
@@ -181,7 +181,6 @@ static void __cpuinit trap_init_f00f_bug(void)
|
||||||
|
|
||||||
|
static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
|
||||||
|
{
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
/* calling is from identify_secondary_cpu() ? */
|
||||||
|
if (!c->cpu_index)
|
||||||
|
return;
|
||||||
|
@@ -198,7 +197,6 @@ static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
|
||||||
|
WARN_ONCE(1, "WARNING: SMP operation may be unreliable"
|
||||||
|
"with B stepping processors.\n");
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
|
||||||
|
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
|
||||||
|
index b0f1271..3b67877 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/mcheck/mce.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
|
||||||
|
@@ -119,9 +119,7 @@ void mce_setup(struct mce *m)
|
||||||
|
m->time = get_seconds();
|
||||||
|
m->cpuvendor = boot_cpu_data.x86_vendor;
|
||||||
|
m->cpuid = cpuid_eax(1);
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
m->socketid = cpu_data(m->extcpu).phys_proc_id;
|
||||||
|
-#endif
|
||||||
|
m->apicid = cpu_data(m->extcpu).initial_apicid;
|
||||||
|
rdmsrl(MSR_IA32_MCG_CAP, m->mcgcap);
|
||||||
|
}
|
||||||
|
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
|
||||||
|
index 445a61c..d4444be 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
|
||||||
|
@@ -65,11 +65,9 @@ struct threshold_bank {
|
||||||
|
};
|
||||||
|
static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
static unsigned char shared_bank[NR_BANKS] = {
|
||||||
|
0, 0, 0, 0, 1
|
||||||
|
};
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
|
||||||
|
|
||||||
|
@@ -227,10 +225,9 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
|
||||||
|
|
||||||
|
if (!block)
|
||||||
|
per_cpu(bank_map, cpu) |= (1 << bank);
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
+
|
||||||
|
if (shared_bank[bank] && c->cpu_core_id)
|
||||||
|
break;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
memset(&b, 0, sizeof(b));
|
||||||
|
b.cpu = cpu;
|
||||||
|
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
|
||||||
|
index 14b2314..8022c66 100644
|
||||||
|
--- a/arch/x86/kernel/cpu/proc.c
|
||||||
|
+++ b/arch/x86/kernel/cpu/proc.c
|
||||||
|
@@ -64,12 +64,10 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
|
||||||
|
static int show_cpuinfo(struct seq_file *m, void *v)
|
||||||
|
{
|
||||||
|
struct cpuinfo_x86 *c = v;
|
||||||
|
- unsigned int cpu = 0;
|
||||||
|
+ unsigned int cpu;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
cpu = c->cpu_index;
|
||||||
|
-#endif
|
||||||
|
seq_printf(m, "processor\t: %u\n"
|
||||||
|
"vendor_id\t: %s\n"
|
||||||
|
"cpu family\t: %d\n"
|
||||||
|
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
|
||||||
|
index 18a1293..0db57b5 100644
|
||||||
|
--- a/drivers/edac/sb_edac.c
|
||||||
|
+++ b/drivers/edac/sb_edac.c
|
||||||
|
@@ -1609,11 +1609,9 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
|
||||||
|
mce->cpuvendor, mce->cpuid, mce->time,
|
||||||
|
mce->socketid, mce->apicid);
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
/* Only handle if it is the right mc controller */
|
||||||
|
if (cpu_data(mce->cpu).phys_proc_id != pvt->sbridge_dev->mc)
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
smp_rmb();
|
||||||
|
if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
|
||||||
|
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
|
||||||
|
index 0790c98..19b4412 100644
|
||||||
|
--- a/drivers/hwmon/coretemp.c
|
||||||
|
+++ b/drivers/hwmon/coretemp.c
|
||||||
|
@@ -57,16 +57,15 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
|
||||||
|
#define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
|
||||||
|
#define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SMP
|
||||||
|
#define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id
|
||||||
|
#define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id
|
||||||
|
+#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_SMP
|
||||||
|
#define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu))
|
||||||
|
#else
|
||||||
|
-#define TO_PHYS_ID(cpu) (cpu)
|
||||||
|
-#define TO_CORE_ID(cpu) (cpu)
|
||||||
|
#define for_each_sibling(i, cpu) for (i = 0; false; )
|
||||||
|
#endif
|
||||||
|
-#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per-Core Temperature Data
|
3188
3.2.34/bump/1026_linux-3.2.27.patch
Normal file
3188
3.2.34/bump/1026_linux-3.2.27.patch
Normal file
File diff suppressed because it is too large
Load Diff
1114
3.2.34/bump/1027_linux-3.2.28.patch
Normal file
1114
3.2.34/bump/1027_linux-3.2.28.patch
Normal file
File diff suppressed because it is too large
Load Diff
4279
3.2.34/bump/1028_linux-3.2.29.patch
Normal file
4279
3.2.34/bump/1028_linux-3.2.29.patch
Normal file
File diff suppressed because it is too large
Load Diff
5552
3.2.34/bump/1029_linux-3.2.30.patch
Normal file
5552
3.2.34/bump/1029_linux-3.2.30.patch
Normal file
File diff suppressed because it is too large
Load Diff
3327
3.2.34/bump/1030_linux-3.2.31.patch
Normal file
3327
3.2.34/bump/1030_linux-3.2.31.patch
Normal file
File diff suppressed because it is too large
Load Diff
6206
3.2.34/bump/1031_linux-3.2.32.patch
Normal file
6206
3.2.34/bump/1031_linux-3.2.32.patch
Normal file
File diff suppressed because it is too large
Load Diff
3450
3.2.34/bump/1032_linux-3.2.33.patch
Normal file
3450
3.2.34/bump/1032_linux-3.2.33.patch
Normal file
File diff suppressed because it is too large
Load Diff
3678
3.2.34/bump/1033_linux-3.2.34.patch
Normal file
3678
3.2.34/bump/1033_linux-3.2.34.patch
Normal file
File diff suppressed because it is too large
Load Diff
41
3.2.34/cloneconfig.patch
Normal file
41
3.2.34/cloneconfig.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From: Andreas Gruenbacher <agruen@suse.de>
|
||||||
|
Subject: Add ``cloneconfig'' target
|
||||||
|
Patch-mainline: Submitted 24 Feb 2011
|
||||||
|
|
||||||
|
Cloneconfig takes the first configuration it finds which appears
|
||||||
|
to belong to the running kernel, and configures the kernel sources
|
||||||
|
to match this configuration as closely as possible.
|
||||||
|
|
||||||
|
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||||
|
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
scripts/kconfig/Makefile | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
--- a/scripts/kconfig/Makefile
|
||||||
|
+++ b/scripts/kconfig/Makefile
|
||||||
|
@@ -99,6 +99,23 @@ PHONY += allnoconfig allyesconfig allmod
|
||||||
|
|
||||||
|
allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
+
|
||||||
|
+UNAME_RELEASE := $(shell uname -r)
|
||||||
|
+CLONECONFIG := $(firstword $(wildcard /proc/config.gz \
|
||||||
|
+ /lib/modules/$(UNAME_RELEASE)/.config \
|
||||||
|
+ /etc/kernel-config \
|
||||||
|
+ /boot/config-$(UNAME_RELEASE)))
|
||||||
|
+cloneconfig: $(obj)/conf
|
||||||
|
+ $(Q)case "$(CLONECONFIG)" in \
|
||||||
|
+ '') echo -e "The configuration of the running" \
|
||||||
|
+ "kernel could not be determined\n"; \
|
||||||
|
+ false ;; \
|
||||||
|
+ *.gz) gzip -cd $(CLONECONFIG) > .config.running ;; \
|
||||||
|
+ *) cat $(CLONECONFIG) > .config.running ;; \
|
||||||
|
+ esac && \
|
||||||
|
+ echo -e "Cloning configuration file $(CLONECONFIG)\n"
|
||||||
|
+ $(Q)$< --defconfig=.config.running arch/$(SRCARCH)/Kconfig
|
||||||
|
+
|
||||||
|
|
||||||
|
PHONY += listnewconfig oldnoconfig savedefconfig defconfig
|
||||||
|
|
337
3.2.34/colored-printk-3.2.33.patch
Normal file
337
3.2.34/colored-printk-3.2.33.patch
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/arch/x86/kernel/early_printk.c linux-2.6.29.3-cprintk/arch/x86/kernel/early_printk.c
|
||||||
|
--- a/arch/x86/kernel/early_printk.c 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/arch/x86/kernel/early_printk.c 2009-05-09 16:10:36.000000000 +0200
|
||||||
|
@@ -23,7 +23,8 @@
|
||||||
|
static int max_ypos = 25, max_xpos = 80;
|
||||||
|
static int current_ypos = 25, current_xpos;
|
||||||
|
|
||||||
|
-static void early_vga_write(struct console *con, const char *str, unsigned n)
|
||||||
|
+static void early_vga_write(struct console *con, const char *str, unsigned n,
|
||||||
|
+ unsigned int loglevel)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int i, k, j;
|
||||||
|
@@ -93,7 +94,8 @@ static int early_serial_putc(unsigned ch
|
||||||
|
return timeout ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void early_serial_write(struct console *con, const char *s, unsigned n)
|
||||||
|
+static void early_serial_write(struct console *con, const char *s, unsigned n,
|
||||||
|
+ unsigned int loglevel)
|
||||||
|
{
|
||||||
|
while (*s && n-- > 0) {
|
||||||
|
if (*s == '\n')
|
||||||
|
@@ -887,7 +889,7 @@ asmlinkage void early_printk(const char
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
n = vscnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
- early_console->write(early_console, buf, n);
|
||||||
|
+ early_console->write(early_console, buf, n, 0);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/drivers/char/Kconfig linux-2.6.29.3-cprintk/drivers/tty/Kconfig
|
||||||
|
--- a/drivers/char/Kconfig 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/drivers/tty/Kconfig 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -66,6 +66,111 @@ config VT_CONSOLE
|
||||||
|
|
||||||
|
If unsure, say Y.
|
||||||
|
|
||||||
|
+menuconfig VT_CKO
|
||||||
|
+ bool "Colored kernel message output"
|
||||||
|
+ depends on VT_CONSOLE
|
||||||
|
+ ---help---
|
||||||
|
+ This option enables kernel messages to be emitted in
|
||||||
|
+ colors other than the default.
|
||||||
|
+
|
||||||
|
+ The color value you need to enter is composed (OR-ed)
|
||||||
|
+ of a foreground and a background color.
|
||||||
|
+
|
||||||
|
+ Foreground:
|
||||||
|
+ 0x00 = black, 0x08 = dark gray,
|
||||||
|
+ 0x01 = red, 0x09 = light red,
|
||||||
|
+ 0x02 = green, 0x0A = light green,
|
||||||
|
+ 0x03 = brown, 0x0B = yellow,
|
||||||
|
+ 0x04 = blue, 0x0C = light blue,
|
||||||
|
+ 0x05 = magenta, 0x0D = light magenta,
|
||||||
|
+ 0x06 = cyan, 0x0E = light cyan,
|
||||||
|
+ 0x07 = gray, 0x0F = white,
|
||||||
|
+
|
||||||
|
+ (Foreground colors 0x08 to 0x0F do not work when a VGA
|
||||||
|
+ console font with 512 glyphs is used.)
|
||||||
|
+
|
||||||
|
+ Background:
|
||||||
|
+ 0x00 = black, 0x40 = blue,
|
||||||
|
+ 0x10 = red, 0x50 = magenta,
|
||||||
|
+ 0x20 = green, 0x60 = cyan,
|
||||||
|
+ 0x30 = brown, 0x70 = gray,
|
||||||
|
+
|
||||||
|
+ For example, 0x1F would yield white on red.
|
||||||
|
+
|
||||||
|
+ If unsure, say N.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_EMERG_COLOR
|
||||||
|
+ hex "Emergency messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel emergency messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_ALERT_COLOR
|
||||||
|
+ hex "Alert messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel alert messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_CRIT_COLOR
|
||||||
|
+ hex "Critical messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel critical messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_ERR_COLOR
|
||||||
|
+ hex "Error messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel error messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_WARNING_COLOR
|
||||||
|
+ hex "Warning messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel warning messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_NOTICE_COLOR
|
||||||
|
+ hex "Notice messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel notice messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_INFO_COLOR
|
||||||
|
+ hex "Information messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel information messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
+config VT_PRINTK_DEBUG_COLOR
|
||||||
|
+ hex "Debug messages color"
|
||||||
|
+ range 0x00 0xFF
|
||||||
|
+ depends on VT_CKO
|
||||||
|
+ default 0x07
|
||||||
|
+ ---help---
|
||||||
|
+ This option defines with which color kernel debug messages will
|
||||||
|
+ be printed to the console.
|
||||||
|
+
|
||||||
|
config HW_CONSOLE
|
||||||
|
bool
|
||||||
|
depends on VT && !S390 && !UML
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/drivers/char/vt.c linux-2.6.29.3-cprintk/drivers/tty/vt/vt.c
|
||||||
|
--- a/drivers/char/vt.c 2009-05-09 10:46:57.000000000 +0200
|
||||||
|
+++ b/drivers/tty/vt/vt.c 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -73,6 +73,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
+#include <linux/moduleparam.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/tty.h>
|
||||||
|
@@ -2431,17 +2432,45 @@ struct tty_driver *console_driver;
|
||||||
|
|
||||||
|
#ifdef CONFIG_VT_CONSOLE
|
||||||
|
|
||||||
|
+#ifdef CONFIG_VT_CKO
|
||||||
|
+static unsigned int printk_color[8] __read_mostly = {
|
||||||
|
+ CONFIG_VT_PRINTK_EMERG_COLOR, /* KERN_EMERG */
|
||||||
|
+ CONFIG_VT_PRINTK_ALERT_COLOR, /* KERN_ALERT */
|
||||||
|
+ CONFIG_VT_PRINTK_CRIT_COLOR, /* KERN_CRIT */
|
||||||
|
+ CONFIG_VT_PRINTK_ERR_COLOR, /* KERN_ERR */
|
||||||
|
+ CONFIG_VT_PRINTK_WARNING_COLOR, /* KERN_WARNING */
|
||||||
|
+ CONFIG_VT_PRINTK_NOTICE_COLOR, /* KERN_NOTICE */
|
||||||
|
+ CONFIG_VT_PRINTK_INFO_COLOR, /* KERN_INFO */
|
||||||
|
+ CONFIG_VT_PRINTK_DEBUG_COLOR, /* KERN_DEBUG */
|
||||||
|
+};
|
||||||
|
+module_param_array(printk_color, uint, NULL, S_IRUGO | S_IWUSR);
|
||||||
|
+
|
||||||
|
+static inline void vc_set_color(struct vc_data *vc, unsigned char color)
|
||||||
|
+{
|
||||||
|
+ vc->vc_color = color_table[color & 0xF] |
|
||||||
|
+ (color_table[(color >> 4) & 0x7] << 4) |
|
||||||
|
+ (color & 0x80);
|
||||||
|
+ update_attr(vc);
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static unsigned int printk_color[8];
|
||||||
|
+static inline void vc_set_color(const struct vc_data *vc, unsigned char c)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Console on virtual terminal
|
||||||
|
*
|
||||||
|
* The console must be locked when we get here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static void vt_console_print(struct console *co, const char *b, unsigned count)
|
||||||
|
+static void vt_console_print(struct console *co, const char *b, unsigned count,
|
||||||
|
+ unsigned int loglevel)
|
||||||
|
{
|
||||||
|
struct vc_data *vc = vc_cons[fg_console].d;
|
||||||
|
- unsigned char c;
|
||||||
|
static DEFINE_SPINLOCK(printing_lock);
|
||||||
|
+ unsigned char current_color, c;
|
||||||
|
const ushort *start;
|
||||||
|
ushort cnt = 0;
|
||||||
|
ushort myx;
|
||||||
|
@@ -2474,11 +2503,19 @@ static void vt_console_print(struct cons
|
||||||
|
|
||||||
|
start = (ushort *)vc->vc_pos;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * We always get a valid loglevel - <8> and "no level" is transformed
|
||||||
|
+ * to <4> in the typical kernel.
|
||||||
|
+ */
|
||||||
|
+ current_color = printk_color[loglevel];
|
||||||
|
+ vc_set_color(vc, current_color);
|
||||||
|
+
|
||||||
|
/* Contrived structure to try to emulate original need_wrap behaviour
|
||||||
|
* Problems caused when we have need_wrap set on '\n' character */
|
||||||
|
while (count--) {
|
||||||
|
c = *b++;
|
||||||
|
if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
|
||||||
|
+ vc_set_color(vc, vc->vc_def_color);
|
||||||
|
if (cnt > 0) {
|
||||||
|
if (CON_IS_VISIBLE(vc))
|
||||||
|
vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
|
||||||
|
@@ -2491,6 +2528,7 @@ static void vt_console_print(struct cons
|
||||||
|
bs(vc);
|
||||||
|
start = (ushort *)vc->vc_pos;
|
||||||
|
myx = vc->vc_x;
|
||||||
|
+ vc_set_color(vc, current_color);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c != 13)
|
||||||
|
@@ -2498,6 +2536,7 @@ static void vt_console_print(struct cons
|
||||||
|
cr(vc);
|
||||||
|
start = (ushort *)vc->vc_pos;
|
||||||
|
myx = vc->vc_x;
|
||||||
|
+ vc_set_color(vc, current_color);
|
||||||
|
if (c == 10 || c == 13)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@@ -2520,6 +2559,7 @@ static void vt_console_print(struct cons
|
||||||
|
vc->vc_need_wrap = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ vc_set_color(vc, vc->vc_def_color);
|
||||||
|
set_cursor(vc);
|
||||||
|
notify_update(vc);
|
||||||
|
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/drivers/net/netconsole.c linux-2.6.29.3-cprintk/drivers/net/netconsole.c
|
||||||
|
--- a/drivers/net/netconsole.c 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/drivers/net/netconsole.c 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -691,7 +691,8 @@ static struct notifier_block netconsole_
|
||||||
|
.notifier_call = netconsole_netdev_event,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static void write_msg(struct console *con, const char *msg, unsigned int len)
|
||||||
|
+static void write_msg(struct console *con, const char *msg, unsigned int len,
|
||||||
|
+ unsigned int loglevel)
|
||||||
|
{
|
||||||
|
int frag, left;
|
||||||
|
unsigned long flags;
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/drivers/serial/8250.c linux-2.6.29.3-cprintk/drivers/tty/serial/8250.c
|
||||||
|
--- a/drivers/serial/8250.c 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/drivers/tty/serial/8250.c 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -2698,7 +2698,8 @@ static void serial8250_console_putchar(s
|
||||||
|
* The console_lock must be held when we get here.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
-serial8250_console_write(struct console *co, const char *s, unsigned int count)
|
||||||
|
+serial8250_console_write(struct console *co, const char *s, unsigned int count,
|
||||||
|
+ unsigned int loglevel)
|
||||||
|
{
|
||||||
|
struct uart_8250_port *up = &serial8250_ports[co->index];
|
||||||
|
unsigned long flags;
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/drivers/serial/8250_early.c linux-2.6.29.3-cprintk/drivers/tty/serial/8250_early.c
|
||||||
|
--- a/drivers/serial/8250_early.c 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/drivers/tty/serial/8250_early.c 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -83,7 +83,7 @@ static void __init serial_putc(struct ua
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init early_serial8250_write(struct console *console,
|
||||||
|
- const char *s, unsigned int count)
|
||||||
|
+ const char *s, unsigned int count, unsigned int loglevel)
|
||||||
|
{
|
||||||
|
struct uart_port *port = &early_device.port;
|
||||||
|
unsigned int ier;
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/include/linux/console.h linux-2.6.29.3-cprintk/include/linux/console.h
|
||||||
|
--- a/include/linux/console.h 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/include/linux/console.h 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -95,7 +95,7 @@ void give_up_console(const struct consw
|
||||||
|
|
||||||
|
struct console {
|
||||||
|
char name[16];
|
||||||
|
- void (*write)(struct console *, const char *, unsigned);
|
||||||
|
+ void (*write)(struct console *, const char *, unsigned, unsigned int);
|
||||||
|
int (*read)(struct console *, char *, unsigned);
|
||||||
|
struct tty_driver *(*device)(struct console *, int *);
|
||||||
|
void (*unblank)(void);
|
||||||
|
diff -pruN -X linux/Documentation/dontdiff linux-2.6.29.3/kernel/printk.c linux-2.6.29.3-cprintk/kernel/printk.c
|
||||||
|
--- a/kernel/printk.c 2009-03-24 00:12:14.000000000 +0100
|
||||||
|
+++ b/kernel/printk.c 2009-05-09 14:43:48.000000000 +0200
|
||||||
|
@@ -389,7 +389,8 @@ SYSCALL_DEFINE3(syslog, int, type, char
|
||||||
|
/*
|
||||||
|
* Call the console drivers on a range of log_buf
|
||||||
|
*/
|
||||||
|
-static void __call_console_drivers(unsigned start, unsigned end)
|
||||||
|
+static void __call_console_drivers(unsigned start, unsigned end,
|
||||||
|
+ unsigned int loglevel)
|
||||||
|
{
|
||||||
|
struct console *con;
|
||||||
|
|
||||||
|
@@ -397,7 +398,7 @@ static void __call_console_drivers(unsig
|
||||||
|
if ((con->flags & CON_ENABLED) && con->write &&
|
||||||
|
(cpu_online(smp_processor_id()) ||
|
||||||
|
(con->flags & CON_ANYTIME)))
|
||||||
|
- con->write(con, &LOG_BUF(start), end - start);
|
||||||
|
+ con->write(con, &LOG_BUF(start), end - start, loglevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -424,10 +425,11 @@ static void _call_console_drivers(unsign
|
||||||
|
if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
|
||||||
|
/* wrapped write */
|
||||||
|
__call_console_drivers(start & LOG_BUF_MASK,
|
||||||
|
- log_buf_len);
|
||||||
|
- __call_console_drivers(0, end & LOG_BUF_MASK);
|
||||||
|
+ log_buf_len, msg_log_level);
|
||||||
|
+ __call_console_drivers(0, end & LOG_BUF_MASK,
|
||||||
|
+ msg_log_level);
|
||||||
|
} else {
|
||||||
|
- __call_console_drivers(start, end);
|
||||||
|
+ __call_console_drivers(start, end, msg_log_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
3.2.34/hz-432-kconfig-option.patch
Normal file
25
3.2.34/hz-432-kconfig-option.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
diff -urN oldtree/kernel/Kconfig.hz newtree/kernel/Kconfig.hz
|
||||||
|
--- oldtree/kernel/Kconfig.hz 2007-03-06 15:00:55.000000000 -0500
|
||||||
|
+++ newtree/kernel/Kconfig.hz 2007-03-06 17:52:36.000000000 -0500
|
||||||
|
@@ -39,6 +39,14 @@
|
||||||
|
on SMP and NUMA systems and exactly dividing by both PAL and
|
||||||
|
NTSC frame rates for video and multimedia work.
|
||||||
|
|
||||||
|
+ config HZ_432
|
||||||
|
+ bool "432 HZ"
|
||||||
|
+ help
|
||||||
|
+ 432 HZ is the best value for desktop systems. Most responsive
|
||||||
|
+ out of all the options. This is for Dual Core/Processor systems only.
|
||||||
|
+ as timer frequencies * number of processors = actual frequency.
|
||||||
|
+ Try this if you have a dual-core/dual processor system.
|
||||||
|
+
|
||||||
|
config HZ_1000
|
||||||
|
bool "1000 HZ"
|
||||||
|
help
|
||||||
|
@@ -52,5 +60,6 @@
|
||||||
|
default 100 if HZ_100
|
||||||
|
default 250 if HZ_250_NODEFAULT
|
||||||
|
default 300 if HZ_300
|
||||||
|
+ default 432 if HZ_432
|
||||||
|
default 1000 if HZ_1000
|
||||||
|
|
25
3.2.34/hz-864-kconfig-option.patch
Normal file
25
3.2.34/hz-864-kconfig-option.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
diff -urN oldtree/kernel/Kconfig.hz newtree/kernel/Kconfig.hz
|
||||||
|
--- oldtree/kernel/Kconfig.hz 2007-03-06 15:00:55.000000000 -0500
|
||||||
|
+++ newtree/kernel/Kconfig.hz 2007-03-06 17:52:36.000000000 -0500
|
||||||
|
@@ -39,6 +39,14 @@
|
||||||
|
as timer frequencies * number of processors = actual frequency.
|
||||||
|
Try this if you have a dual-core/dual processor system.
|
||||||
|
|
||||||
|
+ config HZ_864
|
||||||
|
+ bool "864 HZ"
|
||||||
|
+ help
|
||||||
|
+ 864 HZ is the best value for desktop systems. Most responsive
|
||||||
|
+ out of all the options. The only reason it is not default is
|
||||||
|
+ because it may break few drivers. Give it a try if you have
|
||||||
|
+ a desktop :).
|
||||||
|
+
|
||||||
|
config HZ_1000
|
||||||
|
bool "1000 HZ"
|
||||||
|
help
|
||||||
|
@@ -52,5 +60,6 @@
|
||||||
|
default 250 if HZ_250_NODEFAULT
|
||||||
|
default 300 if HZ_300
|
||||||
|
default 432 if HZ_432
|
||||||
|
+ default 864 if HZ_864
|
||||||
|
default 1000 if HZ_1000
|
||||||
|
|
1603
3.2.34/imqmq-3.2.patch
Normal file
1603
3.2.34/imqmq-3.2.patch
Normal file
File diff suppressed because it is too large
Load Diff
137
3.2.34/kbuild-compress-kernel-modules-on-installation.patch
Normal file
137
3.2.34/kbuild-compress-kernel-modules-on-installation.patch
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
================================
|
||||||
|
Signed-off-by: Steve Brokenshire <sbrokenshire@xestia.co.uk>
|
||||||
|
[Rediffed for 2.6.31.3, defaulted to y and compress with -9 /Thomas]
|
||||||
|
Signed-off-by: Thomas Backlund <tmb@mandriva.org>
|
||||||
|
|
||||||
|
diff -Nurp linux-2.6.31/Documentation/kbuild/modules.txt linux-2.6.31.compress/Documentation/kbuild/modules.txt
|
||||||
|
--- linux-2.6.31/Documentation/kbuild/modules.txt 2009-09-10 01:13:59.000000000 +0300
|
||||||
|
+++ linux-2.6.31.compress/Documentation/kbuild/modules.txt 2009-10-09 14:17:49.335619817 +0300
|
||||||
|
@@ -123,6 +123,13 @@ executed to make module versioning work.
|
||||||
|
Install the external module(s). The default location is
|
||||||
|
/lib/modules/<kernel_release>/extra/, but a prefix may
|
||||||
|
be added with INSTALL_MOD_PATH (discussed in section 5).
|
||||||
|
+ If MODULES_COMPRESS is set when the modules_install target is
|
||||||
|
+ run then the module is compressed after it has been
|
||||||
|
+ copied to /lib/modules/<kernel-version>. Compressed modules
|
||||||
|
+ using the default gzip compression format will require
|
||||||
|
+ module-init-tools installed with --zlib-enabled.
|
||||||
|
+ Any options set in MODULE_COMPRESS_OPTIONS will be
|
||||||
|
+ passed to the selected compression format.
|
||||||
|
|
||||||
|
clean
|
||||||
|
Remove all generated files in the module directory only.
|
||||||
|
diff -Nurp linux-2.6.31/init/Kconfig linux-2.6.31.compress/init/Kconfig
|
||||||
|
--- linux-2.6.31/init/Kconfig 2009-09-10 01:13:59.000000000 +0300
|
||||||
|
+++ linux-2.6.31.compress/init/Kconfig 2009-10-09 14:19:01.812591181 +0300
|
||||||
|
@@ -1161,6 +1161,64 @@ config MODULE_FORCE_UNLOAD
|
||||||
|
rmmod). This is mainly for kernel developers and desperate users.
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
|
+config MODULE_COMPRESS
|
||||||
|
+ bool "Compress kernel modules on installation"
|
||||||
|
+ depends on MODULES
|
||||||
|
+ default y
|
||||||
|
+ help
|
||||||
|
+ This option compresses the kernel modules when 'make
|
||||||
|
+ modules_install' is run.
|
||||||
|
+
|
||||||
|
+ The modules will be compressed into the selected compression
|
||||||
|
+ format with gzip being the default compression format.
|
||||||
|
+
|
||||||
|
+ When a kernel module is installed from outside of the main kernel
|
||||||
|
+ source and uses the Kbuild system for installing modules then that
|
||||||
|
+ kernel module will also be compressed when it is installed.
|
||||||
|
+
|
||||||
|
+ When running mkinitrd you will find that an error message
|
||||||
|
+ appears saying that it cannot find a certain kernel module.
|
||||||
|
+ As a workaround, unset CONFIG_MODULE_COMPRESS, build the modules
|
||||||
|
+ and install them, run mkinitrd and create the initrd image, place
|
||||||
|
+ the initrd image in the correct place for booting, set
|
||||||
|
+ CONFIG_MODULE_COMPRESS and then install the modules again.
|
||||||
|
+
|
||||||
|
+ This option requires the module-init-tools package to be
|
||||||
|
+ configured with --enable-zlib (if using gzip which is the
|
||||||
|
+ default compression format).
|
||||||
|
+
|
||||||
|
+ If unsure, say Y.
|
||||||
|
+
|
||||||
|
+config MODULE_COMPRESS_OPTIONS
|
||||||
|
+ string "Compression format command line options"
|
||||||
|
+ depends on MODULE_COMPRESS
|
||||||
|
+ default "-9"
|
||||||
|
+ help
|
||||||
|
+ This option specifies the command line options to be used for
|
||||||
|
+ the selected compression format.
|
||||||
|
+
|
||||||
|
+ Please refer to the selected compression format's documentation
|
||||||
|
+ on which options should be used.
|
||||||
|
+
|
||||||
|
+ If unsure, leave this option blank.
|
||||||
|
+
|
||||||
|
+choice
|
||||||
|
+ prompt "Kernel module compression format"
|
||||||
|
+ depends on MODULE_COMPRESS
|
||||||
|
+ default MODULE_COMPRESS_GZIP
|
||||||
|
+
|
||||||
|
+config MODULE_COMPRESS_GZIP
|
||||||
|
+ bool "gzip compression"
|
||||||
|
+ help
|
||||||
|
+ Compresses the kernel modules using the gzip (GNU zip)
|
||||||
|
+ compression format.
|
||||||
|
+
|
||||||
|
+ This option requires gzip to be installed.
|
||||||
|
+
|
||||||
|
+ If unsure, leave this option selected.
|
||||||
|
+
|
||||||
|
+endchoice
|
||||||
|
+
|
||||||
|
config MODVERSIONS
|
||||||
|
bool "Module versioning support"
|
||||||
|
help
|
||||||
|
diff -Nurp linux-2.6.31/scripts/Makefile.modinst linux-2.6.31.compress/scripts/Makefile.modinst
|
||||||
|
--- linux-2.6.31/scripts/Makefile.modinst 2009-09-10 01:13:59.000000000 +0300
|
||||||
|
+++ linux-2.6.31.compress/scripts/Makefile.modinst 2009-10-09 14:17:49.337619404 +0300
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
PHONY := __modinst
|
||||||
|
__modinst:
|
||||||
|
|
||||||
|
+include include/config/auto.conf
|
||||||
|
include scripts/Kbuild.include
|
||||||
|
|
||||||
|
#
|
||||||
|
@@ -16,8 +17,21 @@ PHONY += $(modules)
|
||||||
|
__modinst: $(modules)
|
||||||
|
@:
|
||||||
|
|
||||||
|
-quiet_cmd_modules_install = INSTALL $@
|
||||||
|
- cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@)
|
||||||
|
+ifeq ($(CONFIG_MODULE_COMPRESS_OPTIONS), "")
|
||||||
|
+else
|
||||||
|
+ MODCOMPOPT = $(shell echo -n $(CONFIG_MODULE_COMPRESS_OPTIONS))
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+quiet_cmd_modules_install = INSTALL $@
|
||||||
|
+ cmd_modules_install = mkdir -p $(2); \
|
||||||
|
+ cp $@ $(2) ; \
|
||||||
|
+ $(mod_strip_cmd) $(2)/$(notdir $@)
|
||||||
|
+
|
||||||
|
+quiet_cmd_modules_compress_gzip = COMPRESS $@
|
||||||
|
+ cmd_modules_compress_gzip = gzip $(MODCOMPOPT) -c \
|
||||||
|
+ $(2)/$(@F) \
|
||||||
|
+ > $(2)/$(@F).gz; \
|
||||||
|
+ rm $(2)/$(@F)
|
||||||
|
|
||||||
|
# Modules built outside the kernel source tree go into extra by default
|
||||||
|
INSTALL_MOD_DIR ?= extra
|
||||||
|
@@ -26,8 +40,11 @@ ext-mod-dir = $(INSTALL_MOD_DIR)$(subst
|
||||||
|
modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
|
||||||
|
|
||||||
|
$(modules):
|
||||||
|
+
|
||||||
|
$(call cmd,modules_install,$(MODLIB)/$(modinst_dir))
|
||||||
|
|
||||||
|
+ $(if $(CONFIG_MODULE_COMPRESS_GZIP), \
|
||||||
|
+ $(call cmd,modules_compress_gzip,$(MODLIB)/$(modinst_dir)))
|
||||||
|
|
||||||
|
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||||
|
# information in a variable se we can use it in if_changed and friends.
|
569
3.2.34/kernel-3.2-lsproduo.patch
Normal file
569
3.2.34/kernel-3.2-lsproduo.patch
Normal file
@ -0,0 +1,569 @@
|
|||||||
|
diff -uprN linux-3.4-rc7/arch/arm/configs/orion5x_defconfig linux-3.4-rc7-wtgl/arch/arm/configs/orion5x_defconfig
|
||||||
|
--- linux-3.4-rc7/arch/arm/configs/orion5x_defconfig 2012-05-12 19:37:47.000000000 -0600
|
||||||
|
+++ linux-3.4-rc7-wtgl/arch/arm/configs/orion5x_defconfig 2012-08-16 23:41:47.118502384 -0600
|
||||||
|
@@ -19,6 +19,7 @@ CONFIG_MACH_TS209=y
|
||||||
|
CONFIG_MACH_TERASTATION_PRO2=y
|
||||||
|
CONFIG_MACH_LINKSTATION_PRO=y
|
||||||
|
CONFIG_MACH_LINKSTATION_MINI=y
|
||||||
|
+CONFIG_MACH_LINKSTATION_PRODUO=y
|
||||||
|
CONFIG_MACH_LINKSTATION_LS_HGL=y
|
||||||
|
CONFIG_MACH_TS409=y
|
||||||
|
CONFIG_MACH_WRT350N_V2=y
|
||||||
|
diff -uprN linux-3.4-rc7/arch/arm/mach-orion5x/Kconfig linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/Kconfig
|
||||||
|
--- linux-3.4-rc7/arch/arm/mach-orion5x/Kconfig 2012-05-12 19:37:47.000000000 -0600
|
||||||
|
+++ linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/Kconfig 2012-08-16 23:47:02.334496150 -0600
|
||||||
|
@@ -65,13 +65,52 @@ config MACH_LINKSTATION_MINI
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Buffalo Linkstation Mini platform.
|
||||||
|
|
||||||
|
+config MACH_LINKSTATION_PRODUO
|
||||||
|
+ bool "Buffalo Linkstation Pro Duo"
|
||||||
|
+ select I2C_BOARDINFO
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the
|
||||||
|
+ Buffalo Linkstation Pro Duo platform.
|
||||||
|
+
|
||||||
|
+ LS-W1.0TGL/R1 is the general model number. There
|
||||||
|
+ is no /R3 models, as /R1 stands for RAID1.
|
||||||
|
+ There are two hardware revisions of the product.
|
||||||
|
+
|
||||||
|
+ The first revision has version 1.xx firmware, 64 MB RAM,
|
||||||
|
+ a single USB port, a power BUTTON, an Auto/Manual
|
||||||
|
+ power MODE SWITCH, and a RESET button.
|
||||||
|
+
|
||||||
|
+ The second revision has version 3.xx firmware, 128 MB RAM,
|
||||||
|
+ two USB ports, an Off/On/Auto power SWITCH, and a FUNCTION button.
|
||||||
|
+
|
||||||
|
+ choice
|
||||||
|
+ prompt "HW model"
|
||||||
|
+ depends on MACH_LINKSTATION_PRODUO
|
||||||
|
+ default MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+ default MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+
|
||||||
|
+ config MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+ bool "Revision 1"
|
||||||
|
+ help
|
||||||
|
+ The first revision has version 1.xx firmware, 64 MB RAM,
|
||||||
|
+ a single USB port, a power BUTTON, an Auto/Manual
|
||||||
|
+ power MODE SWITCH, and a RESET button.
|
||||||
|
+
|
||||||
|
+ config MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+ bool "Revision 2"
|
||||||
|
+ help
|
||||||
|
+ The second revision has version 3.xx firmware, 128 MB RAM,
|
||||||
|
+ two USB ports, an Off/On/Auto power SWITCH, and a FUNCTION button.
|
||||||
|
+ endchoice
|
||||||
|
+
|
||||||
|
+
|
||||||
|
config MACH_LINKSTATION_LS_HGL
|
||||||
|
bool "Buffalo Linkstation LS-HGL"
|
||||||
|
select I2C_BOARDINFO
|
||||||
|
help
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Buffalo Linkstation LS-HGL platform.
|
||||||
|
-
|
||||||
|
+
|
||||||
|
config MACH_TS409
|
||||||
|
bool "QNAP TS-409"
|
||||||
|
help
|
||||||
|
diff -uprN linux-3.4-rc7/arch/arm/mach-orion5x/Makefile linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/Makefile
|
||||||
|
--- linux-3.4-rc7/arch/arm/mach-orion5x/Makefile 2012-05-12 19:37:47.000000000 -0600
|
||||||
|
+++ linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/Makefile 2012-08-16 23:48:26.182494492 -0600
|
||||||
|
@@ -5,6 +5,7 @@ obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobo
|
||||||
|
obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_LINKSTATION_PRODUO) += lsproduo-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_LS_HGL) += ls_hgl-setup.o
|
||||||
|
obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
|
||||||
|
obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
|
||||||
|
diff -uprN linux-3.4-rc7/arch/arm/mach-orion5x/lsproduo-setup.c linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/lsproduo-setup.c
|
||||||
|
--- linux-3.4-rc7/arch/arm/mach-orion5x/lsproduo-setup.c 1969-12-31 17:00:00.000000000 -0700
|
||||||
|
+++ linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/lsproduo-setup.c 2012-08-16 23:52:09.630490073 -0600
|
||||||
|
@@ -0,0 +1,459 @@
|
||||||
|
+/*
|
||||||
|
+ * arch/arm/mach-orion5x/lsproduo-setup.c
|
||||||
|
+ *
|
||||||
|
+ * Source taken from arch/arm/mach-orion5x/lsmini-setup.c - kernel 2.6.30
|
||||||
|
+ * Maintainer: Matt Gomboc <gomboc0@gmail.com>
|
||||||
|
+ *
|
||||||
|
+ * This file is licensed under the terms of the GNU General Public
|
||||||
|
+ * License version 2. This program is licensed "as is" without any
|
||||||
|
+ * warranty of any kind, whether express or implied.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/mv643xx_eth.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/i2c.h>
|
||||||
|
+#include <linux/ata_platform.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+#include <asm/mach/arch.h>
|
||||||
|
+#include <mach/orion5x.h>
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "mpp.h"
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/proc_fs.h>
|
||||||
|
+#include <asm/uaccess.h>
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Linkstation Pro Duo Info
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 256K NOR flash Device bus boot chip select
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#define LSPRODUO_NOR_BOOT_BASE 0xf4000000
|
||||||
|
+#define LSPRODUO_NOR_BOOT_SIZE SZ_256K
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 256KB NOR Flash on BOOT Device
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static struct physmap_flash_data lsproduo_nor_flash_data = {
|
||||||
|
+ .width = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct resource lsproduo_nor_flash_resource = {
|
||||||
|
+ .flags = IORESOURCE_MEM,
|
||||||
|
+ .start = LSPRODUO_NOR_BOOT_BASE,
|
||||||
|
+ .end = LSPRODUO_NOR_BOOT_BASE + LSPRODUO_NOR_BOOT_SIZE - 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsproduo_nor_flash = {
|
||||||
|
+ .name = "physmap-flash",
|
||||||
|
+ .id = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsproduo_nor_flash_data,
|
||||||
|
+ },
|
||||||
|
+ .num_resources = 1,
|
||||||
|
+ .resource = &lsproduo_nor_flash_resource,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Ethernet
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static struct mv643xx_eth_platform_data lsproduo_eth_data = {
|
||||||
|
+ .phy_addr = 8,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * RTC 5C372a on I2C bus
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static struct i2c_board_info __initdata lsproduo_i2c_rtc = {
|
||||||
|
+ I2C_BOARD_INFO("rs5c372a", 0x32),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LEDs attached to GPIO
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+#define LSPRODUO_GPIO_LED_ALARM 2
|
||||||
|
+#define LSPRODUO_GPIO_LED_INFO 3
|
||||||
|
+#define LSPRODUO_GPIO_LED_PWR 0
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+ #define LSPRODUO_GPIO_LED_FUNC 18
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+static struct gpio_led lsproduo_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "alarm:red",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_ALARM,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "info:amber",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_INFO,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "power:greem",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_PWR,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+static struct gpio_led lsproduo_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "alarm:red",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_ALARM,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "info:amber",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_INFO,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "power:green",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_PWR,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },{
|
||||||
|
+ .name = "func:blue",
|
||||||
|
+ .gpio = LSPRODUO_GPIO_LED_FUNC,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct gpio_led_platform_data lsproduo_led_data = {
|
||||||
|
+ .leds = lsproduo_led_pins,
|
||||||
|
+ .num_leds = ARRAY_SIZE(lsproduo_led_pins),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsproduo_leds = {
|
||||||
|
+ .name = "leds-gpio",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsproduo_led_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/****************************************************************************
|
||||||
|
+ * GPIO Attached Keys
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+ #define LSPRODUO_GPIO_KEY_POWER 8
|
||||||
|
+ #define LSPRODUO_GPIO_KEY_AUTOPOWER 10
|
||||||
|
+
|
||||||
|
+ #define LSPRODUO_SW_POWER 0x00
|
||||||
|
+ #define LSPRODUO_SW_AUTOPOWER 0x01
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lsproduo_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSPRODUO_SW_POWER,
|
||||||
|
+ .gpio = LSPRODUO_GPIO_KEY_POWER,
|
||||||
|
+ .desc = "Power-on Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSPRODUO_SW_AUTOPOWER,
|
||||||
|
+ .gpio = LSPRODUO_GPIO_KEY_AUTOPOWER,
|
||||||
|
+ .desc = "Power-auto Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+ #define LSPRODUO_GPIO_KEY_POWER 10
|
||||||
|
+ #define LSPRODUO_GPIO_KEY_AUTOPOWER 22
|
||||||
|
+ #define LSPRODUO_GPIO_KEY_FUNC 8
|
||||||
|
+
|
||||||
|
+ #define LSPRODUO_SW_POWER 0x00
|
||||||
|
+ #define LSPRODUO_SW_AUTOPOWER 0x01
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lsproduo_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .code = KEY_OPTION,
|
||||||
|
+ .gpio = LSPRODUO_GPIO_KEY_FUNC,
|
||||||
|
+ .desc = "Function Button",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },{
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSPRODUO_SW_POWER,
|
||||||
|
+ .gpio = LSPRODUO_GPIO_KEY_POWER,
|
||||||
|
+ .desc = "Power-on Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSPRODUO_SW_AUTOPOWER,
|
||||||
|
+ .gpio = LSPRODUO_GPIO_KEY_AUTOPOWER,
|
||||||
|
+ .desc = "Power-auto Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_platform_data lsproduo_button_data = {
|
||||||
|
+ .buttons = lsproduo_buttons,
|
||||||
|
+ .nbuttons = ARRAY_SIZE(lsproduo_buttons),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsproduo_button_device = {
|
||||||
|
+ .name = "gpio-keys",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsproduo_button_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/****************************************************************************
|
||||||
|
+ * GPIO Attached Fan
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+/* Define max char len */
|
||||||
|
+#define MAX_LEN 8
|
||||||
|
+
|
||||||
|
+#define LSPRODUO_GPIO_FAN_LOW 17
|
||||||
|
+#define LSPRODUO_GPIO_FAN_HIGH 14
|
||||||
|
+
|
||||||
|
+static struct proc_dir_entry *lsproduo_proc_dir_root, *lsproduo_proc_dir_gpio, *lsproduo_fan_proc_file;
|
||||||
|
+static char lsproduo_fan_state[MAX_LEN];
|
||||||
|
+
|
||||||
|
+static int lsproduo_fan_get(char *buf, char **start, off_t offset, int count, int *eof, void *data)
|
||||||
|
+{
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ len = snprintf(buf, count, "state: %s\n", lsproduo_fan_state);
|
||||||
|
+ return len;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int lsproduo_fan_set( struct file *file, const char *buffer, unsigned long count, void *data )
|
||||||
|
+{
|
||||||
|
+ int len, ret;
|
||||||
|
+ char *ptr, tState[MAX_LEN];
|
||||||
|
+
|
||||||
|
+ if (count > MAX_LEN )
|
||||||
|
+ len = MAX_LEN;
|
||||||
|
+ else
|
||||||
|
+ len = count;
|
||||||
|
+
|
||||||
|
+ ret = copy_from_user(tState, buffer, len);
|
||||||
|
+ if(ret < 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_ERR "%s: Setting fan speed failed\n", "lsproduo");
|
||||||
|
+ return -EFAULT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ptr = strrchr(tState, '\n');
|
||||||
|
+ if(ptr) *ptr = '\0';
|
||||||
|
+
|
||||||
|
+ if (strcasecmp(tState, "off") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan off\n", "lsproduo");
|
||||||
|
+ sprintf(lsproduo_fan_state, "off");
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_LOW, 1);
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_HIGH, 1);
|
||||||
|
+ } else if (strcasecmp(tState, "slow") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan slow\n", "lsproduo");
|
||||||
|
+ sprintf(lsproduo_fan_state, "slow");
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_LOW, 1);
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_HIGH, 0);
|
||||||
|
+ } else if (strcasecmp(tState, "fast") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan fast\n", "lsproduo");
|
||||||
|
+ sprintf(lsproduo_fan_state, "fast");
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_LOW, 0);
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_HIGH, 1);
|
||||||
|
+ } else if (strcasecmp(tState, "full") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan full\n", "lsproduo");
|
||||||
|
+ sprintf(lsproduo_fan_state, "full");
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_LOW, 0);
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_HIGH, 0);
|
||||||
|
+ } else
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_ERR "%s: unknown fan speed given\n", "lsproduo");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ lsproduo_fan_state[len] = '\0';
|
||||||
|
+
|
||||||
|
+ return len;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * SATA
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv_sata_platform_data lsproduo_sata_data = {
|
||||||
|
+ .n_ports = 2,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Linkstation Pro Duo specific power off method: reboot
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * On the Linkstation Pro Duo, the shutdown process is following:
|
||||||
|
+ * - Userland monitors key events until the power switch goes to off position
|
||||||
|
+ * - The board reboots
|
||||||
|
+ * - U-boot starts and goes into an idle mode waiting for the user
|
||||||
|
+ * to move the switch to ON position
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void lsproduo_power_off(void)
|
||||||
|
+{
|
||||||
|
+ /* orion5x_restart('h', NULL); */
|
||||||
|
+ arm_machine_restart(0, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * General Setup
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSPRODUO_GPIO_HDD_POWER0 1
|
||||||
|
+#define LSPRODUO_GPIO_USB_POWER 9
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+ #define LSPRODUO_GPIO_POWER 8
|
||||||
|
+ #define LSPRODUO_GPIO_AUTO_POWER 10
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+ #define LSPRODUO_GPIO_POWER 10
|
||||||
|
+ #define LSPRODUO_GPIO_USB_POWER2 19
|
||||||
|
+ #define LSPRODUO_GPIO_AUTO_POWER 22
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static unsigned int lsproduo_mpp_modes[] __initdata = {
|
||||||
|
+ MPP0_GPIO, /* LED_PWR */
|
||||||
|
+ MPP1_GPIO, /* HDD_PWR */
|
||||||
|
+ MPP2_GPIO, /* LED_ALARM */
|
||||||
|
+ MPP3_GPIO, /* LED_INFO */
|
||||||
|
+ MPP4_UNUSED,
|
||||||
|
+ MPP5_UNUSED,
|
||||||
|
+ MPP6_GPIO, /* FAN_LCK */
|
||||||
|
+ MPP9_GPIO, /* USB_PWR */
|
||||||
|
+ MPP11_UNUSED, /* LED_ETH dummy */
|
||||||
|
+ MPP12_UNUSED,
|
||||||
|
+ MPP13_UNUSED,
|
||||||
|
+ MPP14_GPIO, /* FAN_HIGH */
|
||||||
|
+ MPP15_UNUSED,
|
||||||
|
+ MPP16_UNUSED,
|
||||||
|
+ MPP17_GPIO, /* FAN_LOW */
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+ MPP7_GPIO, /* INIT */
|
||||||
|
+ MPP8_GPIO, /* POWER */
|
||||||
|
+ MPP10_GPIO, /* AUTO_POWER */
|
||||||
|
+ MPP18_UNUSED,
|
||||||
|
+ MPP19_UNUSED,
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+ MPP7_UNUSED,
|
||||||
|
+ MPP8_GPIO, /* FUNC */
|
||||||
|
+ MPP10_GPIO, /* POWER */
|
||||||
|
+ MPP18_GPIO, /* LED_FUNC*/
|
||||||
|
+ MPP19_GPIO, /* USB_PWR2 */
|
||||||
|
+ MPP22_GPIO, /* AUTO_POWER */
|
||||||
|
+#endif
|
||||||
|
+ 0,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void __init lsproduo_init(void)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Setup basic Orion functions. Need to be called early.
|
||||||
|
+ */
|
||||||
|
+ orion5x_init();
|
||||||
|
+
|
||||||
|
+ orion5x_mpp_conf(lsproduo_mpp_modes);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Configure peripherals.
|
||||||
|
+ */
|
||||||
|
+ orion5x_ehci0_init();
|
||||||
|
+ orion5x_ehci1_init();
|
||||||
|
+ orion5x_eth_init(&lsproduo_eth_data);
|
||||||
|
+ orion5x_i2c_init();
|
||||||
|
+ orion5x_sata_init(&lsproduo_sata_data);
|
||||||
|
+ orion5x_uart0_init();
|
||||||
|
+ orion5x_xor_init();
|
||||||
|
+
|
||||||
|
+ orion5x_setup_dev_boot_win(LSPRODUO_NOR_BOOT_BASE,
|
||||||
|
+ LSPRODUO_NOR_BOOT_SIZE);
|
||||||
|
+ platform_device_register(&lsproduo_nor_flash);
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lsproduo_button_device);
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lsproduo_leds);
|
||||||
|
+
|
||||||
|
+ i2c_register_board_info(0, &lsproduo_i2c_rtc, 1);
|
||||||
|
+
|
||||||
|
+ /* enable USB power */
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_USB_POWER, 1);
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_USB_POWER2, 1);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ printk(KERN_INFO "Buffalo Linkstation Pro Duo fan driver loaded\n");
|
||||||
|
+ sprintf(lsproduo_fan_state, "fast");
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_LOW, 1);
|
||||||
|
+ gpio_set_value(LSPRODUO_GPIO_FAN_HIGH, 0);
|
||||||
|
+
|
||||||
|
+ lsproduo_proc_dir_root = proc_mkdir( "linkstation", NULL );
|
||||||
|
+ lsproduo_proc_dir_gpio = proc_mkdir( "gpio", lsproduo_proc_dir_root );
|
||||||
|
+ lsproduo_fan_proc_file = create_proc_entry( "fan", S_IRUGO, lsproduo_proc_dir_gpio );
|
||||||
|
+ if( lsproduo_fan_proc_file ) {
|
||||||
|
+ lsproduo_fan_proc_file->read_proc = lsproduo_fan_get;
|
||||||
|
+ lsproduo_fan_proc_file->write_proc = lsproduo_fan_set;
|
||||||
|
+ lsproduo_fan_proc_file->data = NULL;
|
||||||
|
+ } else
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_INFO "Registration of fan device failed\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* register power-off method */
|
||||||
|
+ pm_power_off = lsproduo_power_off;
|
||||||
|
+
|
||||||
|
+ pr_info("%s: finished\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV1
|
||||||
|
+MACHINE_START(LINKSTATION_PRODUO, "Buffalo Linkstation Pro Duo - Revision 1")
|
||||||
|
+ .atag_offset = 0x00000100,
|
||||||
|
+ .init_machine = lsproduo_init,
|
||||||
|
+ .map_io = orion5x_map_io,
|
||||||
|
+ .init_early = orion5x_init_early,
|
||||||
|
+ .init_irq = orion5x_init_irq,
|
||||||
|
+ .timer = &orion5x_timer,
|
||||||
|
+ .fixup = tag_fixup_mem32,
|
||||||
|
+ /* .restart = orion5x_restart, */
|
||||||
|
+MACHINE_END
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_PRODUO_REV2
|
||||||
|
+MACHINE_START(LINKSTATION_PRODUO, "Buffalo Linkstation Pro Duo - Revision 2")
|
||||||
|
+ .atag_offset = 0x00000100,
|
||||||
|
+ .init_machine = lsproduo_init,
|
||||||
|
+ .map_io = orion5x_map_io,
|
||||||
|
+ .init_early = orion5x_init_early,
|
||||||
|
+ .init_irq = orion5x_init_irq,
|
||||||
|
+ .timer = &orion5x_timer,
|
||||||
|
+ .fixup = tag_fixup_mem32,
|
||||||
|
+ /* .restart = orion5x_restart, */
|
||||||
|
+MACHINE_END
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
diff -uprN linux-3.4-rc7/arch/arm/mach-orion5x/mpp.h linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/mpp.h
|
||||||
|
--- linux-3.4-rc7/arch/arm/mach-orion5x/mpp.h 2012-05-12 19:37:47.000000000 -0600
|
||||||
|
+++ linux-3.4-rc7-wtgl/arch/arm/mach-orion5x/mpp.h 2012-08-16 22:15:34.000000000 -0600
|
||||||
|
@@ -122,7 +122,10 @@
|
||||||
|
#define MPP19_GIGE MPP(19, 0x1, 0, 0, 1, 1, 1)
|
||||||
|
#define MPP19_UART MPP(19, 0x0, 0, 0, 0, 1, 1)
|
||||||
|
|
||||||
|
-#define MPP_MAX 19
|
||||||
|
+#define MPP22_GPIO MPP(22, 0x5, 1, 1, 0, 1, 0)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#define MPP_MAX 22
|
||||||
|
|
||||||
|
void orion5x_mpp_conf(unsigned int *mpp_list);
|
||||||
|
|
||||||
|
diff -uprN linux-3.4-rc7/arch/arm/tools/mach-types linux-3.4-rc7-wtgl/arch/arm/tools/mach-types
|
||||||
|
--- linux-3.4-rc7/arch/arm/tools/mach-types 2012-05-12 19:37:47.000000000 -0600
|
||||||
|
+++ linux-3.4-rc7-wtgl/arch/arm/tools/mach-types 2012-08-16 23:43:59.830499760 -0600
|
||||||
|
@@ -333,6 +333,8 @@ smdkc100 MACH_SMDKC100 SMDKC100 1826
|
||||||
|
tavorevb MACH_TAVOREVB TAVOREVB 1827
|
||||||
|
saar MACH_SAAR SAAR 1828
|
||||||
|
at91sam9m10g45ek MACH_AT91SAM9M10G45EK AT91SAM9M10G45EK 1830
|
||||||
|
+linkstation_produo MACH_LINKSTATION_PRODUO LINKSTATION_PRODUO 1831
|
||||||
|
+##see header for btaining a new version, preferred to patching
|
||||||
|
usb_a9g20 MACH_USB_A9G20 USB_A9G20 1841
|
||||||
|
mxlads MACH_MXLADS MXLADS 1851
|
||||||
|
linkstation_mini MACH_LINKSTATION_MINI LINKSTATION_MINI 1858
|
439
3.2.34/kernel-3.2-lsql.patch
Normal file
439
3.2.34/kernel-3.2-lsql.patch
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/configs/orion5x_defconfig linux-3.2.33-go/arch/arm/configs/orion5x_defconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/configs/orion5x_defconfig 2012-11-11 15:13:23.313493927 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/configs/orion5x_defconfig 2012-11-11 15:14:01.321037277 +0100
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
CONFIG_MACH_LINKSTATION_MINI=y
|
||||||
|
CONFIG_MACH_LINKSTATION_PRODUO=y
|
||||||
|
CONFIG_MACH_LINKSTATION_LS_HGL=y
|
||||||
|
+CONFIG_MACH_LINKSTATION_LSQL=y
|
||||||
|
CONFIG_MACH_TS409=y
|
||||||
|
CONFIG_MACH_WRT350N_V2=y
|
||||||
|
CONFIG_MACH_TS78XX=y
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/mach-orion5x/Kconfig linux-3.2.33-go/arch/arm/mach-orion5x/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/mach-orion5x/Kconfig 2012-11-11 15:13:23.518491566 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/mach-orion5x/Kconfig 2012-11-11 15:14:01.321037277 +0100
|
||||||
|
@@ -111,6 +111,13 @@
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Buffalo Linkstation LS-HGL platform.
|
||||||
|
|
||||||
|
+config MACH_LINKSTATION_LSQL
|
||||||
|
+ bool "Buffalo Linkstation LS-QL"
|
||||||
|
+ select I2C_BOARDINFO
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the
|
||||||
|
+ Buffalo Linkstation LS-QL platform.
|
||||||
|
+
|
||||||
|
config MACH_TS409
|
||||||
|
bool "QNAP TS-409"
|
||||||
|
help
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/mach-orion5x/lsql-setup.c linux-3.2.33-go/arch/arm/mach-orion5x/lsql-setup.c
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/mach-orion5x/lsql-setup.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/mach-orion5x/lsql-setup.c 2012-11-11 15:14:01.323037254 +0100
|
||||||
|
@@ -0,0 +1,388 @@
|
||||||
|
+/*
|
||||||
|
+ * arch/arm/mach-orion5x/lsql-setup.c
|
||||||
|
+ *
|
||||||
|
+ * Source based off arch/arm/mach-orion5x/lsproduo-setup.c, which was from lsmini-setup.c
|
||||||
|
+ * Maintainer: Matt Gomboc <gomboc0@gmail.com>
|
||||||
|
+ *
|
||||||
|
+ * This file is licensed under the terms of the GNU General Public
|
||||||
|
+ * License version 2. This program is licensed "as is" without any
|
||||||
|
+ * warranty of any kind, whether express or implied.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/mv643xx_eth.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/i2c.h>
|
||||||
|
+#include <linux/ata_platform.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+#include <asm/mach/arch.h>
|
||||||
|
+#include <mach/orion5x.h>
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "mpp.h"
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/proc_fs.h>
|
||||||
|
+#include <asm/uaccess.h>
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Linkstation Quad LS-QL/R5 Info
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 256K NOR flash Device bus boot chip select
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#define LSQL_NOR_BOOT_BASE 0xf4000000
|
||||||
|
+#define LSQL_NOR_BOOT_SIZE SZ_256K
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 256KB NOR Flash on BOOT Device
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static struct physmap_flash_data lsql_nor_flash_data = {
|
||||||
|
+ .width = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct resource lsql_nor_flash_resource = {
|
||||||
|
+ .flags = IORESOURCE_MEM,
|
||||||
|
+ .start = LSQL_NOR_BOOT_BASE,
|
||||||
|
+ .end = LSQL_NOR_BOOT_BASE + LSQL_NOR_BOOT_SIZE - 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsql_nor_flash = {
|
||||||
|
+ .name = "physmap-flash",
|
||||||
|
+ .id = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsql_nor_flash_data,
|
||||||
|
+ },
|
||||||
|
+ .num_resources = 1,
|
||||||
|
+ .resource = &lsql_nor_flash_resource,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Ethernet
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static struct mv643xx_eth_platform_data lsql_eth_data = {
|
||||||
|
+ .phy_addr = 8,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * RTC 5C372a on I2C bus
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static struct i2c_board_info __initdata lsql_i2c_rtc = {
|
||||||
|
+ I2C_BOARD_INFO("rs5c372a", 0x32),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LEDs attached to GPIO
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+#define LSQL_GPIO_LED_ALARM 2 /* looks like it should be 2 by the uboot sources, but doesnt successfully trigger the3 top LED*/
|
||||||
|
+#define LSQL_GPIO_LED_INFO 3
|
||||||
|
+#define LSQL_GPIO_LED_PWR 0
|
||||||
|
+#define LSQL_GPIO_LED_FUNC 18
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct gpio_led lsql_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "alarm:red",
|
||||||
|
+ .gpio = LSQL_GPIO_LED_ALARM,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "info:amber",
|
||||||
|
+ .gpio = LSQL_GPIO_LED_INFO,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "power:blue",
|
||||||
|
+ .gpio = LSQL_GPIO_LED_PWR,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },{
|
||||||
|
+ .name = "func:blue",
|
||||||
|
+ .gpio = LSQL_GPIO_LED_FUNC,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct gpio_led_platform_data lsql_led_data = {
|
||||||
|
+ .leds = lsql_led_pins,
|
||||||
|
+ .num_leds = ARRAY_SIZE(lsql_led_pins),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct platform_device lsql_leds = {
|
||||||
|
+ .name = "leds-gpio",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsql_led_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/****************************************************************************
|
||||||
|
+ * GPIO Attached Keys
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+ #define LSQL_GPIO_KEY_POWER 10
|
||||||
|
+ #define LSQL_GPIO_KEY_AUTOPOWER 22
|
||||||
|
+ #define LSQL_GPIO_KEY_FUNC 7
|
||||||
|
+
|
||||||
|
+ #define LSQL_SW_POWER 0x00
|
||||||
|
+ #define LSQL_SW_AUTOPOWER 0x01
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lsql_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .code = KEY_OPTION,
|
||||||
|
+ .gpio = LSQL_GPIO_KEY_FUNC,
|
||||||
|
+ .desc = "Function Button",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },{
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSQL_SW_POWER,
|
||||||
|
+ .gpio = LSQL_GPIO_KEY_POWER,
|
||||||
|
+ .desc = "Power-on Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSQL_SW_AUTOPOWER,
|
||||||
|
+ .gpio = LSQL_GPIO_KEY_AUTOPOWER,
|
||||||
|
+ .desc = "Power-auto Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_platform_data lsql_button_data = {
|
||||||
|
+ .buttons = lsql_buttons,
|
||||||
|
+ .nbuttons = ARRAY_SIZE(lsql_buttons),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsql_button_device = {
|
||||||
|
+ .name = "gpio-keys",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsql_button_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/****************************************************************************
|
||||||
|
+ * GPIO Attached Fan
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+/* Define max char len */
|
||||||
|
+
|
||||||
|
+#define MAX_LEN 8
|
||||||
|
+
|
||||||
|
+#define LSQL_GPIO_FAN_LOW 17
|
||||||
|
+#define LSQL_GPIO_FAN_HIGH 14
|
||||||
|
+
|
||||||
|
+static struct proc_dir_entry *lsql_proc_dir_root, *lsql_proc_dir_gpio, *lsql_fan_proc_file;
|
||||||
|
+static char lsql_fan_state[MAX_LEN];
|
||||||
|
+
|
||||||
|
+static int lsql_fan_get(char *buf, char **start, off_t offset, int count, int *eof, void *data)
|
||||||
|
+{
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ len = snprintf(buf, count, "state: %s\n", lsql_fan_state);
|
||||||
|
+ return len;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int lsql_fan_set( struct file *file, const char *buffer, unsigned long count, void *data )
|
||||||
|
+{
|
||||||
|
+ int len, ret;
|
||||||
|
+ char *ptr, tState[MAX_LEN];
|
||||||
|
+
|
||||||
|
+ if (count > MAX_LEN )
|
||||||
|
+ len = MAX_LEN;
|
||||||
|
+ else
|
||||||
|
+ len = count;
|
||||||
|
+
|
||||||
|
+ ret = copy_from_user(tState, buffer, len);
|
||||||
|
+ if(ret < 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_ERR "%s: Setting fan speed failed\n", "lsql");
|
||||||
|
+ return -EFAULT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ptr = strrchr(tState, '\n');
|
||||||
|
+ if(ptr) *ptr = '\0';
|
||||||
|
+
|
||||||
|
+ if (strcasecmp(tState, "off") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan off\n", "lsql");
|
||||||
|
+ sprintf(lsql_fan_state, "off");
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_LOW, 1);
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_HIGH, 1);
|
||||||
|
+ } else if (strcasecmp(tState, "slow") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan slow\n", "lsql");
|
||||||
|
+ sprintf(lsql_fan_state, "slow");
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_LOW, 1);
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_HIGH, 0);
|
||||||
|
+ } else if (strcasecmp(tState, "fast") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan fast\n", "lsql");
|
||||||
|
+ sprintf(lsql_fan_state, "fast");
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_LOW, 0);
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_HIGH, 1);
|
||||||
|
+ } else if (strcasecmp(tState, "full") == 0)
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_DEBUG "%s: set fan full\n", "lsql");
|
||||||
|
+ sprintf(lsql_fan_state, "full");
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_LOW, 0);
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_HIGH, 0);
|
||||||
|
+ } else
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_ERR "%s: unknown fan speed given\n", "lsql");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ lsql_fan_state[len] = '\0';
|
||||||
|
+
|
||||||
|
+ return len;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * SATA
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv_sata_platform_data lsql_sata_data = {
|
||||||
|
+ .n_ports = 2, /*maybe this should be 4, but works with 2 */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Linkstation Quad specific power off method: reboot
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * On Linkstations in general, the shutdown process is following:
|
||||||
|
+ * - Userland monitors key events until the power switch goes to off position
|
||||||
|
+ * - The board reboots
|
||||||
|
+ * - U-boot starts and goes into an idle mode waiting for the user
|
||||||
|
+ * to move the switch to ON position
|
||||||
|
+ *
|
||||||
|
+ * on the Quad however, there is a power button on the upper, front,
|
||||||
|
+ * a function button on the lower front, ans a Auto/Manual power button on the back.
|
||||||
|
+ * After halting system, uboot waits the power button on the front panel to be pushed
|
||||||
|
+ *
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void lsql_power_off(void)
|
||||||
|
+{
|
||||||
|
+ arm_machine_restart(0, NULL); /* orion5x_restart('h', NULL); */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * General Setup
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSQL_GPIO_USB_POWER 9
|
||||||
|
+#define LSQL_GPIO_POWER 10
|
||||||
|
+#define LSQL_GPIO_USB_POWER2 19
|
||||||
|
+#define LSQL_GPIO_AUTO_POWER 22
|
||||||
|
+
|
||||||
|
+static unsigned int lsql_mpp_modes[] __initdata = {
|
||||||
|
+ MPP0_GPIO, /* LED_PWR */
|
||||||
|
+ MPP1_GPIO, /* for debugging purposes, change to MPP1_UNUSED for final */
|
||||||
|
+ MPP2_GPIO, /* LED_ALARM */ /* looks like it should be 2 by the uboot sources, but doesnt successfully trigger the3 top LED*/
|
||||||
|
+ MPP3_GPIO, /* LED_INFO */
|
||||||
|
+ MPP4_GPIO,
|
||||||
|
+ MPP5_GPIO,
|
||||||
|
+ MPP6_GPIO, /* FAN_LCK */
|
||||||
|
+ MPP7_GPIO, /* FUNC */
|
||||||
|
+ MPP8_GPIO,
|
||||||
|
+ MPP9_GPIO, /* USB_PWR */
|
||||||
|
+ MPP10_GPIO, /* POWER */
|
||||||
|
+ MPP11_GPIO,
|
||||||
|
+ MPP12_GPIO,
|
||||||
|
+ MPP13_GPIO,
|
||||||
|
+ MPP14_GPIO, /* FAN_HIGH */
|
||||||
|
+ MPP15_GPIO,
|
||||||
|
+ MPP16_GPIO,
|
||||||
|
+ MPP17_GPIO, /* FAN_LOW */
|
||||||
|
+ MPP18_GPIO, /* LED_FUNC*/
|
||||||
|
+ MPP19_GPIO, /* USB_PWR2 */
|
||||||
|
+ MPP22_GPIO, /* AUTO_POWER*/
|
||||||
|
+ 0,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void __init lsql_init(void)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Setup basic Orion functions. Need to be called early.
|
||||||
|
+ */
|
||||||
|
+ orion5x_init();
|
||||||
|
+
|
||||||
|
+ orion5x_mpp_conf(lsql_mpp_modes);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Configure peripherals.
|
||||||
|
+ */
|
||||||
|
+ orion5x_ehci0_init();
|
||||||
|
+ orion5x_ehci1_init();
|
||||||
|
+ orion5x_eth_init(&lsql_eth_data);
|
||||||
|
+ orion5x_i2c_init();
|
||||||
|
+ orion5x_sata_init(&lsql_sata_data);
|
||||||
|
+ orion5x_uart0_init();
|
||||||
|
+ orion5x_xor_init();
|
||||||
|
+
|
||||||
|
+ orion5x_setup_dev_boot_win(LSQL_NOR_BOOT_BASE,
|
||||||
|
+ LSQL_NOR_BOOT_SIZE);
|
||||||
|
+ platform_device_register(&lsql_nor_flash);
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lsql_button_device);
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lsql_leds);
|
||||||
|
+
|
||||||
|
+ i2c_register_board_info(0, &lsql_i2c_rtc, 1);
|
||||||
|
+
|
||||||
|
+ /* enable USB power */
|
||||||
|
+ gpio_set_value(LSQL_GPIO_USB_POWER, 1);
|
||||||
|
+ gpio_set_value(LSQL_GPIO_USB_POWER2, 1);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ printk(KERN_INFO "Buffalo Linkstation fan driver loaded\n");
|
||||||
|
+ sprintf(lsql_fan_state, "fast");
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_LOW, 0);
|
||||||
|
+ gpio_set_value(LSQL_GPIO_FAN_HIGH, 1);
|
||||||
|
+
|
||||||
|
+ lsql_proc_dir_root = proc_mkdir( "linkstation", NULL );
|
||||||
|
+ lsql_proc_dir_gpio = proc_mkdir( "gpio", lsql_proc_dir_root );
|
||||||
|
+ lsql_fan_proc_file = create_proc_entry( "fan", S_IRUGO, lsql_proc_dir_gpio );
|
||||||
|
+ if( lsql_fan_proc_file ) {
|
||||||
|
+ lsql_fan_proc_file->read_proc = lsql_fan_get;
|
||||||
|
+ lsql_fan_proc_file->write_proc = lsql_fan_set;
|
||||||
|
+ lsql_fan_proc_file->data = NULL;
|
||||||
|
+ } else
|
||||||
|
+ {
|
||||||
|
+ printk(KERN_INFO "Registration of fan device failed\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* register power-off method */
|
||||||
|
+ pm_power_off = lsql_power_off;
|
||||||
|
+
|
||||||
|
+ pr_info("%s: finished\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LINKSTATION_LSQL
|
||||||
|
+MACHINE_START(LINKSTATION_LSQL, "Buffalo Linkstation Quad QL/R5")
|
||||||
|
+ .atag_offset = 0x00000100,
|
||||||
|
+ .init_machine = lsql_init,
|
||||||
|
+ .map_io = orion5x_map_io,
|
||||||
|
+ .init_early = orion5x_init_early,
|
||||||
|
+ .init_irq = orion5x_init_irq,
|
||||||
|
+ .timer = &orion5x_timer,
|
||||||
|
+ .fixup = tag_fixup_mem32,
|
||||||
|
+ /* .restart = orion5x_restart, */
|
||||||
|
+MACHINE_END
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/mach-orion5x/Makefile linux-3.2.33-go/arch/arm/mach-orion5x/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/mach-orion5x/Makefile 2012-11-11 15:13:23.517491578 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/mach-orion5x/Makefile 2012-11-11 15:14:01.323037254 +0100
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_PRODUO) += lsproduo-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_LS_HGL) += ls_hgl-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_LINKSTATION_LSQL) += lsql-setup.o
|
||||||
|
obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
|
||||||
|
obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
|
||||||
|
obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/tools/mach-types linux-3.2.33-go/arch/arm/tools/mach-types
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/tools/mach-types 2012-11-11 15:13:23.340493615 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/tools/mach-types 2012-11-11 15:14:26.618733715 +0100
|
||||||
|
@@ -1129,3 +1129,4 @@
|
||||||
|
m28evk MACH_M28EVK M28EVK 3613
|
||||||
|
smdk4212 MACH_SMDK4212 SMDK4212 3638
|
||||||
|
smdk4412 MACH_SMDK4412 SMDK4412 3765
|
||||||
|
+linkstation_lsql MACH_LINKSTATION_LSQL LINKSTATION_LSQL 4238
|
387
3.2.34/kernel-3.2-lsxhl.patch
Normal file
387
3.2.34/kernel-3.2-lsxhl.patch
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
Add support for the Buffalo Linkstation XHL. This NAS box is based on a
|
||||||
|
Marvell Kirkwood chip at 1.2 GHz and features 256 MB RAM, 512kb SPI boot
|
||||||
|
flash, gigabit ethernet and one SATA port.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Walle <michael at walle.cc>
|
||||||
|
---
|
||||||
|
arch/arm/configs/kirkwood_defconfig | 1 +
|
||||||
|
arch/arm/mach-kirkwood/Kconfig | 6 +
|
||||||
|
arch/arm/mach-kirkwood/Makefile | 1 +
|
||||||
|
arch/arm/mach-kirkwood/lsxhl-setup.c | 313 ++++++++++++++++++++++++++++++++++
|
||||||
|
arch/arm/tools/mach-types | 1 +
|
||||||
|
5 files changed, 322 insertions(+), 0 deletions(-)
|
||||||
|
create mode 100644 arch/arm/mach-kirkwood/lsxhl-setup.c
|
||||||
|
|
||||||
|
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
|
||||||
|
index aeb3af5..9f77811 100644
|
||||||
|
--- a/arch/arm/configs/kirkwood_defconfig
|
||||||
|
+++ b/arch/arm/configs/kirkwood_defconfig
|
||||||
|
@@ -28,6 +28,7 @@ CONFIG_MACH_D2NET_V2=y
|
||||||
|
CONFIG_MACH_NET2BIG_V2=y
|
||||||
|
CONFIG_MACH_NET5BIG_V2=y
|
||||||
|
CONFIG_MACH_T5325=y
|
||||||
|
+CONFIG_MACH_LSXHL=y
|
||||||
|
# CONFIG_CPU_FEROCEON_OLD_ID is not set
|
||||||
|
CONFIG_NO_HZ=y
|
||||||
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
|
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
index 7fc603b..307cc99 100644
|
||||||
|
--- a/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
+++ b/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
@@ -130,6 +130,12 @@ config MACH_T5325
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
HP t5325 Thin Client.
|
||||||
|
|
||||||
|
+config MACH_LSXHL
|
||||||
|
+ bool "Buffalo LS-XHL Series"
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the
|
||||||
|
+ Buffalo LS-XHL Series.
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
||||||
|
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
|
||||||
|
index 5dcaa81..221980b 100644
|
||||||
|
--- a/arch/arm/mach-kirkwood/Makefile
|
||||||
|
+++ b/arch/arm/mach-kirkwood/Makefile
|
||||||
|
@@ -18,5 +18,6 @@ obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
|
||||||
|
obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
|
||||||
|
obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
|
||||||
|
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_LSXHL) += lsxhl-setup.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||||
|
diff --git a/arch/arm/mach-kirkwood/lsxhl-setup.c b/arch/arm/mach-kirkwood/lsxhl-setup.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..783d257
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/arm/mach-kirkwood/lsxhl-setup.c
|
||||||
|
@@ -0,0 +1,313 @@
|
||||||
|
+/*
|
||||||
|
+ * arch/arm/mach-kirkwood/lsxhl-setup.c
|
||||||
|
+ *
|
||||||
|
+ * Buffalo LS-XHL Series Setup
|
||||||
|
+ *
|
||||||
|
+ * This file is licensed under the terms of the GNU General Public
|
||||||
|
+ * License version 2. This program is licensed "as is" without any
|
||||||
|
+ * warranty of any kind, whether express or implied.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/ata_platform.h>
|
||||||
|
+#include <linux/spi/flash.h>
|
||||||
|
+#include <linux/spi/spi.h>
|
||||||
|
+#include <linux/mv643xx_eth.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+#include <linux/gpio-fan.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+#include <asm/mach/arch.h>
|
||||||
|
+#include <mach/kirkwood.h>
|
||||||
|
+#include <plat/mvsdio.h>
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "mpp.h"
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 512KB SPI Flash on BOOT Device
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mtd_partition lsxhl_partitions[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "u-boot",
|
||||||
|
+ .size = 0x70000,
|
||||||
|
+ .offset = 0x00000,
|
||||||
|
+ .mask_flags = MTD_WRITEABLE,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "u-boot env",
|
||||||
|
+ .size = 0x10000,
|
||||||
|
+ .offset = 0x70000,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct flash_platform_data lsxhl_spi_slave_data = {
|
||||||
|
+ .type = "m25p40",
|
||||||
|
+ .parts = lsxhl_partitions,
|
||||||
|
+ .nr_parts = ARRAY_SIZE(lsxhl_partitions),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct spi_board_info __initdata lsxhl_spi_slave_info[] = {
|
||||||
|
+ {
|
||||||
|
+ .modalias = "m25p80",
|
||||||
|
+ .platform_data = &lsxhl_spi_slave_data,
|
||||||
|
+ .irq = -1,
|
||||||
|
+ .max_speed_hz = 20000000,
|
||||||
|
+ .bus_num = 0,
|
||||||
|
+ .chip_select = 0,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Ethernet
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv643xx_eth_platform_data lsxhl_ge00_data = {
|
||||||
|
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct mv643xx_eth_platform_data lsxhl_ge01_data = {
|
||||||
|
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * SATA
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv_sata_platform_data lsxhl_sata_data = {
|
||||||
|
+ .n_ports = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LEDs attached to GPIO
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSXHL_GPIO_LED_ALARM 37
|
||||||
|
+#define LSXHL_GPIO_LED_INFO 38
|
||||||
|
+#define LSXHL_GPIO_LED_PWR 39
|
||||||
|
+#define LSXHL_GPIO_LED_FUNC_BLUE 36
|
||||||
|
+#define LSXHL_GPIO_LED_FUNC_RED 48
|
||||||
|
+
|
||||||
|
+static struct gpio_led lsxhl_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "alarm:red",
|
||||||
|
+ .gpio = LSXHL_GPIO_LED_ALARM,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "info:amber",
|
||||||
|
+ .gpio = LSXHL_GPIO_LED_INFO,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "power:blue",
|
||||||
|
+ .default_trigger = "default-on",
|
||||||
|
+ .gpio = LSXHL_GPIO_LED_PWR,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "func:blue:bottom",
|
||||||
|
+ .gpio = LSXHL_GPIO_LED_FUNC_BLUE,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "func:red:bottom",
|
||||||
|
+ .gpio = LSXHL_GPIO_LED_FUNC_RED,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_led_platform_data lsxhl_led_data = {
|
||||||
|
+ .leds = lsxhl_led_pins,
|
||||||
|
+ .num_leds = ARRAY_SIZE(lsxhl_led_pins),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsxhl_leds = {
|
||||||
|
+ .name = "leds-gpio",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsxhl_led_data,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * General Setup
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSXHL_GPIO_HDD_POWER 10
|
||||||
|
+#define LSXHL_GPIO_USB_POWER 11
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Attached Keys
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSXHL_GPIO_KEY_FUNC 41
|
||||||
|
+#define LSXHL_GPIO_KEY_AUTOPOWER 42
|
||||||
|
+#define LSXHL_GPIO_KEY_POWER 43
|
||||||
|
+#define LSXHL_SW_POWER 0x00
|
||||||
|
+#define LSXHL_SW_AUTOPOWER 0x01
|
||||||
|
+#define LSXHL_SW_FUNC 0x02
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lsxhl_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSXHL_SW_POWER,
|
||||||
|
+ .gpio = LSXHL_GPIO_KEY_POWER,
|
||||||
|
+ .desc = "Power-on Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSXHL_SW_AUTOPOWER,
|
||||||
|
+ .gpio = LSXHL_GPIO_KEY_AUTOPOWER,
|
||||||
|
+ .desc = "Power-auto Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSXHL_SW_POWER,
|
||||||
|
+ .gpio = LSXHL_GPIO_KEY_FUNC,
|
||||||
|
+ .desc = "Function Button",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_platform_data lsxhl_button_data = {
|
||||||
|
+ .buttons = lsxhl_buttons,
|
||||||
|
+ .nbuttons = ARRAY_SIZE(lsxhl_buttons),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsxhl_button_device = {
|
||||||
|
+ .name = "gpio-keys",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsxhl_button_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Fan
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSXHL_GPIO_FAN_HIGH 18
|
||||||
|
+#define LSXHL_GPIO_FAN_LOW 19
|
||||||
|
+#define LSXHL_GPIO_FAN_LOCK 40
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_alarm lsxhl_alarm = {
|
||||||
|
+ .gpio = LSXHL_GPIO_FAN_LOCK,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_speed lsxhl_speeds[] = {
|
||||||
|
+ {
|
||||||
|
+ .rpm = 0,
|
||||||
|
+ .ctrl_val = 3,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 1500,
|
||||||
|
+ .ctrl_val = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 3250,
|
||||||
|
+ .ctrl_val = 2,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 5000,
|
||||||
|
+ .ctrl_val = 0,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int lsxhl_gpio_list[] = {
|
||||||
|
+ LSXHL_GPIO_FAN_HIGH, LSXHL_GPIO_FAN_LOW,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_platform_data lsxhl_fan_data = {
|
||||||
|
+ .num_ctrl = ARRAY_SIZE(lsxhl_gpio_list),
|
||||||
|
+ .ctrl = lsxhl_gpio_list,
|
||||||
|
+ .alarm = &lsxhl_alarm,
|
||||||
|
+ .num_speed = ARRAY_SIZE(lsxhl_speeds),
|
||||||
|
+ .speed = lsxhl_speeds,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsxhl_fan_device = {
|
||||||
|
+ .name = "gpio-fan",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsxhl_fan_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Data
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static unsigned int lsxhl_mpp_config[] __initdata = {
|
||||||
|
+ MPP10_GPO, /* HDD Power Enable */
|
||||||
|
+ MPP11_GPIO, /* USB Vbus Enable */
|
||||||
|
+ MPP18_GPO, /* FAN High Enable# */
|
||||||
|
+ MPP19_GPO, /* FAN Low Enable# */
|
||||||
|
+ MPP36_GPIO, /* Function Blue LED */
|
||||||
|
+ MPP37_GPIO, /* Alarm LED */
|
||||||
|
+ MPP38_GPIO, /* Info LED */
|
||||||
|
+ MPP39_GPIO, /* Power LED */
|
||||||
|
+ MPP40_GPIO, /* Fan Lock */
|
||||||
|
+ MPP41_GPIO, /* Function Button */
|
||||||
|
+ MPP42_GPIO, /* Power Switch */
|
||||||
|
+ MPP43_GPIO, /* Power Auto Switch */
|
||||||
|
+ MPP48_GPIO, /* Function Red LED */
|
||||||
|
+ 0
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LS-XHL specific power off method: reboot
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * On the LS-XHL, the shutdown process is following:
|
||||||
|
+ * - Userland monitors key events until the power switch goes to off position
|
||||||
|
+ * - The board reboots
|
||||||
|
+ * - U-boot starts and goes into an idle mode waiting for the user
|
||||||
|
+ * to move the switch to ON position
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void lsxhl_power_off(void)
|
||||||
|
+{
|
||||||
|
+ arm_machine_restart('h', NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __init lsxhl_init(void)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Basic setup. Needs to be called early.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_init();
|
||||||
|
+ kirkwood_mpp_conf(lsxhl_mpp_config);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Configure peripherals.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_uart0_init();
|
||||||
|
+ kirkwood_ehci_init();
|
||||||
|
+ kirkwood_ge00_init(&lsxhl_ge00_data);
|
||||||
|
+ kirkwood_ge01_init(&lsxhl_ge01_data);
|
||||||
|
+ kirkwood_sata_init(&lsxhl_sata_data);
|
||||||
|
+ kirkwood_spi_init();
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lsxhl_leds);
|
||||||
|
+ platform_device_register(&lsxhl_button_device);
|
||||||
|
+ platform_device_register(&lsxhl_fan_device);
|
||||||
|
+
|
||||||
|
+ spi_register_board_info(lsxhl_spi_slave_info,
|
||||||
|
+ ARRAY_SIZE(lsxhl_spi_slave_info));
|
||||||
|
+
|
||||||
|
+ /* usb power on */
|
||||||
|
+ gpio_set_value(LSXHL_GPIO_USB_POWER, 1);
|
||||||
|
+
|
||||||
|
+ /* register power-off method */
|
||||||
|
+ pm_power_off = lsxhl_power_off;
|
||||||
|
+
|
||||||
|
+ pr_info("%s: finished\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MACHINE_START(LSXHL, "Buffalo Linkstation LS-XHL")
|
||||||
|
+ .atag_offset = 0x100,
|
||||||
|
+ .init_machine = lsxhl_init,
|
||||||
|
+ .map_io = kirkwood_map_io,
|
||||||
|
+ .init_early = kirkwood_init_early,
|
||||||
|
+ .init_irq = kirkwood_init_irq,
|
||||||
|
+ .timer = &kirkwood_timer,
|
||||||
|
+MACHINE_END
|
||||||
|
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
|
||||||
|
index 3b3776d..8acc587 100644
|
||||||
|
--- a/arch/arm/tools/mach-types
|
||||||
|
+++ b/arch/arm/tools/mach-types
|
||||||
|
@@ -448,6 +448,7 @@ mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650
|
||||||
|
guruplug MACH_GURUPLUG GURUPLUG 2659
|
||||||
|
spear310 MACH_SPEAR310 SPEAR310 2660
|
||||||
|
spear320 MACH_SPEAR320 SPEAR320 2661
|
||||||
|
+lsxhl MACH_LSXHL LSXHL 2663
|
||||||
|
aquila MACH_AQUILA AQUILA 2676
|
||||||
|
sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
|
||||||
|
msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
|
||||||
|
--
|
||||||
|
1.7.2.3
|
2132
3.2.34/kernel-3.4.0-layer7-2.22.patch
Normal file
2132
3.2.34/kernel-3.4.0-layer7-2.22.patch
Normal file
File diff suppressed because it is too large
Load Diff
135
3.2.34/kirkwood-jumbo-frame.patch
Normal file
135
3.2.34/kirkwood-jumbo-frame.patch
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
kirkwood and dove have a smaller FIFO than other "orion" SoCs. This
|
||||||
|
needs to be taken into account otherwise people using things like jumbo frames
|
||||||
|
will get into some troubles.
|
||||||
|
|
||||||
|
As a side note, this patch is an updated version of a patch sent some years
|
||||||
|
ago: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017320.html
|
||||||
|
which seems to have been lost.
|
||||||
|
|
||||||
|
Signed-off-by: Arnaud Patard <arnaud.patard@xxxxxxxxxxx>
|
||||||
|
|
||||||
|
Index: alunn/arch/arm/mach-dove/common.c
|
||||||
|
===================================================================
|
||||||
|
--- alunn.orig/arch/arm/mach-dove/common.c 2012-07-20 09:14:45.000000000 +0200
|
||||||
|
+++ alunn/arch/arm/mach-dove/common.c 2012-07-20 17:51:38.872925518 +0200
|
||||||
|
@@ -102,7 +102,7 @@ void __init dove_ehci1_init(void)
|
||||||
|
void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
|
||||||
|
{
|
||||||
|
orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE,
|
||||||
|
- IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR);
|
||||||
|
+ IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
Index: alunn/arch/arm/mach-kirkwood/common.c
|
||||||
|
===================================================================
|
||||||
|
--- alunn.orig/arch/arm/mach-kirkwood/common.c 2012-07-20 09:14:46.000000000 +0200
|
||||||
|
+++ alunn/arch/arm/mach-kirkwood/common.c 2012-07-20 17:51:03.104927094 +0200
|
||||||
|
@@ -301,7 +301,7 @@ void __init kirkwood_ge00_init(struct mv
|
||||||
|
{
|
||||||
|
orion_ge00_init(eth_data,
|
||||||
|
GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
|
||||||
|
- IRQ_KIRKWOOD_GE00_ERR);
|
||||||
|
+ IRQ_KIRKWOOD_GE00_ERR, 1600);
|
||||||
|
/* The interface forgets the MAC address assigned by u-boot if
|
||||||
|
the clock is turned off, so claim the clk now. */
|
||||||
|
clk_prepare_enable(ge0);
|
||||||
|
@@ -315,7 +315,7 @@ void __init kirkwood_ge01_init(struct mv
|
||||||
|
{
|
||||||
|
orion_ge01_init(eth_data,
|
||||||
|
GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
|
||||||
|
- IRQ_KIRKWOOD_GE01_ERR);
|
||||||
|
+ IRQ_KIRKWOOD_GE01_ERR, 1600);
|
||||||
|
clk_prepare_enable(ge1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Index: alunn/arch/arm/mach-mv78xx0/common.c
|
||||||
|
===================================================================
|
||||||
|
--- alunn.orig/arch/arm/mach-mv78xx0/common.c 2012-07-20 09:14:46.000000000 +0200
|
||||||
|
+++ alunn/arch/arm/mach-mv78xx0/common.c 2012-07-20 17:50:26.712928695 +0200
|
||||||
|
@@ -213,7 +213,7 @@ void __init mv78xx0_ge00_init(struct mv6
|
||||||
|
{
|
||||||
|
orion_ge00_init(eth_data,
|
||||||
|
GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
|
||||||
|
- IRQ_MV78XX0_GE_ERR);
|
||||||
|
+ IRQ_MV78XX0_GE_ERR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -224,7 +224,7 @@ void __init mv78xx0_ge01_init(struct mv6
|
||||||
|
{
|
||||||
|
orion_ge01_init(eth_data,
|
||||||
|
GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
|
||||||
|
- NO_IRQ);
|
||||||
|
+ NO_IRQ, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Index: alunn/arch/arm/mach-orion5x/common.c
|
||||||
|
===================================================================
|
||||||
|
--- alunn.orig/arch/arm/mach-orion5x/common.c 2012-07-20 09:14:46.000000000 +0200
|
||||||
|
+++ alunn/arch/arm/mach-orion5x/common.c 2012-07-20 17:50:26.744928692 +0200
|
||||||
|
@@ -109,7 +109,7 @@ void __init orion5x_eth_init(struct mv64
|
||||||
|
{
|
||||||
|
orion_ge00_init(eth_data,
|
||||||
|
ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
|
||||||
|
- IRQ_ORION5X_ETH_ERR);
|
||||||
|
+ IRQ_ORION5X_ETH_ERR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Index: alunn/arch/arm/plat-orion/common.c
|
||||||
|
===================================================================
|
||||||
|
--- alunn.orig/arch/arm/plat-orion/common.c 2012-07-20 09:14:46.000000000 +0200
|
||||||
|
+++ alunn/arch/arm/plat-orion/common.c 2012-07-20 17:50:26.756928690 +0200
|
||||||
|
@@ -291,10 +291,12 @@ static struct platform_device orion_ge00
|
||||||
|
void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
|
||||||
|
unsigned long mapbase,
|
||||||
|
unsigned long irq,
|
||||||
|
- unsigned long irq_err)
|
||||||
|
+ unsigned long irq_err,
|
||||||
|
+ unsigned int tx_csum_limit)
|
||||||
|
{
|
||||||
|
fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
|
||||||
|
mapbase + 0x2000, SZ_16K - 1, irq_err);
|
||||||
|
+ orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;
|
||||||
|
ge_complete(&orion_ge00_shared_data,
|
||||||
|
orion_ge00_resources, irq, &orion_ge00_shared,
|
||||||
|
eth_data, &orion_ge00);
|
||||||
|
@@ -343,10 +345,12 @@ static struct platform_device orion_ge01
|
||||||
|
void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
|
||||||
|
unsigned long mapbase,
|
||||||
|
unsigned long irq,
|
||||||
|
- unsigned long irq_err)
|
||||||
|
+ unsigned long irq_err,
|
||||||
|
+ unsigned int tx_csum_limit)
|
||||||
|
{
|
||||||
|
fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
|
||||||
|
mapbase + 0x2000, SZ_16K - 1, irq_err);
|
||||||
|
+ orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;
|
||||||
|
ge_complete(&orion_ge01_shared_data,
|
||||||
|
orion_ge01_resources, irq, &orion_ge01_shared,
|
||||||
|
eth_data, &orion_ge01);
|
||||||
|
Index: alunn/arch/arm/plat-orion/include/plat/common.h
|
||||||
|
===================================================================
|
||||||
|
--- alunn.orig/arch/arm/plat-orion/include/plat/common.h 2012-07-20 09:14:46.000000000 +0200
|
||||||
|
+++ alunn/arch/arm/plat-orion/include/plat/common.h 2012-07-20 17:50:26.772928691 +0200
|
||||||
|
@@ -39,12 +39,14 @@ void __init orion_rtc_init(unsigned long
|
||||||
|
void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
|
||||||
|
unsigned long mapbase,
|
||||||
|
unsigned long irq,
|
||||||
|
- unsigned long irq_err);
|
||||||
|
+ unsigned long irq_err,
|
||||||
|
+ unsigned int tx_csum_limit);
|
||||||
|
|
||||||
|
void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
|
||||||
|
unsigned long mapbase,
|
||||||
|
unsigned long irq,
|
||||||
|
- unsigned long irq_err);
|
||||||
|
+ unsigned long irq_err,
|
||||||
|
+ unsigned int tx_csum_limit);
|
||||||
|
|
||||||
|
void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
|
||||||
|
unsigned long mapbase,
|
||||||
|
|
||||||
|
|
15
3.2.34/linux-2.6-defaults-fat-utf8.patch
Normal file
15
3.2.34/linux-2.6-defaults-fat-utf8.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=181963
|
||||||
|
|
||||||
|
--- linux-2.6.15.noarch/fs/fat/inode.c~ 2006-02-20 23:20:12.000000000 -0500
|
||||||
|
+++ linux-2.6.15.noarch/fs/fat/inode.c 2006-02-20 23:21:42.000000000 -0500
|
||||||
|
@@ -952,7 +952,8 @@ static int parse_options(char *options,
|
||||||
|
opts->shortname = 0;
|
||||||
|
opts->name_check = 'n';
|
||||||
|
opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0;
|
||||||
|
- opts->utf8 = opts->unicode_xlate = 0;
|
||||||
|
+ opts->utf8 = 1;
|
||||||
|
+ opts->unicode_xlate = 0;
|
||||||
|
opts->numtail = 1;
|
||||||
|
opts->nocase = 0;
|
||||||
|
*debug = 0;
|
13
3.2.34/linux-2.6-x86-tune-generic.patch
Normal file
13
3.2.34/linux-2.6-x86-tune-generic.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
* Optimise for today's CPUs.
|
||||||
|
|
||||||
|
--- linux-2.6/arch/x86/Makefile_32.cpu 2006-01-09 11:39:04.000000000 -0500
|
||||||
|
+++ linux-2.6/arch/x86/Makefile_32.cpu 2006-01-09 11:39:36.000000000 -0500
|
||||||
|
@@ -15,7 +15,7 @@ cflags-$(CONFIG_M486) += -march=i486
|
||||||
|
cflags-$(CONFIG_M586) += -march=i586
|
||||||
|
cflags-$(CONFIG_M586TSC) += -march=i586
|
||||||
|
cflags-$(CONFIG_M586MMX) += -march=pentium-mmx
|
||||||
|
-cflags-$(CONFIG_M686) += -march=i686
|
||||||
|
+cflags-$(CONFIG_M686) += -march=i686 $(call tune,generic)
|
||||||
|
cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2)
|
||||||
|
cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3)
|
||||||
|
cflags-$(CONFIG_MPENTIUMM) += -march=i686 $(call tune,pentium3)
|
7807
3.2.34/linux-3.2-e2c-0.4.58.patch
Normal file
7807
3.2.34/linux-3.2-e2c-0.4.58.patch
Normal file
File diff suppressed because it is too large
Load Diff
201830
3.2.34/linux-3.2.33-zfs.patch
Normal file
201830
3.2.34/linux-3.2.33-zfs.patch
Normal file
File diff suppressed because it is too large
Load Diff
256
3.2.34/lschlv2.patch
Normal file
256
3.2.34/lschlv2.patch
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
--- a/arch/arm/mach-kirkwood/include/mach/system.h
|
||||||
|
+++ b/arch/arm/mach-kirkwood/include/mach/system.h
|
||||||
|
@@ -9,6 +9,8 @@
|
||||||
|
#ifndef __ASM_ARCH_SYSTEM_H
|
||||||
|
#define __ASM_ARCH_SYSTEM_H
|
||||||
|
|
||||||
|
+#include <linux/io.h>
|
||||||
|
+#include <asm/proc-fns.h>
|
||||||
|
#include <mach/bridge-regs.h>
|
||||||
|
|
||||||
|
static inline void arch_idle(void)
|
||||||
|
--- a/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
+++ b/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
@@ -87,6 +87,12 @@
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
HP t5325 Thin Client.
|
||||||
|
|
||||||
|
+config MACH_LINKSTATION_CHLV2
|
||||||
|
+ bool "Buffalo LS-CHLv2 Series"
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the
|
||||||
|
+ Buffalo LS-CHLv2 Series.
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
||||||
|
--- a/arch/arm/mach-kirkwood/lschlv2-setup.c
|
||||||
|
+++ b/arch/arm/mach-kirkwood/lschlv2-setup.c
|
||||||
|
@@ -0,0 +1,210 @@
|
||||||
|
+/*
|
||||||
|
+ * arch/arm/mach-kirkwood/lschlv2-setup.c
|
||||||
|
+ *
|
||||||
|
+ * Buffalo LS Kirkwood Series Setup
|
||||||
|
+ *
|
||||||
|
+ * This file is licensed under the terms of the GNU General Public
|
||||||
|
+ * License version 2. This program is licensed "as is" without any
|
||||||
|
+ * warranty of any kind, whether express or implied.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/ata_platform.h>
|
||||||
|
+#include <linux/mv643xx_eth.h>
|
||||||
|
+#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/spi/flash.h>
|
||||||
|
+#include <linux/spi/spi.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+#include <asm/mach/arch.h>
|
||||||
|
+#include "include/mach/system.h"
|
||||||
|
+#include <mach/kirkwood.h>
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "mpp.h"
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 512KB SPI Flash on BOOT Device
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mtd_partition lschlv2_partitions[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "u-boot",
|
||||||
|
+ .offset = 0x00000,
|
||||||
|
+ .size = 0x70000,
|
||||||
|
+ .mask_flags = MTD_WRITEABLE,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "u-boot env",
|
||||||
|
+ .offset = MTDPART_OFS_APPEND,
|
||||||
|
+ .size = 0x10000,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct flash_platform_data lschlv2_spi_slave_data = {
|
||||||
|
+ .type = "m25p40",
|
||||||
|
+ .parts = lschlv2_partitions,
|
||||||
|
+ .nr_parts = ARRAY_SIZE(lschlv2_partitions),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct spi_board_info __initdata lschlv2_spi_slave_info[] = {
|
||||||
|
+ {
|
||||||
|
+ .modalias = "m25p80",
|
||||||
|
+ .platform_data = &lschlv2_spi_slave_data,
|
||||||
|
+ .irq = -1,
|
||||||
|
+ .max_speed_hz = 20000000,
|
||||||
|
+ .bus_num = 0,
|
||||||
|
+ .chip_select = 0,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct mv643xx_eth_platform_data lschlv2_ge00_data = {
|
||||||
|
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct mv643xx_eth_platform_data lschlv2_ge01_data = {
|
||||||
|
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static unsigned int lschlv2_mpp_config[] __initdata = {
|
||||||
|
+ MPP10_GPO, /* HDD Power */
|
||||||
|
+ MPP11_GPIO, /* USB Vbus Power */
|
||||||
|
+ MPP18_GPO, /* FAN High on:0, off:1 */
|
||||||
|
+ MPP19_GPO, /* FAN Low on:0, off:1 */
|
||||||
|
+ MPP36_GPIO, /* FUNC LED */
|
||||||
|
+ MPP37_GPIO, /* ALARM LED */
|
||||||
|
+ MPP38_GPIO, /* INFO LED */
|
||||||
|
+ MPP39_GPIO, /* POWER LED */
|
||||||
|
+ MPP40_GPIO, /* FAN LOCK */
|
||||||
|
+ MPP41_GPIO, /* FUNC SW */
|
||||||
|
+ MPP42_GPIO, /* POWER SW */
|
||||||
|
+ MPP43_GPIO, /* POWER AUTO SW */
|
||||||
|
+ MPP48_GPIO, /* FUNC RED LED */
|
||||||
|
+ MPP49_GPIO, /* UART EN */
|
||||||
|
+ 0
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct mv_sata_platform_data lschlv2_sata_data = {
|
||||||
|
+ .n_ports = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_led lschlv2_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "func",
|
||||||
|
+ .gpio = 36,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "alarm",
|
||||||
|
+ .gpio = 37,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "info",
|
||||||
|
+ .gpio = 38,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "power",
|
||||||
|
+ .gpio = 39,
|
||||||
|
+ .default_trigger = "default-on",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "func2",
|
||||||
|
+ .gpio = 48,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_led_platform_data lschlv2_led_data = {
|
||||||
|
+ .leds = lschlv2_led_pins,
|
||||||
|
+ .num_leds = ARRAY_SIZE(lschlv2_led_pins),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lschlv2_leds = {
|
||||||
|
+ .name = "leds-gpio",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lschlv2_led_data,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#define LSCHLv2_GPIO_USB_VBUS_EN 11
|
||||||
|
+#define LSCHLv2_GPIO_KEY_FUNC 41
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lschlv2_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .code = KEY_OPTION,
|
||||||
|
+ .gpio = LSCHLv2_GPIO_KEY_FUNC,
|
||||||
|
+ .desc = "Function Button",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_platform_data lschlv2_button_data = {
|
||||||
|
+ .buttons = lschlv2_buttons,
|
||||||
|
+ .nbuttons = ARRAY_SIZE(lschlv2_buttons),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lschlv2_button_device = {
|
||||||
|
+ .name = "gpio-keys",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lschlv2_button_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void lschlv2_power_off(void)
|
||||||
|
+{
|
||||||
|
+ arch_reset(0, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __init lschlv2_init(void)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Basic setup. Needs to be called early.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_init();
|
||||||
|
+ kirkwood_mpp_conf(lschlv2_mpp_config);
|
||||||
|
+
|
||||||
|
+ kirkwood_uart0_init();
|
||||||
|
+
|
||||||
|
+ if (gpio_request(LSCHLv2_GPIO_USB_VBUS_EN, "USB Power Enable") != 0 ||
|
||||||
|
+ gpio_direction_output(LSCHLv2_GPIO_USB_VBUS_EN, 1) != 0)
|
||||||
|
+ printk(KERN_ERR "can't set up USB Power Enable\n");
|
||||||
|
+ kirkwood_ehci_init();
|
||||||
|
+
|
||||||
|
+ kirkwood_ge00_init(&lschlv2_ge00_data);
|
||||||
|
+ kirkwood_ge01_init(&lschlv2_ge01_data);
|
||||||
|
+
|
||||||
|
+ kirkwood_sata_init(&lschlv2_sata_data);
|
||||||
|
+
|
||||||
|
+ kirkwood_spi_init();
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lschlv2_leds);
|
||||||
|
+ platform_device_register(&lschlv2_button_device);
|
||||||
|
+
|
||||||
|
+ spi_register_board_info(lschlv2_spi_slave_info,
|
||||||
|
+ ARRAY_SIZE(lschlv2_spi_slave_info));
|
||||||
|
+
|
||||||
|
+ /* register power-off method */
|
||||||
|
+ pm_power_off = lschlv2_power_off;
|
||||||
|
+
|
||||||
|
+ pr_info("%s: finished\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+MACHINE_START(LINKSTATION_CHLV2, "Buffalo Linkstation LS-CHLv2")
|
||||||
|
+ .atag_offset = 0x100,
|
||||||
|
+ .init_machine = lschlv2_init,
|
||||||
|
+ .map_io = kirkwood_map_io,
|
||||||
|
+ .init_early = kirkwood_init_early,
|
||||||
|
+ .init_irq = kirkwood_init_irq,
|
||||||
|
+ .timer = &kirkwood_timer,
|
||||||
|
+MACHINE_END
|
||||||
|
--- a/arch/arm/mach-kirkwood/Makefile
|
||||||
|
+++ b/arch/arm/mach-kirkwood/Makefile
|
||||||
|
@@ -20,3 +20,4 @@
|
||||||
|
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_LINKSTATION_CHLV2) += lschlv2-setup.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||||
|
--- a/arch/arm/mach-kirkwood/common.c
|
||||||
|
+++ b/arch/arm/mach-kirkwood/common.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include <plat/orion_nand.h>
|
||||||
|
#include <plat/orion_wdt.h>
|
||||||
|
#include <plat/time.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/*****************************************************************************
|
32
3.2.34/net-netfilter-IFWLOG-2.6.35-buildfix.patch
Normal file
32
3.2.34/net-netfilter-IFWLOG-2.6.35-buildfix.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
--- linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2010-07-30 21:17:30.000000000 +0300
|
||||||
|
+++ linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_IFWLOG.c 2010-07-31 13:46:33.834611944 +0300
|
||||||
|
@@ -135,7 +135,7 @@ static void ipt_IFWLOG_packet(const stru
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int ipt_IFWLOG_target(struct sk_buff *skb,
|
||||||
|
- const struct xt_target_param *target_param)
|
||||||
|
+ const struct xt_action_param *target_param)
|
||||||
|
{
|
||||||
|
const struct ipt_IFWLOG_info *info = target_param->targinfo;
|
||||||
|
|
||||||
|
@@ -144,17 +144,17 @@ static unsigned int ipt_IFWLOG_target(st
|
||||||
|
return IPT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static bool ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
|
||||||
|
+static int ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
|
||||||
|
{
|
||||||
|
const struct ipt_IFWLOG_info *info = tgchk_param->targinfo;
|
||||||
|
|
||||||
|
if (info->prefix[sizeof(info->prefix)-1] != '\0') {
|
||||||
|
DEBUGP("IFWLOG: prefix term %i\n",
|
||||||
|
info->prefix[sizeof(info->prefix)-1]);
|
||||||
|
- return false;
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return true;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xt_target ipt_IFWLOG = {
|
15
3.2.34/net-netfilter-IFWLOG-2.6.37-buildfix.patch
Normal file
15
3.2.34/net-netfilter-IFWLOG-2.6.37-buildfix.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
net/ipv4/netfilter/ipt_IFWLOG.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- linux-2.6.37-rc3-git1-tmb0.3/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2010-11-24 21:58:36.000000000 +0200
|
||||||
|
+++ linux-2.6.37-rc3-git1-tmb0.3/net/ipv4/netfilter/ipt_IFWLOG.c 2010-11-25 13:08:55.719379646 +0200
|
||||||
|
@@ -141,7 +141,7 @@ static unsigned int ipt_IFWLOG_target(st
|
||||||
|
|
||||||
|
ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info);
|
||||||
|
|
||||||
|
- return IPT_CONTINUE;
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
|
264
3.2.34/net-netfilter-IFWLOG-mdv.patch
Normal file
264
3.2.34/net-netfilter-IFWLOG-mdv.patch
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
ipt_IFWLOG: Mandriva changes
|
||||||
|
|
||||||
|
This patch holds all the Mandriva changes done in ipt_IFWLOG
|
||||||
|
netfilter module.
|
||||||
|
|
||||||
|
This work is mostly done by Thomas Backlund, Herton R. Krzesinski
|
||||||
|
and Luiz Fernando N. Capitulino.
|
||||||
|
|
||||||
|
Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
|
||||||
|
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||||
|
|
||||||
|
---
|
||||||
|
include/linux/netfilter_ipv4/Kbuild | 1
|
||||||
|
include/linux/netfilter_ipv4/ipt_IFWLOG.h | 23 +++++-
|
||||||
|
net/ipv4/netfilter/ipt_IFWLOG.c | 108 +++++++++++++++---------------
|
||||||
|
3 files changed, 77 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
|
diff -p -up linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h
|
||||||
|
--- linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig 2008-12-12 10:55:07.000000000 -0500
|
||||||
|
+++ linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h 2008-12-12 10:56:30.000000000 -0500
|
||||||
|
@@ -1,10 +1,25 @@
|
||||||
|
-#ifndef _IPT_IFWLOG_H
|
||||||
|
-#define _IPT_IFWLOG_H
|
||||||
|
+#ifndef _LINUX_IPT_IFWLOG_H
|
||||||
|
+#define _LINUX_IPT_IFWLOG_H
|
||||||
|
|
||||||
|
#ifndef NETLINK_IFWLOG
|
||||||
|
-#define NETLINK_IFWLOG 19
|
||||||
|
+#define NETLINK_IFWLOG 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef __KERNEL__
|
||||||
|
+/* Multicast groups - backwards compatiblility for userspace */
|
||||||
|
+#define IFWLOG_NLGRP_NONE 0x00000000
|
||||||
|
+#define IFWLOG_NLGRP_DEF 0x00000001 /* default message group */
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+enum {
|
||||||
|
+ IFWLOGNLGRP_NONE,
|
||||||
|
+#define IFWLOGNLGRP_NONE IFWLOGNLGRP_NONE
|
||||||
|
+ IFWLOGNLGRP_DEF,
|
||||||
|
+#define IFWLOGNLGRP_DEF IFWLOGNLGRP_DEF
|
||||||
|
+ __IFWLOGNLGRP_MAX
|
||||||
|
+};
|
||||||
|
+#define IFWLOGNLGRP_MAX (__IFWLOGNLGRP_MAX - 1)
|
||||||
|
+
|
||||||
|
#define PREFSIZ 32
|
||||||
|
|
||||||
|
struct nl_msg { /* Netlink message */
|
||||||
|
@@ -23,4 +38,4 @@ struct ipt_IFWLOG_info {
|
||||||
|
char prefix[PREFSIZ];
|
||||||
|
};
|
||||||
|
|
||||||
|
-#endif /* _IPT_IFWLOG_H */
|
||||||
|
+#endif /* _LINUX_IPT_IFWLOG_H */
|
||||||
|
diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c
|
||||||
|
--- linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2008-12-12 10:55:07.000000000 -0500
|
||||||
|
+++ linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c 2008-12-12 10:57:16.000000000 -0500
|
||||||
|
@@ -4,6 +4,14 @@
|
||||||
|
* 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.
|
||||||
|
+ *
|
||||||
|
+ * 2007-10-10 Thomas Backlund <tmb@mandriva.org>: build fixes for 2.6.22.9
|
||||||
|
+ * 2007-11-11 Herton Krzesinski <herton@mandriva.com>: build fixes for 2.6.24-rc
|
||||||
|
+ * 2007-12-03 Luiz Capitulino <lcapitulino@mandriva.com.br>: v1.1
|
||||||
|
+ * - Better multicast group usage
|
||||||
|
+ * - Coding style fixes
|
||||||
|
+ * - Do not return -EINVAL by default in ipt_ifwlog_init()
|
||||||
|
+ * - Minor refinements
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
@@ -19,12 +27,10 @@
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
#include <linux/netfilter.h>
|
||||||
|
+#include <linux/netfilter/x_tables.h>
|
||||||
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
#include <linux/netfilter_ipv4/ipt_IFWLOG.h>
|
||||||
|
|
||||||
|
-MODULE_LICENSE("GPL");
|
||||||
|
-MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
|
||||||
|
-MODULE_DESCRIPTION("Interactive firewall logging and module");
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define DEBUGP PRINTR
|
||||||
|
@@ -36,44 +42,41 @@ MODULE_DESCRIPTION("Interactive firewall
|
||||||
|
|
||||||
|
static struct sock *nl;
|
||||||
|
|
||||||
|
-#define GROUP 10
|
||||||
|
-
|
||||||
|
/* send struct to userspace */
|
||||||
|
-static void send_packet(struct nl_msg msg)
|
||||||
|
+static void send_packet(const struct nl_msg *msg)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb = NULL;
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
+ unsigned int size;
|
||||||
|
|
||||||
|
- skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC);
|
||||||
|
+ size = NLMSG_SPACE(sizeof(*msg));
|
||||||
|
+ skb = alloc_skb(size, GFP_ATOMIC);
|
||||||
|
if (!skb) {
|
||||||
|
PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n");
|
||||||
|
- return ;
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh));
|
||||||
|
+ nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh));
|
||||||
|
|
||||||
|
- memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg));
|
||||||
|
+ memcpy(NLMSG_DATA(nlh), (const void *) msg, sizeof(*msg));
|
||||||
|
|
||||||
|
NETLINK_CB(skb).pid = 0; /* from kernel */
|
||||||
|
- NETLINK_CB(skb).dst_pid = 0; /* multicast */
|
||||||
|
- NETLINK_CB(skb).dst_group = 10;
|
||||||
|
+ NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF;
|
||||||
|
|
||||||
|
if (nl) {
|
||||||
|
DEBUGP(KERN_WARNING
|
||||||
|
"IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n",
|
||||||
|
(long)nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags,
|
||||||
|
(long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid);
|
||||||
|
- DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix);
|
||||||
|
+ DEBUGP(KERN_WARNING "prefix : %s\n", msg->prefix);
|
||||||
|
|
||||||
|
- netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC);
|
||||||
|
- return ;
|
||||||
|
+ netlink_broadcast(nl, skb, 0, IFWLOGNLGRP_DEF, GFP_ATOMIC);
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- nlmsg_failure:
|
||||||
|
- if (skb)
|
||||||
|
- kfree_skb(skb);
|
||||||
|
- PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
|
||||||
|
- return ;
|
||||||
|
+nlmsg_failure:
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill struct for userspace */
|
||||||
|
@@ -128,73 +131,76 @@ static void ipt_IFWLOG_packet(const stru
|
||||||
|
do_gettimeofday((struct timeval *)&tv);
|
||||||
|
msg.timestamp_sec = tv.tv_sec;
|
||||||
|
|
||||||
|
- send_packet(msg);
|
||||||
|
+ send_packet(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb,
|
||||||
|
- const struct net_device *in,
|
||||||
|
- const struct net_device *out,
|
||||||
|
- unsigned int hooknum,
|
||||||
|
- const void *targinfo,
|
||||||
|
- void *userinfo)
|
||||||
|
+static unsigned int ipt_IFWLOG_target(struct sk_buff *skb,
|
||||||
|
+ const struct xt_target_param *target_param)
|
||||||
|
{
|
||||||
|
- const struct ipt_IFWLOG_info *info = targinfo;
|
||||||
|
+ const struct ipt_IFWLOG_info *info = target_param->targinfo;
|
||||||
|
|
||||||
|
- ipt_IFWLOG_packet(*pskb, in, out, info);
|
||||||
|
+ ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info);
|
||||||
|
|
||||||
|
return IPT_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int ipt_IFWLOG_checkentry(const char *tablename,
|
||||||
|
- const struct ipt_entry *e,
|
||||||
|
- void *targinfo,
|
||||||
|
- unsigned int targinfosize,
|
||||||
|
- unsigned int hook_mask)
|
||||||
|
+static bool ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
|
||||||
|
{
|
||||||
|
- const struct ipt_IFWLOG_info *info = targinfo;
|
||||||
|
+ const struct ipt_IFWLOG_info *info = tgchk_param->targinfo;
|
||||||
|
|
||||||
|
if (info->prefix[sizeof(info->prefix)-1] != '\0') {
|
||||||
|
DEBUGP("IFWLOG: prefix term %i\n",
|
||||||
|
info->prefix[sizeof(info->prefix)-1]);
|
||||||
|
- return 0;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return 1;
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static struct ipt_target ipt_IFWLOG = {
|
||||||
|
+static struct xt_target ipt_IFWLOG = {
|
||||||
|
.name = "IFWLOG",
|
||||||
|
+ .family = AF_INET,
|
||||||
|
.target = ipt_IFWLOG_target,
|
||||||
|
.targetsize = sizeof(struct ipt_IFWLOG_info),
|
||||||
|
.checkentry = ipt_IFWLOG_checkentry,
|
||||||
|
.me = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static int __init init(void)
|
||||||
|
+static int __init ipt_ifwlog_init(void)
|
||||||
|
{
|
||||||
|
- nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE);
|
||||||
|
- if (!nl) {
|
||||||
|
- PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
- if (ipt_register_target(&ipt_IFWLOG)) {
|
||||||
|
+ nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, IFWLOGNLGRP_MAX,
|
||||||
|
+ NULL, NULL, THIS_MODULE);
|
||||||
|
+ if (!nl) {
|
||||||
|
+ PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = xt_register_target(&ipt_IFWLOG);
|
||||||
|
+ if (err) {
|
||||||
|
if (nl && nl->sk_socket)
|
||||||
|
sock_release(nl->sk_socket);
|
||||||
|
- return -EINVAL;
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINTR(KERN_INFO "IFWLOG: register target\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void __exit fini(void)
|
||||||
|
+static void __exit ipt_ifwlog_fini(void)
|
||||||
|
{
|
||||||
|
if (nl && nl->sk_socket)
|
||||||
|
- sock_release(nl->sk_socket);
|
||||||
|
+ sock_release(nl->sk_socket);
|
||||||
|
PRINTR(KERN_INFO "IFWLOG: unregister target\n");
|
||||||
|
- ipt_unregister_target(&ipt_IFWLOG);
|
||||||
|
+ xt_unregister_target(&ipt_IFWLOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
-module_init(init);
|
||||||
|
-module_exit(fini);
|
||||||
|
+module_init(ipt_ifwlog_init);
|
||||||
|
+module_exit(ipt_ifwlog_fini);
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
|
||||||
|
+MODULE_AUTHOR("Luiz Capitulino <lcapitulino@mandriva.com.br>");
|
||||||
|
+MODULE_DESCRIPTION("Interactive firewall logging and module");
|
||||||
|
+MODULE_VERSION("v1.1");
|
||||||
|
--- linux/include/linux/netfilter_ipv4/Kbuild.net-netfilter-IFWLOG-mdv.orig 2012-05-21 01:29:13.000000000 +0300
|
||||||
|
+++ linux/include/linux/netfilter_ipv4/Kbuild 2012-05-26 01:27:24.743139430 +0300
|
||||||
|
@@ -2,6 +2,7 @@ header-y += ip_queue.h
|
||||||
|
header-y += ip_tables.h
|
||||||
|
header-y += ipt_CLUSTERIP.h
|
||||||
|
header-y += ipt_ECN.h
|
||||||
|
+header-y += ipt_IFWLOG.h
|
||||||
|
header-y += ipt_LOG.h
|
||||||
|
header-y += ipt_REJECT.h
|
||||||
|
header-y += ipt_TTL.h
|
269
3.2.34/net-netfilter-IFWLOG.patch
Normal file
269
3.2.34/net-netfilter-IFWLOG.patch
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
---
|
||||||
|
include/linux/netfilter_ipv4/ipt_IFWLOG.h | 26 +++
|
||||||
|
net/ipv4/netfilter/Kconfig | 11 +
|
||||||
|
net/ipv4/netfilter/Makefile | 1
|
||||||
|
net/ipv4/netfilter/ipt_IFWLOG.c | 200 ++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 238 insertions(+)
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/net/ipv4/netfilter/ipt_IFWLOG.c
|
||||||
|
@@ -0,0 +1,200 @@
|
||||||
|
+/* Interactive Firewall for Mandriva
|
||||||
|
+ * Samir Bellabes <sbellabes@mandriva.com>
|
||||||
|
+ *
|
||||||
|
+ * 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 <asm/types.h>
|
||||||
|
+#include <linux/jiffies.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/ip.h>
|
||||||
|
+#include <net/icmp.h>
|
||||||
|
+#include <net/udp.h>
|
||||||
|
+#include <net/tcp.h>
|
||||||
|
+#include <net/sock.h>
|
||||||
|
+#include <linux/netlink.h>
|
||||||
|
+#include <linux/string.h>
|
||||||
|
+
|
||||||
|
+#include <linux/netfilter.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ipt_IFWLOG.h>
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
|
||||||
|
+MODULE_DESCRIPTION("Interactive firewall logging and module");
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+#define DEBUGP PRINTR
|
||||||
|
+#else
|
||||||
|
+#define DEBUGP(format, args...)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define PRINTR(format, args...) do { if(net_ratelimit()) printk(format, ##args); } while(0)
|
||||||
|
+
|
||||||
|
+static struct sock *nl;
|
||||||
|
+
|
||||||
|
+#define GROUP 10
|
||||||
|
+
|
||||||
|
+/* send struct to userspace */
|
||||||
|
+static void send_packet(struct nl_msg msg)
|
||||||
|
+{
|
||||||
|
+ struct sk_buff *skb = NULL;
|
||||||
|
+ struct nlmsghdr *nlh;
|
||||||
|
+
|
||||||
|
+ skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC);
|
||||||
|
+ if (!skb) {
|
||||||
|
+ PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n");
|
||||||
|
+ return ;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh));
|
||||||
|
+
|
||||||
|
+ memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg));
|
||||||
|
+
|
||||||
|
+ NETLINK_CB(skb).pid = 0; /* from kernel */
|
||||||
|
+ NETLINK_CB(skb).dst_pid = 0; /* multicast */
|
||||||
|
+ NETLINK_CB(skb).dst_group = 10;
|
||||||
|
+
|
||||||
|
+ if (nl) {
|
||||||
|
+ DEBUGP(KERN_WARNING
|
||||||
|
+ "IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n",
|
||||||
|
+ (long)nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags,
|
||||||
|
+ (long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid);
|
||||||
|
+ DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix);
|
||||||
|
+
|
||||||
|
+ netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC);
|
||||||
|
+ return ;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nlmsg_failure:
|
||||||
|
+ if (skb)
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
|
||||||
|
+ return ;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* fill struct for userspace */
|
||||||
|
+static void ipt_IFWLOG_packet(const struct sk_buff *skb,
|
||||||
|
+ const struct net_device *in,
|
||||||
|
+ const struct net_device *out,
|
||||||
|
+ const struct ipt_IFWLOG_info *info)
|
||||||
|
+{
|
||||||
|
+ struct iphdr iph;
|
||||||
|
+ struct tcphdr tcph;
|
||||||
|
+ struct udphdr udph;
|
||||||
|
+ struct nl_msg msg;
|
||||||
|
+ struct iphdr _iph, *ih;
|
||||||
|
+ struct timeval tv;
|
||||||
|
+
|
||||||
|
+ memset(&msg, 0, sizeof(struct nl_msg));
|
||||||
|
+
|
||||||
|
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
|
||||||
|
+ if (ih == NULL) {
|
||||||
|
+ PRINTR(KERN_WARNING "IFWLOG: skb truncated");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* save interface name */
|
||||||
|
+ if (in)
|
||||||
|
+ strcpy(msg.indev_name, in->name);
|
||||||
|
+ if (out)
|
||||||
|
+ strcpy(msg.outdev_name, out->name);
|
||||||
|
+
|
||||||
|
+ /* save log-prefix */
|
||||||
|
+ strcpy(msg.prefix, info->prefix);
|
||||||
|
+
|
||||||
|
+ /* save ip header */
|
||||||
|
+ skb_copy_bits(skb, 0, &iph, sizeof(iph));
|
||||||
|
+ memcpy(&msg.ip, &iph, sizeof(struct iphdr));
|
||||||
|
+
|
||||||
|
+ /* save transport header */
|
||||||
|
+ switch (iph.protocol){
|
||||||
|
+ case IPPROTO_TCP:
|
||||||
|
+ skb_copy_bits(skb, iph.ihl*4 , &tcph, sizeof(tcph));
|
||||||
|
+ memcpy(&msg.h.th, &tcph, sizeof(struct tcphdr));
|
||||||
|
+ break;
|
||||||
|
+ case IPPROTO_UDP:
|
||||||
|
+ skb_copy_bits(skb, iph.ihl*4 , &udph, sizeof(udph));
|
||||||
|
+ memcpy(&msg.h.uh, &udph, sizeof(struct udphdr));
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* save timetamp */
|
||||||
|
+ do_gettimeofday((struct timeval *)&tv);
|
||||||
|
+ msg.timestamp_sec = tv.tv_sec;
|
||||||
|
+
|
||||||
|
+ send_packet(msg);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb,
|
||||||
|
+ const struct net_device *in,
|
||||||
|
+ const struct net_device *out,
|
||||||
|
+ unsigned int hooknum,
|
||||||
|
+ const void *targinfo,
|
||||||
|
+ void *userinfo)
|
||||||
|
+{
|
||||||
|
+ const struct ipt_IFWLOG_info *info = targinfo;
|
||||||
|
+
|
||||||
|
+ ipt_IFWLOG_packet(*pskb, in, out, info);
|
||||||
|
+
|
||||||
|
+ return IPT_CONTINUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ipt_IFWLOG_checkentry(const char *tablename,
|
||||||
|
+ const struct ipt_entry *e,
|
||||||
|
+ void *targinfo,
|
||||||
|
+ unsigned int targinfosize,
|
||||||
|
+ unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+ const struct ipt_IFWLOG_info *info = targinfo;
|
||||||
|
+
|
||||||
|
+ if (info->prefix[sizeof(info->prefix)-1] != '\0') {
|
||||||
|
+ DEBUGP("IFWLOG: prefix term %i\n",
|
||||||
|
+ info->prefix[sizeof(info->prefix)-1]);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct ipt_target ipt_IFWLOG = {
|
||||||
|
+ .name = "IFWLOG",
|
||||||
|
+ .target = ipt_IFWLOG_target,
|
||||||
|
+ .targetsize = sizeof(struct ipt_IFWLOG_info),
|
||||||
|
+ .checkentry = ipt_IFWLOG_checkentry,
|
||||||
|
+ .me = THIS_MODULE,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init init(void)
|
||||||
|
+{
|
||||||
|
+ nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE);
|
||||||
|
+ if (!nl) {
|
||||||
|
+ PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ipt_register_target(&ipt_IFWLOG)) {
|
||||||
|
+ if (nl && nl->sk_socket)
|
||||||
|
+ sock_release(nl->sk_socket);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ PRINTR(KERN_INFO "IFWLOG: register target\n");
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit fini(void)
|
||||||
|
+{
|
||||||
|
+ if (nl && nl->sk_socket)
|
||||||
|
+ sock_release(nl->sk_socket);
|
||||||
|
+ PRINTR(KERN_INFO "IFWLOG: unregister target\n");
|
||||||
|
+ ipt_unregister_target(&ipt_IFWLOG);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
||||||
|
--- a/net/ipv4/netfilter/Kconfig
|
||||||
|
+++ b/net/ipv4/netfilter/Kconfig
|
||||||
|
@@ -331,6 +331,17 @@ config IP_NF_TARGET_TTL
|
||||||
|
(e.g. when running oldconfig). It selects
|
||||||
|
CONFIG_NETFILTER_XT_TARGET_HL.
|
||||||
|
|
||||||
|
+config IP_NF_TARGET_IFWLOG
|
||||||
|
+ tristate 'IFWLOG target support'
|
||||||
|
+ depends on IP_NF_IPTABLES
|
||||||
|
+ help
|
||||||
|
+ This option adds a `IFWLOG' target, which is used by
|
||||||
|
+ Interactive Firewall for sending informations to a userspace
|
||||||
|
+ daemon
|
||||||
|
+
|
||||||
|
+ If you want to compile it as a module, say M here and read
|
||||||
|
+ Documentation/modules.txt. If unsure, say `N'.
|
||||||
|
+
|
||||||
|
# raw + specific targets
|
||||||
|
config IP_NF_RAW
|
||||||
|
tristate 'raw table support (required for NOTRACK/TRACE)'
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/linux/netfilter_ipv4/ipt_IFWLOG.h
|
||||||
|
@@ -0,0 +1,26 @@
|
||||||
|
+#ifndef _IPT_IFWLOG_H
|
||||||
|
+#define _IPT_IFWLOG_H
|
||||||
|
+
|
||||||
|
+#ifndef NETLINK_IFWLOG
|
||||||
|
+#define NETLINK_IFWLOG 19
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define PREFSIZ 32
|
||||||
|
+
|
||||||
|
+struct nl_msg { /* Netlink message */
|
||||||
|
+ long timestamp_sec; /* time packet */
|
||||||
|
+ char indev_name[IFNAMSIZ]; /* name of the ingoing interface */
|
||||||
|
+ char outdev_name[IFNAMSIZ]; /* name of the outgoing interface */
|
||||||
|
+ unsigned char prefix[PREFSIZ]; /* informations on the logging reason */
|
||||||
|
+ struct iphdr ip;
|
||||||
|
+ union {
|
||||||
|
+ struct tcphdr th;
|
||||||
|
+ struct udphdr uh;
|
||||||
|
+ } h;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct ipt_IFWLOG_info {
|
||||||
|
+ char prefix[PREFSIZ];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /* _IPT_IFWLOG_H */
|
||||||
|
--- linux/net/ipv4/netfilter/Makefile.net-netfilter-IFWLOG.orig 2012-05-21 01:29:13.000000000 +0300
|
||||||
|
+++ linux/net/ipv4/netfilter/Makefile 2012-05-26 01:23:57.511514194 +0300
|
||||||
|
@@ -53,6 +53,7 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ip
|
||||||
|
|
||||||
|
# targets
|
||||||
|
obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
|
||||||
|
+obj-$(CONFIG_IP_NF_TARGET_IFWLOG) += ipt_IFWLOG.o
|
||||||
|
obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
|
||||||
|
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
||||||
|
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|
11
3.2.34/net-netfilter-psd-2.6.35-buildfix.patch
Normal file
11
3.2.34/net-netfilter-psd-2.6.35-buildfix.patch
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
--- linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_psd.c.orig 2010-07-30 21:17:30.000000000 +0300
|
||||||
|
+++ linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_psd.c 2010-07-31 13:29:00.623601957 +0300
|
||||||
|
@@ -98,7 +98,7 @@ static inline int hashfunc(struct in_add
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ipt_psd_match(const struct sk_buff *pskb,
|
||||||
|
- const struct xt_match_param *match_param)
|
||||||
|
+ struct xt_action_param *match_param)
|
||||||
|
{
|
||||||
|
struct iphdr *ip_hdr;
|
||||||
|
struct tcphdr *tcp_hdr;
|
235
3.2.34/net-netfilter-psd-mdv.patch
Normal file
235
3.2.34/net-netfilter-psd-mdv.patch
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
ipt_psd: Mandriva changes
|
||||||
|
|
||||||
|
This patch holds all the Mandriva changes done in ipt_psd
|
||||||
|
netfilter module.
|
||||||
|
|
||||||
|
Most of the time they're just upgrades to match with new
|
||||||
|
API in the kernel.
|
||||||
|
|
||||||
|
This work is mostly done by Thomas Backlund, Herton R.
|
||||||
|
Krzesinski and Luiz Fernando N. Capitulino.
|
||||||
|
|
||||||
|
Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
|
||||||
|
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||||
|
|
||||||
|
---
|
||||||
|
include/linux/netfilter_ipv4/Kbuild | 1
|
||||||
|
net/ipv4/netfilter/Kconfig | 8 ++
|
||||||
|
net/ipv4/netfilter/ipt_psd.c | 113 ++++++++++++++----------------------
|
||||||
|
3 files changed, 55 insertions(+), 67 deletions(-)
|
||||||
|
|
||||||
|
diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_psd.c
|
||||||
|
--- linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig 2008-12-12 11:03:05.000000000 -0500
|
||||||
|
+++ linux-2.6.28/net/ipv4/netfilter/ipt_psd.c 2008-12-12 11:04:03.000000000 -0500
|
||||||
|
@@ -1,21 +1,24 @@
|
||||||
|
/*
|
||||||
|
- This is a module which is used for PSD (portscan detection)
|
||||||
|
- Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
|
||||||
|
- and LOG target module.
|
||||||
|
-
|
||||||
|
- Copyright (C) 2000,2001 astaro AG
|
||||||
|
-
|
||||||
|
- This file is distributed under the terms of the GNU General Public
|
||||||
|
- License (GPL). Copies of the GPL can be obtained from:
|
||||||
|
- ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||||
|
-
|
||||||
|
- 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
|
||||||
|
- 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
|
||||||
|
- 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
|
||||||
|
- 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
|
||||||
|
- 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
|
||||||
|
- 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
|
||||||
|
-*/
|
||||||
|
+ * This is a module which is used for PSD (portscan detection)
|
||||||
|
+ * Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
|
||||||
|
+ * and LOG target module.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2000,2001 astaro AG
|
||||||
|
+ *
|
||||||
|
+ * This file is distributed under the terms of the GNU General Public
|
||||||
|
+ * License (GPL). Copies of the GPL can be obtained from:
|
||||||
|
+ * ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||||
|
+ *
|
||||||
|
+ * 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
|
||||||
|
+ * 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
|
||||||
|
+ * 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
|
||||||
|
+ * 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
|
||||||
|
+ * 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
|
||||||
|
+ * 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
|
||||||
|
+ * 2007-10-10 Thomas Backlund <tmb@mandriva.org>: 2.6.22 update
|
||||||
|
+ * 2007-11-14 Luiz Capitulino <lcapitulino@mandriva.com> : 2.6.22 API usage fixes
|
||||||
|
+ * 2007-11-26 Herton Ronaldo Krzesinski <herton@mandriva.com>: switch xt_match->match to bool
|
||||||
|
+ */
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
@@ -54,7 +57,7 @@ struct port {
|
||||||
|
*/
|
||||||
|
struct host {
|
||||||
|
struct host *next; /* Next entry with the same hash */
|
||||||
|
- clock_t timestamp; /* Last update time */
|
||||||
|
+ unsigned long timestamp; /* Last update time */
|
||||||
|
struct in_addr src_addr; /* Source address */
|
||||||
|
struct in_addr dest_addr; /* Destination address */
|
||||||
|
unsigned short src_port; /* Source port */
|
||||||
|
@@ -93,33 +96,29 @@ static inline int hashfunc(struct in_add
|
||||||
|
return hash & (HASH_SIZE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
+static bool
|
||||||
|
ipt_psd_match(const struct sk_buff *pskb,
|
||||||
|
- const struct net_device *in,
|
||||||
|
- const struct net_device *out,
|
||||||
|
- const void *matchinfo,
|
||||||
|
- int offset,
|
||||||
|
- int *hotdrop)
|
||||||
|
+ const struct xt_match_param *match_param)
|
||||||
|
{
|
||||||
|
struct iphdr *ip_hdr;
|
||||||
|
struct tcphdr *tcp_hdr;
|
||||||
|
struct in_addr addr;
|
||||||
|
u_int16_t src_port,dest_port;
|
||||||
|
u_int8_t tcp_flags, proto;
|
||||||
|
- clock_t now;
|
||||||
|
+ unsigned long now;
|
||||||
|
struct host *curr, *last, **head;
|
||||||
|
int hash, index, count;
|
||||||
|
|
||||||
|
/* Parameters from userspace */
|
||||||
|
- const struct ipt_psd_info *psdinfo = matchinfo;
|
||||||
|
+ const struct ipt_psd_info *psdinfo = match_param->matchinfo;
|
||||||
|
|
||||||
|
/* IP header */
|
||||||
|
- ip_hdr = pskb->nh.iph;
|
||||||
|
+ ip_hdr = ipip_hdr(pskb);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
|
||||||
|
DEBUGP("PSD: sanity check failed\n");
|
||||||
|
- return 0;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TCP or UDP ? */
|
||||||
|
@@ -127,7 +126,7 @@ ipt_psd_match(const struct sk_buff *pskb
|
||||||
|
|
||||||
|
if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
|
||||||
|
DEBUGP("PSD: protocol not supported\n");
|
||||||
|
- return 0;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the source address, source & destination ports, and TCP flags */
|
||||||
|
@@ -151,7 +150,7 @@ ipt_psd_match(const struct sk_buff *pskb
|
||||||
|
* them spoof us. [DHCP needs this feature - HW] */
|
||||||
|
if (!addr.s_addr) {
|
||||||
|
DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
|
||||||
|
- return 0;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use jiffies here not to depend on someone setting the time while we're
|
||||||
|
@@ -298,46 +297,26 @@ ipt_psd_match(const struct sk_buff *pskb
|
||||||
|
|
||||||
|
out_no_match:
|
||||||
|
spin_unlock(&state.lock);
|
||||||
|
- return 0;
|
||||||
|
+ return false;
|
||||||
|
|
||||||
|
out_match:
|
||||||
|
spin_unlock(&state.lock);
|
||||||
|
- return 1;
|
||||||
|
+ DEBUGP("PSD: Dropping packets from "NIPQUAD_FMT" \n",
|
||||||
|
+ NIPQUAD(curr->src_addr.s_addr));
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int ipt_psd_checkentry(const char *tablename,
|
||||||
|
- const struct ipt_ip *e,
|
||||||
|
- void *matchinfo,
|
||||||
|
- unsigned int matchsize,
|
||||||
|
- unsigned int hook_mask)
|
||||||
|
-{
|
||||||
|
-/* const struct ipt_psd_info *psdinfo = targinfo;*/
|
||||||
|
-
|
||||||
|
- /* we accept TCP only */
|
||||||
|
-/* if (e->ip.proto != IPPROTO_TCP) { */
|
||||||
|
-/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
|
||||||
|
-/* return 0; */
|
||||||
|
-/* } */
|
||||||
|
-
|
||||||
|
- if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
|
||||||
|
- DEBUGP("PSD: matchsize %u != %u\n",
|
||||||
|
- matchsize,
|
||||||
|
- IPT_ALIGN(sizeof(struct ipt_psd_info)));
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static struct ipt_match ipt_psd_reg = {
|
||||||
|
- .name = "psd",
|
||||||
|
- .match = ipt_psd_match,
|
||||||
|
- .checkentry = ipt_psd_checkentry,
|
||||||
|
- .me = THIS_MODULE };
|
||||||
|
+static struct xt_match ipt_psd_reg = {
|
||||||
|
+ .name = "psd",
|
||||||
|
+ .family = AF_INET,
|
||||||
|
+ .match = ipt_psd_match,
|
||||||
|
+ .matchsize = sizeof(struct ipt_psd_info),
|
||||||
|
+ .me = THIS_MODULE
|
||||||
|
+};
|
||||||
|
|
||||||
|
-static int __init init(void)
|
||||||
|
+static int __init ipt_psd_init(void)
|
||||||
|
{
|
||||||
|
- if (ipt_register_match(&ipt_psd_reg))
|
||||||
|
+ if (xt_register_match(&ipt_psd_reg))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
memset(&state, 0, sizeof(state));
|
||||||
|
@@ -348,11 +327,11 @@ static int __init init(void)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void __exit fini(void)
|
||||||
|
+static void __exit ipt_psd_fini(void)
|
||||||
|
{
|
||||||
|
- ipt_unregister_match(&ipt_psd_reg);
|
||||||
|
+ xt_unregister_match(&ipt_psd_reg);
|
||||||
|
printk("netfilter PSD unloaded - (c) astaro AG\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
-module_init(init);
|
||||||
|
-module_exit(fini);
|
||||||
|
+module_init(ipt_psd_init);
|
||||||
|
+module_exit(ipt_psd_fini);
|
||||||
|
--- a/net/ipv4/netfilter/Kconfig
|
||||||
|
+++ b/net/ipv4/netfilter/Kconfig
|
||||||
|
@@ -322,6 +322,14 @@
|
||||||
|
(e.g. when running oldconfig). It selects
|
||||||
|
CONFIG_NETFILTER_XT_TARGET_HL.
|
||||||
|
|
||||||
|
+config IP_NF_MATCH_PSD
|
||||||
|
+ tristate 'Port scanner detection support'
|
||||||
|
+ depends on NETFILTER_ADVANCED
|
||||||
|
+ help
|
||||||
|
+ Module used for PSD (portscan detection).
|
||||||
|
+
|
||||||
|
+ To compile it as a module, choose M here. If unsure, say N.
|
||||||
|
+
|
||||||
|
config IP_NF_TARGET_IFWLOG
|
||||||
|
tristate 'IFWLOG target support'
|
||||||
|
depends on IP_NF_IPTABLES
|
||||||
|
--- linux/include/linux/netfilter_ipv4/Kbuild.net-netfilter-psd-mdv.orig 2012-05-26 01:28:56.000000000 +0300
|
||||||
|
+++ linux/include/linux/netfilter_ipv4/Kbuild 2012-05-26 01:30:21.493540796 +0300
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
header-y += ipt_addrtype.h
|
||||||
|
header-y += ipt_ah.h
|
||||||
|
header-y += ipt_ecn.h
|
||||||
|
+header-y += ipt_psd.h
|
||||||
|
header-y += ipt_realm.h
|
||||||
|
header-y += ipt_ttl.h
|
||||||
|
header-y += nf_nat.h
|
420
3.2.34/net-netfilter-psd.patch
Normal file
420
3.2.34/net-netfilter-psd.patch
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
---
|
||||||
|
include/linux/netfilter_ipv4/ipt_psd.h | 40 +++
|
||||||
|
net/ipv4/netfilter/Makefile | 1
|
||||||
|
net/ipv4/netfilter/ipt_psd.c | 358 +++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 399 insertions(+)
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/net/ipv4/netfilter/ipt_psd.c
|
||||||
|
@@ -0,0 +1,358 @@
|
||||||
|
+/*
|
||||||
|
+ This is a module which is used for PSD (portscan detection)
|
||||||
|
+ Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
|
||||||
|
+ and LOG target module.
|
||||||
|
+
|
||||||
|
+ Copyright (C) 2000,2001 astaro AG
|
||||||
|
+
|
||||||
|
+ This file is distributed under the terms of the GNU General Public
|
||||||
|
+ License (GPL). Copies of the GPL can be obtained from:
|
||||||
|
+ ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||||
|
+
|
||||||
|
+ 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
|
||||||
|
+ 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
|
||||||
|
+ 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
|
||||||
|
+ 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
|
||||||
|
+ 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
|
||||||
|
+ 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/ip.h>
|
||||||
|
+#include <net/tcp.h>
|
||||||
|
+#include <linux/spinlock.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ipt_psd.h>
|
||||||
|
+
|
||||||
|
+#if 0
|
||||||
|
+#define DEBUGP printk
|
||||||
|
+#else
|
||||||
|
+#define DEBUGP(format, args...)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
|
||||||
|
+
|
||||||
|
+#define HF_DADDR_CHANGING 0x01
|
||||||
|
+#define HF_SPORT_CHANGING 0x02
|
||||||
|
+#define HF_TOS_CHANGING 0x04
|
||||||
|
+#define HF_TTL_CHANGING 0x08
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Information we keep per each target port
|
||||||
|
+ */
|
||||||
|
+struct port {
|
||||||
|
+ u_int16_t number; /* port number */
|
||||||
|
+ u_int8_t proto; /* protocol number */
|
||||||
|
+ u_int8_t and_flags; /* tcp ANDed flags */
|
||||||
|
+ u_int8_t or_flags; /* tcp ORed flags */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Information we keep per each source address.
|
||||||
|
+ */
|
||||||
|
+struct host {
|
||||||
|
+ struct host *next; /* Next entry with the same hash */
|
||||||
|
+ clock_t timestamp; /* Last update time */
|
||||||
|
+ struct in_addr src_addr; /* Source address */
|
||||||
|
+ struct in_addr dest_addr; /* Destination address */
|
||||||
|
+ unsigned short src_port; /* Source port */
|
||||||
|
+ int count; /* Number of ports in the list */
|
||||||
|
+ int weight; /* Total weight of ports in the list */
|
||||||
|
+ struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
|
||||||
|
+ unsigned char tos; /* TOS */
|
||||||
|
+ unsigned char ttl; /* TTL */
|
||||||
|
+ unsigned char flags; /* HF_ flags bitmask */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * State information.
|
||||||
|
+ */
|
||||||
|
+static struct {
|
||||||
|
+ spinlock_t lock;
|
||||||
|
+ struct host list[LIST_SIZE]; /* List of source addresses */
|
||||||
|
+ struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
|
||||||
|
+ int index; /* Oldest entry to be replaced */
|
||||||
|
+} state;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Convert an IP address into a hash table index.
|
||||||
|
+ */
|
||||||
|
+static inline int hashfunc(struct in_addr addr)
|
||||||
|
+{
|
||||||
|
+ unsigned int value;
|
||||||
|
+ int hash;
|
||||||
|
+
|
||||||
|
+ value = addr.s_addr;
|
||||||
|
+ hash = 0;
|
||||||
|
+ do {
|
||||||
|
+ hash ^= value;
|
||||||
|
+ } while ((value >>= HASH_LOG));
|
||||||
|
+
|
||||||
|
+ return hash & (HASH_SIZE - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ipt_psd_match(const struct sk_buff *pskb,
|
||||||
|
+ const struct net_device *in,
|
||||||
|
+ const struct net_device *out,
|
||||||
|
+ const void *matchinfo,
|
||||||
|
+ int offset,
|
||||||
|
+ int *hotdrop)
|
||||||
|
+{
|
||||||
|
+ struct iphdr *ip_hdr;
|
||||||
|
+ struct tcphdr *tcp_hdr;
|
||||||
|
+ struct in_addr addr;
|
||||||
|
+ u_int16_t src_port,dest_port;
|
||||||
|
+ u_int8_t tcp_flags, proto;
|
||||||
|
+ clock_t now;
|
||||||
|
+ struct host *curr, *last, **head;
|
||||||
|
+ int hash, index, count;
|
||||||
|
+
|
||||||
|
+ /* Parameters from userspace */
|
||||||
|
+ const struct ipt_psd_info *psdinfo = matchinfo;
|
||||||
|
+
|
||||||
|
+ /* IP header */
|
||||||
|
+ ip_hdr = pskb->nh.iph;
|
||||||
|
+
|
||||||
|
+ /* Sanity check */
|
||||||
|
+ if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
|
||||||
|
+ DEBUGP("PSD: sanity check failed\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* TCP or UDP ? */
|
||||||
|
+ proto = ip_hdr->protocol;
|
||||||
|
+
|
||||||
|
+ if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
|
||||||
|
+ DEBUGP("PSD: protocol not supported\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get the source address, source & destination ports, and TCP flags */
|
||||||
|
+
|
||||||
|
+ addr.s_addr = ip_hdr->saddr;
|
||||||
|
+
|
||||||
|
+ tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
|
||||||
|
+
|
||||||
|
+ /* Yep, it´s dirty */
|
||||||
|
+ src_port = tcp_hdr->source;
|
||||||
|
+ dest_port = tcp_hdr->dest;
|
||||||
|
+
|
||||||
|
+ if (proto == IPPROTO_TCP) {
|
||||||
|
+ tcp_flags = *((u_int8_t*)tcp_hdr + 13);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ tcp_flags = 0x00;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
|
||||||
|
+ * them spoof us. [DHCP needs this feature - HW] */
|
||||||
|
+ if (!addr.s_addr) {
|
||||||
|
+ DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Use jiffies here not to depend on someone setting the time while we're
|
||||||
|
+ * running; we need to be careful with possible return value overflows. */
|
||||||
|
+ now = jiffies;
|
||||||
|
+
|
||||||
|
+ spin_lock(&state.lock);
|
||||||
|
+
|
||||||
|
+ /* Do we know this source address already? */
|
||||||
|
+ count = 0;
|
||||||
|
+ last = NULL;
|
||||||
|
+ if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
|
||||||
|
+ do {
|
||||||
|
+ if (curr->src_addr.s_addr == addr.s_addr) break;
|
||||||
|
+ count++;
|
||||||
|
+ if (curr->next) last = curr;
|
||||||
|
+ } while ((curr = curr->next));
|
||||||
|
+
|
||||||
|
+ if (curr) {
|
||||||
|
+
|
||||||
|
+ /* We know this address, and the entry isn't too old. Update it. */
|
||||||
|
+ if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
|
||||||
|
+ time_after_eq(now, curr->timestamp)) {
|
||||||
|
+
|
||||||
|
+ /* Just update the appropriate list entry if we've seen this port already */
|
||||||
|
+ for (index = 0; index < curr->count; index++) {
|
||||||
|
+ if (curr->ports[index].number == dest_port) {
|
||||||
|
+ curr->ports[index].proto = proto;
|
||||||
|
+ curr->ports[index].and_flags &= tcp_flags;
|
||||||
|
+ curr->ports[index].or_flags |= tcp_flags;
|
||||||
|
+ goto out_no_match;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
|
||||||
|
+ if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
|
||||||
|
+ goto out_no_match;
|
||||||
|
+
|
||||||
|
+ /* Packet to a new port, and not TCP/ACK: update the timestamp */
|
||||||
|
+ curr->timestamp = now;
|
||||||
|
+
|
||||||
|
+ /* Logged this scan already? Then drop the packet. */
|
||||||
|
+ if (curr->weight >= psdinfo->weight_threshold)
|
||||||
|
+ goto out_match;
|
||||||
|
+
|
||||||
|
+ /* Specify if destination address, source port, TOS or TTL are not fixed */
|
||||||
|
+ if (curr->dest_addr.s_addr != ip_hdr->daddr)
|
||||||
|
+ curr->flags |= HF_DADDR_CHANGING;
|
||||||
|
+ if (curr->src_port != src_port)
|
||||||
|
+ curr->flags |= HF_SPORT_CHANGING;
|
||||||
|
+ if (curr->tos != ip_hdr->tos)
|
||||||
|
+ curr->flags |= HF_TOS_CHANGING;
|
||||||
|
+ if (curr->ttl != ip_hdr->ttl)
|
||||||
|
+ curr->flags |= HF_TTL_CHANGING;
|
||||||
|
+
|
||||||
|
+ /* Update the total weight */
|
||||||
|
+ curr->weight += (ntohs(dest_port) < 1024) ?
|
||||||
|
+ psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
|
||||||
|
+
|
||||||
|
+ /* Got enough destination ports to decide that this is a scan? */
|
||||||
|
+ /* Then log it and drop the packet. */
|
||||||
|
+ if (curr->weight >= psdinfo->weight_threshold)
|
||||||
|
+ goto out_match;
|
||||||
|
+
|
||||||
|
+ /* Remember the new port */
|
||||||
|
+ if (curr->count < SCAN_MAX_COUNT) {
|
||||||
|
+ curr->ports[curr->count].number = dest_port;
|
||||||
|
+ curr->ports[curr->count].proto = proto;
|
||||||
|
+ curr->ports[curr->count].and_flags = tcp_flags;
|
||||||
|
+ curr->ports[curr->count].or_flags = tcp_flags;
|
||||||
|
+ curr->count++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ goto out_no_match;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We know this address, but the entry is outdated. Mark it unused, and
|
||||||
|
+ * remove from the hash table. We'll allocate a new entry instead since
|
||||||
|
+ * this one might get re-used too soon. */
|
||||||
|
+ curr->src_addr.s_addr = 0;
|
||||||
|
+ if (last)
|
||||||
|
+ last->next = last->next->next;
|
||||||
|
+ else if (*head)
|
||||||
|
+ *head = (*head)->next;
|
||||||
|
+ last = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We don't need an ACK from a new source address */
|
||||||
|
+ if (proto == IPPROTO_TCP && tcp_hdr->ack)
|
||||||
|
+ goto out_no_match;
|
||||||
|
+
|
||||||
|
+ /* Got too many source addresses with the same hash value? Then remove the
|
||||||
|
+ * oldest one from the hash table, so that they can't take too much of our
|
||||||
|
+ * CPU time even with carefully chosen spoofed IP addresses. */
|
||||||
|
+ if (count >= HASH_MAX && last) last->next = NULL;
|
||||||
|
+
|
||||||
|
+ /* We're going to re-use the oldest list entry, so remove it from the hash
|
||||||
|
+ * table first (if it is really already in use, and isn't removed from the
|
||||||
|
+ * hash table already because of the HASH_MAX check above). */
|
||||||
|
+
|
||||||
|
+ /* First, find it */
|
||||||
|
+ if (state.list[state.index].src_addr.s_addr)
|
||||||
|
+ head = &state.hash[hashfunc(state.list[state.index].src_addr)];
|
||||||
|
+ else
|
||||||
|
+ head = &last;
|
||||||
|
+ last = NULL;
|
||||||
|
+ if ((curr = *head))
|
||||||
|
+ do {
|
||||||
|
+ if (curr == &state.list[state.index]) break;
|
||||||
|
+ last = curr;
|
||||||
|
+ } while ((curr = curr->next));
|
||||||
|
+
|
||||||
|
+ /* Then, remove it */
|
||||||
|
+ if (curr) {
|
||||||
|
+ if (last)
|
||||||
|
+ last->next = last->next->next;
|
||||||
|
+ else if (*head)
|
||||||
|
+ *head = (*head)->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get our list entry */
|
||||||
|
+ curr = &state.list[state.index++];
|
||||||
|
+ if (state.index >= LIST_SIZE) state.index = 0;
|
||||||
|
+
|
||||||
|
+ /* Link it into the hash table */
|
||||||
|
+ head = &state.hash[hash];
|
||||||
|
+ curr->next = *head;
|
||||||
|
+ *head = curr;
|
||||||
|
+
|
||||||
|
+ /* And fill in the fields */
|
||||||
|
+ curr->timestamp = now;
|
||||||
|
+ curr->src_addr = addr;
|
||||||
|
+ curr->dest_addr.s_addr = ip_hdr->daddr;
|
||||||
|
+ curr->src_port = src_port;
|
||||||
|
+ curr->count = 1;
|
||||||
|
+ curr->weight = (ntohs(dest_port) < 1024) ?
|
||||||
|
+ psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
|
||||||
|
+ curr->ports[0].number = dest_port;
|
||||||
|
+ curr->ports[0].proto = proto;
|
||||||
|
+ curr->ports[0].and_flags = tcp_flags;
|
||||||
|
+ curr->ports[0].or_flags = tcp_flags;
|
||||||
|
+ curr->tos = ip_hdr->tos;
|
||||||
|
+ curr->ttl = ip_hdr->ttl;
|
||||||
|
+
|
||||||
|
+out_no_match:
|
||||||
|
+ spin_unlock(&state.lock);
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+out_match:
|
||||||
|
+ spin_unlock(&state.lock);
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ipt_psd_checkentry(const char *tablename,
|
||||||
|
+ const struct ipt_ip *e,
|
||||||
|
+ void *matchinfo,
|
||||||
|
+ unsigned int matchsize,
|
||||||
|
+ unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+/* const struct ipt_psd_info *psdinfo = targinfo;*/
|
||||||
|
+
|
||||||
|
+ /* we accept TCP only */
|
||||||
|
+/* if (e->ip.proto != IPPROTO_TCP) { */
|
||||||
|
+/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
|
||||||
|
+/* return 0; */
|
||||||
|
+/* } */
|
||||||
|
+
|
||||||
|
+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
|
||||||
|
+ DEBUGP("PSD: matchsize %u != %u\n",
|
||||||
|
+ matchsize,
|
||||||
|
+ IPT_ALIGN(sizeof(struct ipt_psd_info)));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct ipt_match ipt_psd_reg = {
|
||||||
|
+ .name = "psd",
|
||||||
|
+ .match = ipt_psd_match,
|
||||||
|
+ .checkentry = ipt_psd_checkentry,
|
||||||
|
+ .me = THIS_MODULE };
|
||||||
|
+
|
||||||
|
+static int __init init(void)
|
||||||
|
+{
|
||||||
|
+ if (ipt_register_match(&ipt_psd_reg))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ memset(&state, 0, sizeof(state));
|
||||||
|
+
|
||||||
|
+ spin_lock_init(&(state.lock));
|
||||||
|
+
|
||||||
|
+ printk("netfilter PSD loaded - (c) astaro AG\n");
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit fini(void)
|
||||||
|
+{
|
||||||
|
+ ipt_unregister_match(&ipt_psd_reg);
|
||||||
|
+ printk("netfilter PSD unloaded - (c) astaro AG\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/linux/netfilter_ipv4/ipt_psd.h
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+#ifndef _IPT_PSD_H
|
||||||
|
+#define _IPT_PSD_H
|
||||||
|
+
|
||||||
|
+#include <linux/param.h>
|
||||||
|
+#include <linux/types.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * High port numbers have a lower weight to reduce the frequency of false
|
||||||
|
+ * positives, such as from passive mode FTP transfers.
|
||||||
|
+ */
|
||||||
|
+#define PORT_WEIGHT_PRIV 3
|
||||||
|
+#define PORT_WEIGHT_HIGH 1
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Port scan detection thresholds: at least COUNT ports need to be scanned
|
||||||
|
+ * from the same source, with no longer than DELAY ticks between ports.
|
||||||
|
+ */
|
||||||
|
+#define SCAN_MIN_COUNT 7
|
||||||
|
+#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
|
||||||
|
+#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
|
||||||
|
+#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Keep track of up to LIST_SIZE source addresses, using a hash table of
|
||||||
|
+ * HASH_SIZE entries for faster lookups, but limiting hash collisions to
|
||||||
|
+ * HASH_MAX source addresses per the same hash value.
|
||||||
|
+ */
|
||||||
|
+#define LIST_SIZE 0x100
|
||||||
|
+#define HASH_LOG 9
|
||||||
|
+#define HASH_SIZE (1 << HASH_LOG)
|
||||||
|
+#define HASH_MAX 0x10
|
||||||
|
+
|
||||||
|
+struct ipt_psd_info {
|
||||||
|
+ unsigned int weight_threshold;
|
||||||
|
+ unsigned int delay_threshold;
|
||||||
|
+ unsigned short lo_ports_weight;
|
||||||
|
+ unsigned short hi_ports_weight;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /*_IPT_PSD_H*/
|
||||||
|
--- a/net/ipv4/netfilter/Makefile
|
||||||
|
+++ b/net/ipv4/netfilter/Makefile
|
||||||
|
@@ -49,6 +49,7 @@
|
||||||
|
|
||||||
|
# matches
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
|
||||||
|
+obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
|
||||||
|
|
||||||
|
# targets
|
190
3.2.34/netfilter-implement-rfc-1123-for-ftp-conntrack.patch
Normal file
190
3.2.34/netfilter-implement-rfc-1123-for-ftp-conntrack.patch
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
From: Jeff Mahoney <jeffm@suse.com>
|
||||||
|
Subject: netfilter: Implement RFC 1123 for FTP conntrack
|
||||||
|
References: bnc#466279 bnc#681639
|
||||||
|
Patch-mainline: Submitted via http://bugzilla.netfilter.org/show_bug.cgi?id=574 23 Jan 2011
|
||||||
|
|
||||||
|
The FTP conntrack code currently only accepts the following format for
|
||||||
|
the 227 response for PASV:
|
||||||
|
227 Entering Passive Mode (148,100,81,40,31,161).
|
||||||
|
|
||||||
|
It doesn't accept the following format from an obscure server:
|
||||||
|
227 Data transfer will passively listen to 67,218,99,134,50,144
|
||||||
|
|
||||||
|
From RFC 1123:
|
||||||
|
The format of the 227 reply to a PASV command is not
|
||||||
|
well standardized. In particular, an FTP client cannot
|
||||||
|
assume that the parentheses shown on page 40 of RFC-959
|
||||||
|
will be present (and in fact, Figure 3 on page 43 omits
|
||||||
|
them). Therefore, a User-FTP program that interprets
|
||||||
|
the PASV reply must scan the reply for the first digit
|
||||||
|
of the host and port numbers.
|
||||||
|
|
||||||
|
This patch adds support for the RFC 1123 clarification by:
|
||||||
|
- Allowing a search filter to specify NUL as the terminator so that
|
||||||
|
try_number will return successfully if the array of numbers has been
|
||||||
|
filled when an unexpected character is encountered.
|
||||||
|
- Using space as the separator for the 227 reply and then scanning for
|
||||||
|
the first digit of the number sequence. The number sequence is parsed
|
||||||
|
out using the existing try_rfc959 but with a NUL terminator.
|
||||||
|
|
||||||
|
Tracked in: https://bugzilla.novell.com/show_bug.cgi?id=466279
|
||||||
|
|
||||||
|
Reported-by: Mark Post <mpost@novell.com>
|
||||||
|
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||||
|
---
|
||||||
|
net/netfilter/nf_conntrack_ftp.c | 73 ++++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 54 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
--- a/net/netfilter/nf_conntrack_ftp.c
|
||||||
|
+++ b/net/netfilter/nf_conntrack_ftp.c
|
||||||
|
@@ -53,10 +53,14 @@ unsigned int (*nf_nat_ftp_hook)(struct s
|
||||||
|
struct nf_conntrack_expect *exp);
|
||||||
|
EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
|
||||||
|
|
||||||
|
-static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
|
||||||
|
-static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
|
||||||
|
+static int try_rfc959(const char *, size_t, struct nf_conntrack_man *,
|
||||||
|
+ char, unsigned int *);
|
||||||
|
+static int try_rfc1123(const char *, size_t, struct nf_conntrack_man *,
|
||||||
|
+ char, unsigned int *);
|
||||||
|
+static int try_eprt(const char *, size_t, struct nf_conntrack_man *,
|
||||||
|
+ char, unsigned int *);
|
||||||
|
static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
|
||||||
|
- char);
|
||||||
|
+ char, unsigned int *);
|
||||||
|
|
||||||
|
static struct ftp_search {
|
||||||
|
const char *pattern;
|
||||||
|
@@ -64,7 +68,7 @@ static struct ftp_search {
|
||||||
|
char skip;
|
||||||
|
char term;
|
||||||
|
enum nf_ct_ftp_type ftptype;
|
||||||
|
- int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
|
||||||
|
+ int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char, unsigned int *);
|
||||||
|
} search[IP_CT_DIR_MAX][2] = {
|
||||||
|
[IP_CT_DIR_ORIGINAL] = {
|
||||||
|
{
|
||||||
|
@@ -88,10 +92,8 @@ static struct ftp_search {
|
||||||
|
{
|
||||||
|
.pattern = "227 ",
|
||||||
|
.plen = sizeof("227 ") - 1,
|
||||||
|
- .skip = '(',
|
||||||
|
- .term = ')',
|
||||||
|
.ftptype = NF_CT_FTP_PASV,
|
||||||
|
- .getnum = try_rfc959,
|
||||||
|
+ .getnum = try_rfc1123,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pattern = "229 ",
|
||||||
|
@@ -130,8 +132,9 @@ static int try_number(const char *data,
|
||||||
|
i++;
|
||||||
|
else {
|
||||||
|
/* Unexpected character; true if it's the
|
||||||
|
- terminator and we're finished. */
|
||||||
|
- if (*data == term && i == array_size - 1)
|
||||||
|
+ terminator (or we don't care about one)
|
||||||
|
+ and we're finished. */
|
||||||
|
+ if ((*data == term || !term) && i == array_size - 1)
|
||||||
|
return len;
|
||||||
|
|
||||||
|
pr_debug("Char %u (got %u nums) `%u' unexpected\n",
|
||||||
|
@@ -146,7 +149,8 @@ static int try_number(const char *data,
|
||||||
|
|
||||||
|
/* Returns 0, or length of numbers: 192,168,1,1,5,6 */
|
||||||
|
static int try_rfc959(const char *data, size_t dlen,
|
||||||
|
- struct nf_conntrack_man *cmd, char term)
|
||||||
|
+ struct nf_conntrack_man *cmd, char term,
|
||||||
|
+ unsigned int *offset)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
u_int32_t array[6];
|
||||||
|
@@ -161,6 +165,33 @@ static int try_rfc959(const char *data,
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * From RFC 1123:
|
||||||
|
+ * The format of the 227 reply to a PASV command is not
|
||||||
|
+ * well standardized. In particular, an FTP client cannot
|
||||||
|
+ * assume that the parentheses shown on page 40 of RFC-959
|
||||||
|
+ * will be present (and in fact, Figure 3 on page 43 omits
|
||||||
|
+ * them). Therefore, a User-FTP program that interprets
|
||||||
|
+ * the PASV reply must scan the reply for the first digit
|
||||||
|
+ * of the host and port numbers.
|
||||||
|
+ */
|
||||||
|
+static int try_rfc1123(const char *data, size_t dlen,
|
||||||
|
+ struct nf_conntrack_man *cmd, char term,
|
||||||
|
+ unsigned int *offset)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ for (i = 0; i < dlen; i++)
|
||||||
|
+ if (isdigit(data[i]))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (i == dlen)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ *offset += i;
|
||||||
|
+
|
||||||
|
+ return try_rfc959(data + i, dlen - i, cmd, 0, offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Grab port: number up to delimiter */
|
||||||
|
static int get_port(const char *data, int start, size_t dlen, char delim,
|
||||||
|
__be16 *port)
|
||||||
|
@@ -189,7 +220,7 @@ static int get_port(const char *data, in
|
||||||
|
|
||||||
|
/* Returns 0, or length of numbers: |1|132.235.1.2|6275| or |2|3ffe::1|6275| */
|
||||||
|
static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
|
||||||
|
- char term)
|
||||||
|
+ char term, unsigned int *offset)
|
||||||
|
{
|
||||||
|
char delim;
|
||||||
|
int length;
|
||||||
|
@@ -237,7 +268,8 @@ static int try_eprt(const char *data, si
|
||||||
|
|
||||||
|
/* Returns 0, or length of numbers: |||6446| */
|
||||||
|
static int try_epsv_response(const char *data, size_t dlen,
|
||||||
|
- struct nf_conntrack_man *cmd, char term)
|
||||||
|
+ struct nf_conntrack_man *cmd, char term,
|
||||||
|
+ unsigned int *offset)
|
||||||
|
{
|
||||||
|
char delim;
|
||||||
|
|
||||||
|
@@ -259,9 +291,10 @@ static int find_pattern(const char *data
|
||||||
|
unsigned int *numlen,
|
||||||
|
struct nf_conntrack_man *cmd,
|
||||||
|
int (*getnum)(const char *, size_t,
|
||||||
|
- struct nf_conntrack_man *, char))
|
||||||
|
+ struct nf_conntrack_man *, char,
|
||||||
|
+ unsigned int *))
|
||||||
|
{
|
||||||
|
- size_t i;
|
||||||
|
+ size_t i = plen;
|
||||||
|
|
||||||
|
pr_debug("find_pattern `%s': dlen = %Zu\n", pattern, dlen);
|
||||||
|
if (dlen == 0)
|
||||||
|
@@ -291,16 +324,18 @@ static int find_pattern(const char *data
|
||||||
|
pr_debug("Pattern matches!\n");
|
||||||
|
/* Now we've found the constant string, try to skip
|
||||||
|
to the 'skip' character */
|
||||||
|
- for (i = plen; data[i] != skip; i++)
|
||||||
|
- if (i == dlen - 1) return -1;
|
||||||
|
+ if (skip) {
|
||||||
|
+ for (i = plen; data[i] != skip; i++)
|
||||||
|
+ if (i == dlen - 1) return -1;
|
||||||
|
|
||||||
|
- /* Skip over the last character */
|
||||||
|
- i++;
|
||||||
|
+ /* Skip over the last character */
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
pr_debug("Skipped up to `%c'!\n", skip);
|
||||||
|
|
||||||
|
*numoff = i;
|
||||||
|
- *numlen = getnum(data + i, dlen - i, cmd, term);
|
||||||
|
+ *numlen = getnum(data + i, dlen - i, cmd, term, numoff);
|
||||||
|
if (!*numlen)
|
||||||
|
return -1;
|
||||||
|
|
185
3.2.34/netfilter-ip_conntrack_slp.patch
Normal file
185
3.2.34/netfilter-ip_conntrack_slp.patch
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
From: Jiri Bohac <jbohac@suse.cz>
|
||||||
|
Subject: connection tracking helper for SLP
|
||||||
|
References: fate#301134
|
||||||
|
Patch-mainline: Not yet
|
||||||
|
|
||||||
|
A simple connection tracking helper for SLP. Marks replies to a
|
||||||
|
SLP broadcast query as ESTABLISHED to allow them to pass through the
|
||||||
|
firewall.
|
||||||
|
|
||||||
|
Signed-off-by: Jiri Bohac <jbohac@suse.cz>
|
||||||
|
|
||||||
|
---
|
||||||
|
net/netfilter/Kconfig | 15 ++++
|
||||||
|
net/netfilter/Makefile | 1
|
||||||
|
net/netfilter/nf_conntrack_slp.c | 131 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 147 insertions(+)
|
||||||
|
|
||||||
|
--- a/net/netfilter/Kconfig
|
||||||
|
+++ b/net/netfilter/Kconfig
|
||||||
|
@@ -290,6 +290,21 @@ config NF_CONNTRACK_TFTP
|
||||||
|
|
||||||
|
To compile it as a module, choose M here. If unsure, say N.
|
||||||
|
|
||||||
|
+config NF_CONNTRACK_SLP
|
||||||
|
+ tristate "SLP protocol support"
|
||||||
|
+ depends on NF_CONNTRACK
|
||||||
|
+ depends on NETFILTER_ADVANCED
|
||||||
|
+ help
|
||||||
|
+ SLP queries are sometimes sent as broadcast messages from an
|
||||||
|
+ unprivileged port and responded to with unicast messages to the
|
||||||
|
+ same port. This make them hard to firewall properly because connection
|
||||||
|
+ tracking doesn't deal with broadcasts. This helper tracks locally
|
||||||
|
+ originating broadcast SLP queries and the corresponding
|
||||||
|
+ responses. It relies on correct IP address configuration, specifically
|
||||||
|
+ netmask and broadcast address.
|
||||||
|
+
|
||||||
|
+ To compile it as a module, choose M here. If unsure, say N.
|
||||||
|
+
|
||||||
|
config NF_CT_NETLINK
|
||||||
|
tristate 'Connection tracking netlink interface'
|
||||||
|
select NETFILTER_NETLINK
|
||||||
|
--- a/net/netfilter/Makefile
|
||||||
|
+++ b/net/netfilter/Makefile
|
||||||
|
@@ -36,6 +36,7 @@ obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_co
|
||||||
|
obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
|
||||||
|
obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
|
||||||
|
obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
|
||||||
|
+obj-$(CONFIG_NF_CONNTRACK_SLP) += nf_conntrack_slp.o
|
||||||
|
|
||||||
|
# transparent proxy support
|
||||||
|
obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/net/netfilter/nf_conntrack_slp.c
|
||||||
|
@@ -0,0 +1,131 @@
|
||||||
|
+/*
|
||||||
|
+ * NetBIOS name service broadcast connection tracking helper
|
||||||
|
+ *
|
||||||
|
+ * (c) 2007 Jiri Bohac <jbohac@suse.cz>
|
||||||
|
+ * (c) 2005 Patrick McHardy <kaber@trash.net>
|
||||||
|
+ *
|
||||||
|
+ * 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.
|
||||||
|
+ */
|
||||||
|
+/*
|
||||||
|
+ * This helper tracks locally originating NetBIOS name service
|
||||||
|
+ * requests by issuing permanent expectations (valid until
|
||||||
|
+ * timing out) matching all reply connections from the
|
||||||
|
+ * destination network. The only NetBIOS specific thing is
|
||||||
|
+ * actually the port number.
|
||||||
|
+ */
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/netdevice.h>
|
||||||
|
+#include <linux/inetdevice.h>
|
||||||
|
+#include <linux/if_addr.h>
|
||||||
|
+#include <linux/in.h>
|
||||||
|
+#include <linux/ip.h>
|
||||||
|
+#include <linux/netfilter.h>
|
||||||
|
+#include <net/route.h>
|
||||||
|
+
|
||||||
|
+#include <net/netfilter/nf_conntrack.h>
|
||||||
|
+#include <net/netfilter/nf_conntrack_helper.h>
|
||||||
|
+#include <net/netfilter/nf_conntrack_expect.h>
|
||||||
|
+
|
||||||
|
+#define SLP_PORT 427
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Jiri Bohac <jbohac@suse.cz>");
|
||||||
|
+MODULE_DESCRIPTION("SLP broadcast connection tracking helper");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+MODULE_ALIAS("ip_conntrack_slp");
|
||||||
|
+
|
||||||
|
+static unsigned int timeout __read_mostly = 3;
|
||||||
|
+module_param(timeout, uint, 0400);
|
||||||
|
+MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
|
||||||
|
+
|
||||||
|
+static int help(struct sk_buff *skb, unsigned int protoff,
|
||||||
|
+ struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||||
|
+{
|
||||||
|
+ struct nf_conntrack_expect *exp;
|
||||||
|
+ struct rtable *rt = skb_rtable(skb);
|
||||||
|
+ struct in_device *in_dev;
|
||||||
|
+ __be32 mask = 0;
|
||||||
|
+ __be32 src = 0;
|
||||||
|
+
|
||||||
|
+ /* we're only interested in locally generated packets */
|
||||||
|
+ if (skb->sk == NULL)
|
||||||
|
+ goto out;
|
||||||
|
+ if (rt == NULL || !(rt->rt_flags & (RTCF_MULTICAST|RTCF_BROADCAST)))
|
||||||
|
+ goto out;
|
||||||
|
+ if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ rcu_read_lock();
|
||||||
|
+ in_dev = __in_dev_get_rcu(rt->dst.dev);
|
||||||
|
+ if (in_dev != NULL) {
|
||||||
|
+ for_primary_ifa(in_dev) {
|
||||||
|
+ /* this is a hack as slp uses multicast we can't match
|
||||||
|
+ * the destination address to some broadcast address. So
|
||||||
|
+ * just take the first one. Better would be to install
|
||||||
|
+ * expectations for all addresses */
|
||||||
|
+ mask = ifa->ifa_mask;
|
||||||
|
+ src = ifa->ifa_broadcast;
|
||||||
|
+ break;
|
||||||
|
+ } endfor_ifa(in_dev);
|
||||||
|
+ }
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+
|
||||||
|
+ if (mask == 0 || src == 0)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ exp = nf_ct_expect_alloc(ct);
|
||||||
|
+ if (exp == NULL)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
||||||
|
+ exp->tuple.src.u3.ip = src;
|
||||||
|
+ exp->tuple.src.u.udp.port = htons(SLP_PORT);
|
||||||
|
+
|
||||||
|
+ exp->mask.src.u3.ip = mask;
|
||||||
|
+ exp->mask.src.u.udp.port = htons(0xFFFF);
|
||||||
|
+
|
||||||
|
+ exp->expectfn = NULL;
|
||||||
|
+ exp->flags = NF_CT_EXPECT_PERMANENT;
|
||||||
|
+ exp->class = NF_CT_EXPECT_CLASS_DEFAULT;
|
||||||
|
+ exp->helper = NULL;
|
||||||
|
+
|
||||||
|
+ nf_ct_expect_related(exp);
|
||||||
|
+ nf_ct_expect_put(exp);
|
||||||
|
+
|
||||||
|
+ nf_ct_refresh(ct, skb, timeout * HZ);
|
||||||
|
+out:
|
||||||
|
+ return NF_ACCEPT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct nf_conntrack_expect_policy exp_policy = {
|
||||||
|
+ .max_expected = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct nf_conntrack_helper helper __read_mostly = {
|
||||||
|
+ .name = "slp",
|
||||||
|
+ .tuple.src.l3num = AF_INET,
|
||||||
|
+ .tuple.src.u.udp.port = __constant_htons(SLP_PORT),
|
||||||
|
+ .tuple.dst.protonum = IPPROTO_UDP,
|
||||||
|
+ .me = THIS_MODULE,
|
||||||
|
+ .help = help,
|
||||||
|
+ .expect_policy = &exp_policy,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init nf_conntrack_slp_init(void)
|
||||||
|
+{
|
||||||
|
+ exp_policy.timeout = timeout;
|
||||||
|
+ return nf_conntrack_helper_register(&helper);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit nf_conntrack_slp_fini(void)
|
||||||
|
+{
|
||||||
|
+ nf_conntrack_helper_unregister(&helper);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(nf_conntrack_slp_init);
|
||||||
|
+module_exit(nf_conntrack_slp_fini);
|
@ -0,0 +1,39 @@
|
|||||||
|
From c83e5a977a2510de872d48a4d3bebc94dac0ed8f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Fasheh <mfasheh@suse.com>
|
||||||
|
Date: Fri, 13 May 2011 16:01:39 -0700
|
||||||
|
Subject: [PATCH 2/2] btrfs: Introduce btrfs_get_maps_dev()
|
||||||
|
References: bnc#672923
|
||||||
|
Patch-mainline: Never
|
||||||
|
|
||||||
|
Use this to return the subvolume superblock in proc instead of the global
|
||||||
|
superblock which is automatically taken today. This fixes a userspace
|
||||||
|
breakage where discrepancies between the devices two would confuse software
|
||||||
|
such as lsof.
|
||||||
|
|
||||||
|
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||||
|
---
|
||||||
|
fs/btrfs/super.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
--- a/fs/btrfs/super.c
|
||||||
|
+++ b/fs/btrfs/super.c
|
||||||
|
@@ -1301,6 +1301,11 @@ static void btrfs_fs_dirty_inode(struct
|
||||||
|
"error %d\n", btrfs_ino(inode), ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static dev_t btrfs_get_maps_dev(struct inode *inode)
|
||||||
|
+{
|
||||||
|
+ return BTRFS_I(inode)->root->anon_dev;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const struct super_operations btrfs_super_ops = {
|
||||||
|
.drop_inode = btrfs_drop_inode,
|
||||||
|
.evict_inode = btrfs_evict_inode,
|
||||||
|
@@ -1315,6 +1320,7 @@ static const struct super_operations btr
|
||||||
|
.remount_fs = btrfs_remount,
|
||||||
|
.freeze_fs = btrfs_freeze,
|
||||||
|
.unfreeze_fs = btrfs_unfreeze,
|
||||||
|
+ .get_maps_dev = btrfs_get_maps_dev,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct file_operations btrfs_ctl_fops = {
|
304
3.2.34/patches.suse/btrfs-0900-add-allocator-tracepoints.patch
Normal file
304
3.2.34/patches.suse/btrfs-0900-add-allocator-tracepoints.patch
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
From: Josef Bacik <josef@redhat.com>
|
||||||
|
Date: Thu, 10 Nov 2011 08:29:20 -0500
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] Btrfs: add allocator tracepoints
|
||||||
|
|
||||||
|
I used these tracepoints when figuring out what the cluster stuff was doing, so
|
||||||
|
add them to mainline in case we need to profile this stuff again. Thanks,
|
||||||
|
|
||||||
|
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/extent-tree.c | 9 ++
|
||||||
|
fs/btrfs/free-space-cache.c | 11 ++
|
||||||
|
include/trace/events/btrfs.h | 173 +++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 192 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/fs/btrfs/extent-tree.c
|
||||||
|
+++ b/fs/btrfs/extent-tree.c
|
||||||
|
@@ -5128,6 +5128,8 @@
|
||||||
|
ins->objectid = 0;
|
||||||
|
ins->offset = 0;
|
||||||
|
|
||||||
|
+ trace_find_free_extent(orig_root, num_bytes, empty_size, data);
|
||||||
|
+
|
||||||
|
space_info = __find_space_info(root->fs_info, data);
|
||||||
|
if (!space_info) {
|
||||||
|
printk(KERN_ERR "No space info for %llu\n", data);
|
||||||
|
@@ -5313,6 +5315,8 @@
|
||||||
|
if (offset) {
|
||||||
|
/* we have a block, we're done */
|
||||||
|
spin_unlock(&last_ptr->refill_lock);
|
||||||
|
+ trace_btrfs_reserve_extent_cluster(root,
|
||||||
|
+ block_group, search_start, num_bytes);
|
||||||
|
goto checks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -5359,6 +5363,9 @@
|
||||||
|
if (offset) {
|
||||||
|
/* we found one, proceed */
|
||||||
|
spin_unlock(&last_ptr->refill_lock);
|
||||||
|
+ trace_btrfs_reserve_extent_cluster(root,
|
||||||
|
+ block_group, search_start,
|
||||||
|
+ num_bytes);
|
||||||
|
goto checks;
|
||||||
|
}
|
||||||
|
} else if (!cached && loop > LOOP_CACHING_NOWAIT
|
||||||
|
@@ -5439,6 +5446,8 @@
|
||||||
|
ins->objectid = search_start;
|
||||||
|
ins->offset = num_bytes;
|
||||||
|
|
||||||
|
+ trace_btrfs_reserve_extent(orig_root, block_group,
|
||||||
|
+ search_start, num_bytes);
|
||||||
|
if (offset < search_start)
|
||||||
|
btrfs_add_free_space(used_block_group, offset,
|
||||||
|
search_start - offset);
|
||||||
|
--- a/fs/btrfs/free-space-cache.c
|
||||||
|
+++ b/fs/btrfs/free-space-cache.c
|
||||||
|
@@ -2346,6 +2346,8 @@
|
||||||
|
&entry->offset_index, 1);
|
||||||
|
BUG_ON(ret);
|
||||||
|
|
||||||
|
+ trace_btrfs_setup_cluster(block_group, cluster,
|
||||||
|
+ total_found * block_group->sectorsize, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2368,6 +2370,7 @@
|
||||||
|
u64 window_free;
|
||||||
|
u64 max_extent;
|
||||||
|
u64 max_gap = 128 * 1024;
|
||||||
|
+ u64 total_size = 0;
|
||||||
|
|
||||||
|
entry = tree_search_offset(ctl, offset, 0, 1);
|
||||||
|
if (!entry)
|
||||||
|
@@ -2444,11 +2447,12 @@
|
||||||
|
rb_erase(&entry->offset_index, &ctl->free_space_offset);
|
||||||
|
ret = tree_insert_offset(&cluster->root, entry->offset,
|
||||||
|
&entry->offset_index, 0);
|
||||||
|
+ total_size += entry->bytes;
|
||||||
|
BUG_ON(ret);
|
||||||
|
} while (node && entry != last);
|
||||||
|
|
||||||
|
cluster->max_size = max_extent;
|
||||||
|
-
|
||||||
|
+ trace_btrfs_setup_cluster(block_group, cluster, total_size, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2552,6 +2556,9 @@
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ trace_btrfs_find_cluster(block_group, offset, bytes, empty_size,
|
||||||
|
+ min_bytes);
|
||||||
|
+
|
||||||
|
ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset,
|
||||||
|
bytes, min_bytes);
|
||||||
|
if (ret)
|
||||||
|
@@ -2567,6 +2574,8 @@
|
||||||
|
list_add_tail(&cluster->block_group_list,
|
||||||
|
&block_group->cluster_list);
|
||||||
|
cluster->block_group = block_group;
|
||||||
|
+ } else {
|
||||||
|
+ trace_btrfs_failed_cluster_setup(block_group);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
spin_unlock(&cluster->lock);
|
||||||
|
--- a/include/trace/events/btrfs.h
|
||||||
|
+++ b/include/trace/events/btrfs.h
|
||||||
|
@@ -16,6 +16,8 @@
|
||||||
|
struct btrfs_delayed_tree_ref;
|
||||||
|
struct btrfs_delayed_data_ref;
|
||||||
|
struct btrfs_delayed_ref_head;
|
||||||
|
+struct btrfs_block_group_cache;
|
||||||
|
+struct btrfs_free_cluster;
|
||||||
|
struct map_lookup;
|
||||||
|
struct extent_buffer;
|
||||||
|
|
||||||
|
@@ -44,6 +46,15 @@
|
||||||
|
obj, ((obj >= BTRFS_DATA_RELOC_TREE_OBJECTID) || \
|
||||||
|
(obj <= BTRFS_CSUM_TREE_OBJECTID )) ? __show_root_type(obj) : "-"
|
||||||
|
|
||||||
|
+#define BTRFS_GROUP_FLAGS \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_DATA, "DATA"}, \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_SYSTEM, "SYSTEM"}, \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_METADATA, "METADATA"}, \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_RAID0, "RAID0"}, \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_RAID1, "RAID1"}, \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_DUP, "DUP"}, \
|
||||||
|
+ { BTRFS_BLOCK_GROUP_RAID10, "RAID10"}
|
||||||
|
+
|
||||||
|
TRACE_EVENT(btrfs_transaction_commit,
|
||||||
|
|
||||||
|
TP_PROTO(struct btrfs_root *root),
|
||||||
|
@@ -661,6 +672,168 @@
|
||||||
|
TP_ARGS(root, start, len)
|
||||||
|
);
|
||||||
|
|
||||||
|
+TRACE_EVENT(find_free_extent,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_root *root, u64 num_bytes, u64 empty_size,
|
||||||
|
+ u64 data),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(root, num_bytes, empty_size, data),
|
||||||
|
+
|
||||||
|
+ TP_STRUCT__entry(
|
||||||
|
+ __field( u64, root_objectid )
|
||||||
|
+ __field( u64, num_bytes )
|
||||||
|
+ __field( u64, empty_size )
|
||||||
|
+ __field( u64, data )
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_fast_assign(
|
||||||
|
+ __entry->root_objectid = root->root_key.objectid;
|
||||||
|
+ __entry->num_bytes = num_bytes;
|
||||||
|
+ __entry->empty_size = empty_size;
|
||||||
|
+ __entry->data = data;
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_printk("root = %Lu(%s), len = %Lu, empty_size = %Lu, "
|
||||||
|
+ "flags = %Lu(%s)", show_root_type(__entry->root_objectid),
|
||||||
|
+ __entry->num_bytes, __entry->empty_size, __entry->data,
|
||||||
|
+ __print_flags((unsigned long)__entry->data, "|",
|
||||||
|
+ BTRFS_GROUP_FLAGS))
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
+DECLARE_EVENT_CLASS(btrfs__reserve_extent,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_root *root,
|
||||||
|
+ struct btrfs_block_group_cache *block_group, u64 start,
|
||||||
|
+ u64 len),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(root, block_group, start, len),
|
||||||
|
+
|
||||||
|
+ TP_STRUCT__entry(
|
||||||
|
+ __field( u64, root_objectid )
|
||||||
|
+ __field( u64, bg_objectid )
|
||||||
|
+ __field( u64, flags )
|
||||||
|
+ __field( u64, start )
|
||||||
|
+ __field( u64, len )
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_fast_assign(
|
||||||
|
+ __entry->root_objectid = root->root_key.objectid;
|
||||||
|
+ __entry->bg_objectid = block_group->key.objectid;
|
||||||
|
+ __entry->flags = block_group->flags;
|
||||||
|
+ __entry->start = start;
|
||||||
|
+ __entry->len = len;
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_printk("root = %Lu(%s), block_group = %Lu, flags = %Lu(%s), "
|
||||||
|
+ "start = %Lu, len = %Lu",
|
||||||
|
+ show_root_type(__entry->root_objectid), __entry->bg_objectid,
|
||||||
|
+ __entry->flags, __print_flags((unsigned long)__entry->flags,
|
||||||
|
+ "|", BTRFS_GROUP_FLAGS),
|
||||||
|
+ __entry->start, __entry->len)
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
+DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_root *root,
|
||||||
|
+ struct btrfs_block_group_cache *block_group, u64 start,
|
||||||
|
+ u64 len),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(root, block_group, start, len)
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
+DEFINE_EVENT(btrfs__reserve_extent, btrfs_reserve_extent_cluster,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_root *root,
|
||||||
|
+ struct btrfs_block_group_cache *block_group, u64 start,
|
||||||
|
+ u64 len),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(root, block_group, start, len)
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
+TRACE_EVENT(btrfs_find_cluster,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_block_group_cache *block_group, u64 start,
|
||||||
|
+ u64 bytes, u64 empty_size, u64 min_bytes),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(block_group, start, bytes, empty_size, min_bytes),
|
||||||
|
+
|
||||||
|
+ TP_STRUCT__entry(
|
||||||
|
+ __field( u64, bg_objectid )
|
||||||
|
+ __field( u64, flags )
|
||||||
|
+ __field( u64, start )
|
||||||
|
+ __field( u64, bytes )
|
||||||
|
+ __field( u64, empty_size )
|
||||||
|
+ __field( u64, min_bytes )
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_fast_assign(
|
||||||
|
+ __entry->bg_objectid = block_group->key.objectid;
|
||||||
|
+ __entry->flags = block_group->flags;
|
||||||
|
+ __entry->start = start;
|
||||||
|
+ __entry->bytes = bytes;
|
||||||
|
+ __entry->empty_size = empty_size;
|
||||||
|
+ __entry->min_bytes = min_bytes;
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_printk("block_group = %Lu, flags = %Lu(%s), start = %Lu, len = %Lu,"
|
||||||
|
+ " empty_size = %Lu, min_bytes = %Lu", __entry->bg_objectid,
|
||||||
|
+ __entry->flags,
|
||||||
|
+ __print_flags((unsigned long)__entry->flags, "|",
|
||||||
|
+ BTRFS_GROUP_FLAGS), __entry->start,
|
||||||
|
+ __entry->bytes, __entry->empty_size, __entry->min_bytes)
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
+TRACE_EVENT(btrfs_failed_cluster_setup,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_block_group_cache *block_group),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(block_group),
|
||||||
|
+
|
||||||
|
+ TP_STRUCT__entry(
|
||||||
|
+ __field( u64, bg_objectid )
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_fast_assign(
|
||||||
|
+ __entry->bg_objectid = block_group->key.objectid;
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_printk("block_group = %Lu", __entry->bg_objectid)
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
+TRACE_EVENT(btrfs_setup_cluster,
|
||||||
|
+
|
||||||
|
+ TP_PROTO(struct btrfs_block_group_cache *block_group,
|
||||||
|
+ struct btrfs_free_cluster *cluster, u64 size, int bitmap),
|
||||||
|
+
|
||||||
|
+ TP_ARGS(block_group, cluster, size, bitmap),
|
||||||
|
+
|
||||||
|
+ TP_STRUCT__entry(
|
||||||
|
+ __field( u64, bg_objectid )
|
||||||
|
+ __field( u64, flags )
|
||||||
|
+ __field( u64, start )
|
||||||
|
+ __field( u64, max_size )
|
||||||
|
+ __field( u64, size )
|
||||||
|
+ __field( int, bitmap )
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_fast_assign(
|
||||||
|
+ __entry->bg_objectid = block_group->key.objectid;
|
||||||
|
+ __entry->flags = block_group->flags;
|
||||||
|
+ __entry->start = cluster->window_start;
|
||||||
|
+ __entry->max_size = cluster->max_size;
|
||||||
|
+ __entry->size = size;
|
||||||
|
+ __entry->bitmap = bitmap;
|
||||||
|
+ ),
|
||||||
|
+
|
||||||
|
+ TP_printk("block_group = %Lu, flags = %Lu(%s), window_start = %Lu, "
|
||||||
|
+ "size = %Lu, max_size = %Lu, bitmap = %d",
|
||||||
|
+ __entry->bg_objectid,
|
||||||
|
+ __entry->flags,
|
||||||
|
+ __print_flags((unsigned long)__entry->flags, "|",
|
||||||
|
+ BTRFS_GROUP_FLAGS), __entry->start,
|
||||||
|
+ __entry->size, __entry->max_size, __entry->bitmap)
|
||||||
|
+);
|
||||||
|
+
|
||||||
|
#endif /* _TRACE_BTRFS_H */
|
||||||
|
|
||||||
|
/* This part must be outside protection */
|
@ -0,0 +1,299 @@
|
|||||||
|
From 033eea6d488471c7262b377e066ecf9eea85d5b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Date: Thu, 17 Nov 2011 15:26:17 +0800
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] Btrfs: rewrite btrfs_trim_block_group()
|
||||||
|
|
||||||
|
There are various bugs in block group trimming:
|
||||||
|
|
||||||
|
- It may trim from offset smaller than user-specified offset.
|
||||||
|
- It may trim beyond user-specified range.
|
||||||
|
- It may leak free space for extents smaller than specified minlen.
|
||||||
|
- It may truncate the last trimmed extent thus leak free space.
|
||||||
|
- With mixed extents+bitmaps, some extents may not be trimmed.
|
||||||
|
- With mixed extents+bitmaps, some bitmaps may not be trimmed (even
|
||||||
|
none will be trimmed). Even for those trimmed, not all the free space
|
||||||
|
in the bitmaps will be trimmed.
|
||||||
|
|
||||||
|
I rewrite btrfs_trim_block_group() and break it into two functions.
|
||||||
|
One is to trim extents only, and the other is to trim bitmaps only.
|
||||||
|
|
||||||
|
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/free-space-cache.c | 233 ++++++++++++++++++++++++++++++--------------
|
||||||
|
1 file changed, 163 insertions(+), 70 deletions(-)
|
||||||
|
|
||||||
|
--- a/fs/btrfs/free-space-cache.c
|
||||||
|
+++ b/fs/btrfs/free-space-cache.c
|
||||||
|
@@ -2586,17 +2586,57 @@ void btrfs_init_free_cluster(struct btrf
|
||||||
|
cluster->block_group = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
|
||||||
|
- u64 *trimmed, u64 start, u64 end, u64 minlen)
|
||||||
|
+static int do_trimming(struct btrfs_block_group_cache *block_group,
|
||||||
|
+ u64 *total_trimmed, u64 start, u64 bytes,
|
||||||
|
+ u64 reserved_start, u64 reserved_bytes)
|
||||||
|
{
|
||||||
|
- struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||||
|
- struct btrfs_free_space *entry = NULL;
|
||||||
|
+ struct btrfs_space_info *space_info = block_group->space_info;
|
||||||
|
struct btrfs_fs_info *fs_info = block_group->fs_info;
|
||||||
|
- u64 bytes = 0;
|
||||||
|
- u64 actually_trimmed;
|
||||||
|
- int ret = 0;
|
||||||
|
+ int ret;
|
||||||
|
+ int update = 0;
|
||||||
|
+ u64 trimmed = 0;
|
||||||
|
+
|
||||||
|
+ spin_lock(&space_info->lock);
|
||||||
|
+ spin_lock(&block_group->lock);
|
||||||
|
+ if (!block_group->ro) {
|
||||||
|
+ block_group->reserved += reserved_bytes;
|
||||||
|
+ space_info->bytes_reserved += reserved_bytes;
|
||||||
|
+ update = 1;
|
||||||
|
+ }
|
||||||
|
+ spin_unlock(&block_group->lock);
|
||||||
|
+ spin_unlock(&space_info->lock);
|
||||||
|
|
||||||
|
- *trimmed = 0;
|
||||||
|
+ ret = btrfs_error_discard_extent(fs_info->extent_root,
|
||||||
|
+ start, bytes, &trimmed);
|
||||||
|
+ if (!ret)
|
||||||
|
+ *total_trimmed += trimmed;
|
||||||
|
+
|
||||||
|
+ btrfs_add_free_space(block_group, reserved_start, reserved_bytes);
|
||||||
|
+
|
||||||
|
+ if (update) {
|
||||||
|
+ spin_lock(&space_info->lock);
|
||||||
|
+ spin_lock(&block_group->lock);
|
||||||
|
+ if (block_group->ro)
|
||||||
|
+ space_info->bytes_readonly += reserved_bytes;
|
||||||
|
+ block_group->reserved -= reserved_bytes;
|
||||||
|
+ space_info->bytes_reserved -= reserved_bytes;
|
||||||
|
+ spin_unlock(&space_info->lock);
|
||||||
|
+ spin_unlock(&block_group->lock);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int trim_no_bitmap(struct btrfs_block_group_cache *block_group,
|
||||||
|
+ u64 *total_trimmed, u64 start, u64 end, u64 minlen)
|
||||||
|
+{
|
||||||
|
+ struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||||
|
+ struct btrfs_free_space *entry;
|
||||||
|
+ struct rb_node *node;
|
||||||
|
+ int ret = 0;
|
||||||
|
+ u64 extent_start;
|
||||||
|
+ u64 extent_bytes;
|
||||||
|
+ u64 bytes;
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
spin_lock(&ctl->tree_lock);
|
||||||
|
@@ -2607,81 +2647,118 @@ int btrfs_trim_block_group(struct btrfs_
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = tree_search_offset(ctl, start, 0, 1);
|
||||||
|
- if (!entry)
|
||||||
|
- entry = tree_search_offset(ctl,
|
||||||
|
- offset_to_bitmap(ctl, start),
|
||||||
|
- 1, 1);
|
||||||
|
-
|
||||||
|
- if (!entry || entry->offset >= end) {
|
||||||
|
+ if (!entry) {
|
||||||
|
spin_unlock(&ctl->tree_lock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (entry->bitmap) {
|
||||||
|
- ret = search_bitmap(ctl, entry, &start, &bytes);
|
||||||
|
- if (!ret) {
|
||||||
|
- if (start >= end) {
|
||||||
|
- spin_unlock(&ctl->tree_lock);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- bytes = min(bytes, end - start);
|
||||||
|
- bitmap_clear_bits(ctl, entry, start, bytes);
|
||||||
|
- if (entry->bytes == 0)
|
||||||
|
- free_bitmap(ctl, entry);
|
||||||
|
- } else {
|
||||||
|
- start = entry->offset + BITS_PER_BITMAP *
|
||||||
|
- block_group->sectorsize;
|
||||||
|
+ /* skip bitmaps */
|
||||||
|
+ while (entry->bitmap) {
|
||||||
|
+ node = rb_next(&entry->offset_index);
|
||||||
|
+ if (!node) {
|
||||||
|
spin_unlock(&ctl->tree_lock);
|
||||||
|
- ret = 0;
|
||||||
|
- continue;
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
- } else {
|
||||||
|
- start = entry->offset;
|
||||||
|
- bytes = min(entry->bytes, end - start);
|
||||||
|
- unlink_free_space(ctl, entry);
|
||||||
|
- kmem_cache_free(btrfs_free_space_cachep, entry);
|
||||||
|
+ entry = rb_entry(node, struct btrfs_free_space,
|
||||||
|
+ offset_index);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (entry->offset >= end) {
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ extent_start = entry->offset;
|
||||||
|
+ extent_bytes = entry->bytes;
|
||||||
|
+ start = max(start, extent_start);
|
||||||
|
+ bytes = min(extent_start + extent_bytes, end) - start;
|
||||||
|
+ if (bytes < minlen) {
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+ goto next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ unlink_free_space(ctl, entry);
|
||||||
|
+ kmem_cache_free(btrfs_free_space_cachep, entry);
|
||||||
|
+
|
||||||
|
spin_unlock(&ctl->tree_lock);
|
||||||
|
|
||||||
|
- if (bytes >= minlen) {
|
||||||
|
- struct btrfs_space_info *space_info;
|
||||||
|
- int update = 0;
|
||||||
|
-
|
||||||
|
- space_info = block_group->space_info;
|
||||||
|
- spin_lock(&space_info->lock);
|
||||||
|
- spin_lock(&block_group->lock);
|
||||||
|
- if (!block_group->ro) {
|
||||||
|
- block_group->reserved += bytes;
|
||||||
|
- space_info->bytes_reserved += bytes;
|
||||||
|
- update = 1;
|
||||||
|
- }
|
||||||
|
- spin_unlock(&block_group->lock);
|
||||||
|
- spin_unlock(&space_info->lock);
|
||||||
|
+ ret = do_trimming(block_group, total_trimmed, start, bytes,
|
||||||
|
+ extent_start, extent_bytes);
|
||||||
|
+ if (ret)
|
||||||
|
+ break;
|
||||||
|
+next:
|
||||||
|
+ start += bytes;
|
||||||
|
|
||||||
|
- ret = btrfs_error_discard_extent(fs_info->extent_root,
|
||||||
|
- start,
|
||||||
|
- bytes,
|
||||||
|
- &actually_trimmed);
|
||||||
|
-
|
||||||
|
- btrfs_add_free_space(block_group, start, bytes);
|
||||||
|
- if (update) {
|
||||||
|
- spin_lock(&space_info->lock);
|
||||||
|
- spin_lock(&block_group->lock);
|
||||||
|
- if (block_group->ro)
|
||||||
|
- space_info->bytes_readonly += bytes;
|
||||||
|
- block_group->reserved -= bytes;
|
||||||
|
- space_info->bytes_reserved -= bytes;
|
||||||
|
- spin_unlock(&space_info->lock);
|
||||||
|
- spin_unlock(&block_group->lock);
|
||||||
|
- }
|
||||||
|
+ if (fatal_signal_pending(current)) {
|
||||||
|
+ ret = -ERESTARTSYS;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cond_resched();
|
||||||
|
+ }
|
||||||
|
+out:
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int trim_bitmaps(struct btrfs_block_group_cache *block_group,
|
||||||
|
+ u64 *total_trimmed, u64 start, u64 end, u64 minlen)
|
||||||
|
+{
|
||||||
|
+ struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||||
|
+ struct btrfs_free_space *entry;
|
||||||
|
+ int ret = 0;
|
||||||
|
+ int ret2;
|
||||||
|
+ u64 bytes;
|
||||||
|
+ u64 offset = offset_to_bitmap(ctl, start);
|
||||||
|
+
|
||||||
|
+ while (offset < end) {
|
||||||
|
+ bool next_bitmap = false;
|
||||||
|
+
|
||||||
|
+ spin_lock(&ctl->tree_lock);
|
||||||
|
|
||||||
|
- if (ret)
|
||||||
|
- break;
|
||||||
|
- *trimmed += actually_trimmed;
|
||||||
|
+ if (ctl->free_space < minlen) {
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ entry = tree_search_offset(ctl, offset, 1, 0);
|
||||||
|
+ if (!entry) {
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+ next_bitmap = true;
|
||||||
|
+ goto next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bytes = minlen;
|
||||||
|
+ ret2 = search_bitmap(ctl, entry, &start, &bytes);
|
||||||
|
+ if (ret2 || start >= end) {
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+ next_bitmap = true;
|
||||||
|
+ goto next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bytes = min(bytes, end - start);
|
||||||
|
+ if (bytes < minlen) {
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+ goto next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bitmap_clear_bits(ctl, entry, start, bytes);
|
||||||
|
+ if (entry->bytes == 0)
|
||||||
|
+ free_bitmap(ctl, entry);
|
||||||
|
+
|
||||||
|
+ spin_unlock(&ctl->tree_lock);
|
||||||
|
+
|
||||||
|
+ ret = do_trimming(block_group, total_trimmed, start, bytes,
|
||||||
|
+ start, bytes);
|
||||||
|
+ if (ret)
|
||||||
|
+ break;
|
||||||
|
+next:
|
||||||
|
+ if (next_bitmap) {
|
||||||
|
+ offset += BITS_PER_BITMAP * ctl->unit;
|
||||||
|
+ } else {
|
||||||
|
+ start += bytes;
|
||||||
|
+ if (start >= offset + BITS_PER_BITMAP * ctl->unit)
|
||||||
|
+ offset += BITS_PER_BITMAP * ctl->unit;
|
||||||
|
}
|
||||||
|
- start += bytes;
|
||||||
|
- bytes = 0;
|
||||||
|
|
||||||
|
if (fatal_signal_pending(current)) {
|
||||||
|
ret = -ERESTARTSYS;
|
||||||
|
@@ -2693,6 +2770,22 @@ int btrfs_trim_block_group(struct btrfs_
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
|
||||||
|
+ u64 *trimmed, u64 start, u64 end, u64 minlen)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ *trimmed = 0;
|
||||||
|
+
|
||||||
|
+ ret = trim_no_bitmap(block_group, trimmed, start, end, minlen);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = trim_bitmaps(block_group, trimmed, start, end, minlen);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the left-most item in the cache tree, and then return the
|
@ -0,0 +1,40 @@
|
|||||||
|
From e2049e28add8f8fbfa8680fcf5fc49fa3b713ceb Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Tue, 22 Nov 2011 18:05:48 +0100
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586 bnc#730103
|
||||||
|
Subject: [PATCH] btrfs: lock and disable irq during space alloc
|
||||||
|
|
||||||
|
This is a workaround.
|
||||||
|
|
||||||
|
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/free-space-cache.c | 4 ++--
|
||||||
|
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
|
||||||
|
index 7807276..e49c1cd 100644
|
||||||
|
--- a/fs/btrfs/free-space-cache.c
|
||||||
|
+++ b/fs/btrfs/free-space-cache.c
|
||||||
|
@@ -2102,7 +2102,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
|
||||||
|
u64 bytes_search = bytes + empty_size;
|
||||||
|
u64 ret = 0;
|
||||||
|
|
||||||
|
- spin_lock(&ctl->tree_lock);
|
||||||
|
+ spin_lock_irq(&ctl->tree_lock);
|
||||||
|
entry = find_free_space(ctl, &offset, &bytes_search);
|
||||||
|
if (!entry)
|
||||||
|
goto out;
|
||||||
|
@@ -2123,7 +2123,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
- spin_unlock(&ctl->tree_lock);
|
||||||
|
+ spin_unlock_irq(&ctl->tree_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.7.6
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From: Keith Mannthey <kmannth@us.ibm.com>
|
||||||
|
Date: Tue, 29 Nov 2011 17:44:12 -0800
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586 bnc#724620
|
||||||
|
Subject: [PATCH] Sector Size check during Mount
|
||||||
|
|
||||||
|
Gracefully fail when trying to mount a BTRFS file system that has a
|
||||||
|
sectorsize smaller than PAGE_SIZE.
|
||||||
|
|
||||||
|
On PPC it is possible to build a FS while using a 4k PAGE_SIZE kernel
|
||||||
|
then boot into a 64K PAGE_SIZE kernel. Presently open_ctree fails in an
|
||||||
|
endless loop and hangs the machine in this situation.
|
||||||
|
|
||||||
|
My debugging has show this Sector size < Page size to be a non trivial
|
||||||
|
situation and a graceful exit from the situation would be nice for the
|
||||||
|
time being.
|
||||||
|
|
||||||
|
Signed-off-by: Keith Mannthey <kmannth@us.ibm.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/disk-io.c | 6 ++++++
|
||||||
|
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
||||||
|
index 94abc25..1cbfa75 100644
|
||||||
|
--- a/fs/btrfs/disk-io.c
|
||||||
|
+++ b/fs/btrfs/disk-io.c
|
||||||
|
@@ -2230,6 +2230,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
||||||
|
goto fail_sb_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (sectorsize < PAGE_SIZE) {
|
||||||
|
+ printk(KERN_WARNING "btrfs: Incompatible sector size "
|
||||||
|
+ "found on %s\n", sb->s_id);
|
||||||
|
+ goto fail_sb_buffer;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
mutex_lock(&fs_info->chunk_mutex);
|
||||||
|
ret = btrfs_read_sys_array(tree_root);
|
||||||
|
mutex_unlock(&fs_info->chunk_mutex);
|
||||||
|
--
|
||||||
|
1.7.6.233.gd79bc
|
||||||
|
|
@ -0,0 +1,158 @@
|
|||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Tue, 28 Jun 2011 12:38:06 +0200
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] btrfs: add new ioctl to determine size of compressed file
|
||||||
|
|
||||||
|
Go through all extents of a file in a given [start,end) range and sum
|
||||||
|
for:
|
||||||
|
* regular extent: ->block_len, size is already rounded up to blocks
|
||||||
|
* inline extents: length rounded up to 512
|
||||||
|
|
||||||
|
The range is start inclusive / end exclusive. For whole a file pass
|
||||||
|
0 and (u64)-1.
|
||||||
|
|
||||||
|
The values returned are number of occupied 512B sectors for uncompressed
|
||||||
|
and compressed size and can be easily compared to determine rough
|
||||||
|
compression ratio of the given file range.
|
||||||
|
|
||||||
|
Based on implementation from Ulrich Hecht,
|
||||||
|
http://comments.gmane.org/gmane.comp.file-systems.btrfs/6253
|
||||||
|
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/ioctl.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
fs/btrfs/ioctl.h | 12 ++++++++
|
||||||
|
2 files changed, 95 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
|
||||||
|
index c04f02c..91e6ab8 100644
|
||||||
|
--- a/fs/btrfs/ioctl.c
|
||||||
|
+++ b/fs/btrfs/ioctl.c
|
||||||
|
@@ -2972,6 +2972,86 @@ static int build_ino_list(u64 inum, u64 offset, u64 root, void *ctx)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Returns the compressed size of an inode in 512 byte blocks.
|
||||||
|
+ * Count the on-disk space used by extents starting in range [start, end),
|
||||||
|
+ * inline data are rounded up to sector, ie. 512.
|
||||||
|
+ *
|
||||||
|
+ * The range is start inclusive and end exclusive so it can be used to
|
||||||
|
+ * determine compressed size of a given extent by its start and start of the
|
||||||
|
+ * next extent easily, without counting length.
|
||||||
|
+ * Whole file is specified as start = 0, end = (u64)-1
|
||||||
|
+ */
|
||||||
|
+static long btrfs_ioctl_compr_size(struct file *file, void __user *argp)
|
||||||
|
+{
|
||||||
|
+ struct inode *inode = fdentry(file)->d_inode;
|
||||||
|
+ struct btrfs_ioctl_compr_size_args compr_args;
|
||||||
|
+ u64 len;
|
||||||
|
+ u64 compressed_size = 0;
|
||||||
|
+ u64 size = 0;
|
||||||
|
+ u64 offset = 0;
|
||||||
|
+
|
||||||
|
+ if (S_ISDIR(inode->i_mode))
|
||||||
|
+ return -EISDIR;
|
||||||
|
+
|
||||||
|
+ if (copy_from_user(&compr_args, argp,
|
||||||
|
+ sizeof(struct btrfs_ioctl_compr_size_args)))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+
|
||||||
|
+ if (compr_args.start > compr_args.end)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&inode->i_mutex);
|
||||||
|
+
|
||||||
|
+ offset = compr_args.start;
|
||||||
|
+ if (inode->i_size > compr_args.end)
|
||||||
|
+ len = compr_args.end;
|
||||||
|
+ else
|
||||||
|
+ len = inode->i_size;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * do any pending delalloc/csum calc on inode, one way or
|
||||||
|
+ * another, and lock file content
|
||||||
|
+ */
|
||||||
|
+ btrfs_wait_ordered_range(inode, compr_args.start, len);
|
||||||
|
+
|
||||||
|
+ lock_extent(&BTRFS_I(inode)->io_tree, compr_args.start, len, GFP_NOFS);
|
||||||
|
+
|
||||||
|
+ while (offset < len) {
|
||||||
|
+ struct extent_map *em;
|
||||||
|
+
|
||||||
|
+ em = btrfs_get_extent(inode, NULL, 0, offset, 1, 0);
|
||||||
|
+ if (IS_ERR_OR_NULL(em))
|
||||||
|
+ goto error;
|
||||||
|
+ if (em->block_len != (u64)-1) {
|
||||||
|
+ compressed_size += em->block_len;
|
||||||
|
+ size += ALIGN(em->len, inode->i_sb->s_blocksize);
|
||||||
|
+ } else if (em->block_start == EXTENT_MAP_INLINE) {
|
||||||
|
+ compressed_size += ALIGN(em->len, 512);
|
||||||
|
+ size += ALIGN(em->len, 512);
|
||||||
|
+ }
|
||||||
|
+ offset += em->len;
|
||||||
|
+ free_extent_map(em);
|
||||||
|
+ }
|
||||||
|
+ unlock_extent(&BTRFS_I(inode)->io_tree, compr_args.start, len, GFP_NOFS);
|
||||||
|
+ mutex_unlock(&inode->i_mutex);
|
||||||
|
+
|
||||||
|
+ compr_args.size = size >> 9;
|
||||||
|
+ compr_args.compressed_size = compressed_size >> 9;
|
||||||
|
+
|
||||||
|
+ if (copy_to_user(argp, &compr_args,
|
||||||
|
+ sizeof(struct btrfs_ioctl_compr_size_args)))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+error:
|
||||||
|
+ unlock_extent(&BTRFS_I(inode)->io_tree, compr_args.start, len, GFP_NOFS);
|
||||||
|
+ mutex_unlock(&inode->i_mutex);
|
||||||
|
+
|
||||||
|
+ return -EIO;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
|
||||||
|
void __user *arg)
|
||||||
|
{
|
||||||
|
@@ -3110,6 +3190,8 @@ long btrfs_ioctl(struct file *file, unsigned int
|
||||||
|
return btrfs_ioctl_scrub_cancel(root, argp);
|
||||||
|
case BTRFS_IOC_SCRUB_PROGRESS:
|
||||||
|
return btrfs_ioctl_scrub_progress(root, argp);
|
||||||
|
+ case BTRFS_IOC_COMPR_SIZE:
|
||||||
|
+ return btrfs_ioctl_compr_size(file, argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTTY;
|
||||||
|
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
|
||||||
|
--- a/fs/btrfs/ioctl.h
|
||||||
|
+++ b/fs/btrfs/ioctl.h
|
||||||
|
@@ -217,6 +217,16 @@ struct btrfs_ioctl_logical_ino_args {
|
||||||
|
__u64 inodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct btrfs_ioctl_compr_size_args {
|
||||||
|
+ /* Range start, inclusive */
|
||||||
|
+ __u64 start; /* in */
|
||||||
|
+ /* Range end, exclusive */
|
||||||
|
+ __u64 end; /* in */
|
||||||
|
+ __u64 size; /* out */
|
||||||
|
+ __u64 compressed_size; /* out */
|
||||||
|
+ __u64 reserved[2];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
|
||||||
|
struct btrfs_ioctl_vol_args)
|
||||||
|
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
|
||||||
|
@@ -276,5 +286,7 @@ struct btrfs_ioctl_logical_ino_args {
|
||||||
|
struct btrfs_ioctl_ino_path_args)
|
||||||
|
#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
|
||||||
|
struct btrfs_ioctl_ino_path_args)
|
||||||
|
+#define BTRFS_IOC_COMPR_SIZE _IOR(BTRFS_IOCTL_MAGIC, 51, \
|
||||||
|
+ struct btrfs_ioctl_compr_size_args)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.7.7.3
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
From: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Date: Thu, 26 May 2011 11:39:03 +0800
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] Btrfs: make lzo the default compression scheme
|
||||||
|
|
||||||
|
As the lzo compression feature has been established for quite
|
||||||
|
a while, we are now ready to replace zlib with lzo as the default
|
||||||
|
compression scheme.
|
||||||
|
|
||||||
|
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/disk-io.c | 2 +-
|
||||||
|
fs/btrfs/ioctl.c | 2 +-
|
||||||
|
fs/btrfs/super.c | 8 ++++----
|
||||||
|
3 files changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
||||||
|
index 94abc25..7ea0cdd 100644
|
||||||
|
--- a/fs/btrfs/disk-io.c
|
||||||
|
+++ b/fs/btrfs/disk-io.c
|
||||||
|
@@ -2095,7 +2095,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
||||||
|
* In the long term, we'll store the compression type in the super
|
||||||
|
* block, and it'll be used for per file compression control.
|
||||||
|
*/
|
||||||
|
- fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
|
||||||
|
+ fs_info->compress_type = BTRFS_COMPRESS_LZO;
|
||||||
|
|
||||||
|
ret = btrfs_parse_options(tree_root, options);
|
||||||
|
if (ret) {
|
||||||
|
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
|
||||||
|
index a90e749..d9c2ba6 100644
|
||||||
|
--- a/fs/btrfs/ioctl.c
|
||||||
|
+++ b/fs/btrfs/ioctl.c
|
||||||
|
@@ -992,7 +992,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||||
|
unsigned long ra_index = 0;
|
||||||
|
int ret;
|
||||||
|
int defrag_count = 0;
|
||||||
|
- int compress_type = BTRFS_COMPRESS_ZLIB;
|
||||||
|
+ int compress_type = BTRFS_COMPRESS_LZO;
|
||||||
|
int extent_thresh = range->extent_thresh;
|
||||||
|
int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
|
||||||
|
int cluster = max_cluster;
|
||||||
|
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
|
||||||
|
index 8bd9d6d..b6b5bd7 100644
|
||||||
|
--- a/fs/btrfs/super.c
|
||||||
|
+++ b/fs/btrfs/super.c
|
||||||
|
@@ -270,12 +270,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
|
||||||
|
case Opt_compress_type:
|
||||||
|
if (token == Opt_compress ||
|
||||||
|
token == Opt_compress_force ||
|
||||||
|
- strcmp(args[0].from, "zlib") == 0) {
|
||||||
|
- compress_type = "zlib";
|
||||||
|
- info->compress_type = BTRFS_COMPRESS_ZLIB;
|
||||||
|
- } else if (strcmp(args[0].from, "lzo") == 0) {
|
||||||
|
+ strcmp(args[0].from, "lzo") == 0) {
|
||||||
|
compress_type = "lzo";
|
||||||
|
info->compress_type = BTRFS_COMPRESS_LZO;
|
||||||
|
+ } else if (strcmp(args[0].from, "zlib") == 0) {
|
||||||
|
+ compress_type = "zlib";
|
||||||
|
+ info->compress_type = BTRFS_COMPRESS_ZLIB;
|
||||||
|
} else {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
--
|
||||||
|
1.7.6
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 15 Dec 2011 02:10:55 +0100
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] btrfs: workaround for cleaner deadlock
|
||||||
|
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/disk-io.c | 2 ++
|
||||||
|
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
||||||
|
index 3f9d555..12d785b 100644
|
||||||
|
--- a/fs/btrfs/disk-io.c
|
||||||
|
+++ b/fs/btrfs/disk-io.c
|
||||||
|
@@ -1572,11 +1572,13 @@ static int cleaner_kthread(void *arg)
|
||||||
|
vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
|
||||||
|
|
||||||
|
if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
|
||||||
|
+ down_read_trylock(&root->fs_info->sb->s_umount) &&
|
||||||
|
mutex_trylock(&root->fs_info->cleaner_mutex)) {
|
||||||
|
btrfs_run_delayed_iputs(root);
|
||||||
|
btrfs_clean_old_snapshots(root);
|
||||||
|
mutex_unlock(&root->fs_info->cleaner_mutex);
|
||||||
|
btrfs_run_defrag_inodes(root->fs_info);
|
||||||
|
+ up_read(&root->fs_info->sb->s_umount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (freezing(current)) {
|
||||||
|
--
|
||||||
|
1.7.7.3
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
From: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Date: Wed, 7 Dec 2011 13:12:59 +0800
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] Btrfs: update global block_rsv when creating a new block
|
||||||
|
group
|
||||||
|
|
||||||
|
A bug was triggered while using seed device:
|
||||||
|
|
||||||
|
# mkfs.btrfs /dev/loop1
|
||||||
|
# btrfstune -S 1 /dev/loop1
|
||||||
|
# mount -o /dev/loop1 /mnt
|
||||||
|
# btrfs dev add /dev/loop2 /mnt
|
||||||
|
|
||||||
|
btrfs: block rsv returned -28
|
||||||
|
------------[ cut here ]------------
|
||||||
|
WARNING: at fs/btrfs/extent-tree.c:5969 btrfs_alloc_free_block+0x166/0x396 [btrfs]()
|
||||||
|
...
|
||||||
|
Call Trace:
|
||||||
|
...
|
||||||
|
[<f7b7c31c>] btrfs_cow_block+0x101/0x147 [btrfs]
|
||||||
|
[<f7b7eaa6>] btrfs_search_slot+0x1b8/0x55f [btrfs]
|
||||||
|
[<f7b7f844>] btrfs_insert_empty_items+0x42/0x7f [btrfs]
|
||||||
|
[<f7b7f8c1>] btrfs_insert_item+0x40/0x7e [btrfs]
|
||||||
|
[<f7b8ac02>] btrfs_make_block_group+0x243/0x2aa [btrfs]
|
||||||
|
[<f7bb3f53>] __btrfs_alloc_chunk+0x672/0x70e [btrfs]
|
||||||
|
[<f7bb41ff>] init_first_rw_device+0x77/0x13c [btrfs]
|
||||||
|
[<f7bb5a62>] btrfs_init_new_device+0x664/0x9fd [btrfs]
|
||||||
|
[<f7bbb65a>] btrfs_ioctl+0x694/0xdbe [btrfs]
|
||||||
|
[<c04f55f7>] do_vfs_ioctl+0x496/0x4cc
|
||||||
|
[<c04f5660>] sys_ioctl+0x33/0x4f
|
||||||
|
[<c07b9edf>] sysenter_do_call+0x12/0x38
|
||||||
|
---[ end trace 906adac595facc7d ]---
|
||||||
|
|
||||||
|
Since seed device is readonly, there's no usable space in the filesystem.
|
||||||
|
Afterwards we add a sprout device to it, and the kernel creates a METADATA
|
||||||
|
block group and a SYSTEM block group where comes free space we can reserve,
|
||||||
|
but we still get revervation failure because the global block_rsv hasn't
|
||||||
|
been updated accordingly.
|
||||||
|
|
||||||
|
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/extent-tree.c | 1 +
|
||||||
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
|
||||||
|
index 8861572..a80efb5 100644
|
||||||
|
--- a/fs/btrfs/extent-tree.c
|
||||||
|
+++ b/fs/btrfs/extent-tree.c
|
||||||
|
@@ -7476,6 +7476,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
|
||||||
|
ret = update_space_info(root->fs_info, cache->flags, size, bytes_used,
|
||||||
|
&cache->space_info);
|
||||||
|
BUG_ON(ret);
|
||||||
|
+ update_global_block_rsv(root->fs_info);
|
||||||
|
|
||||||
|
spin_lock(&cache->space_info->lock);
|
||||||
|
cache->space_info->bytes_readonly += cache->bytes_super;
|
||||||
|
--
|
||||||
|
1.7.6.233.gd79bc
|
||||||
|
|
@ -0,0 +1,84 @@
|
|||||||
|
From: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Date: Wed, 7 Dec 2011 13:13:26 +0800
|
||||||
|
Patch-mainline: pending
|
||||||
|
References: FATE#306586
|
||||||
|
Subject: [PATCH] Btrfs: fix possible deadlock when opening a seed device
|
||||||
|
|
||||||
|
The correct lock order is uuid_mutex -> volume_mutex -> chunk_mutex,
|
||||||
|
but when we mount a filesystem which has backing seed devices, we have
|
||||||
|
this lock chain:
|
||||||
|
|
||||||
|
open_ctree()
|
||||||
|
lock(chunk_mutex);
|
||||||
|
read_chunk_tree();
|
||||||
|
read_one_dev();
|
||||||
|
open_seed_devices();
|
||||||
|
lock(uuid_mutex);
|
||||||
|
|
||||||
|
and then we hit a lockdep splat.
|
||||||
|
|
||||||
|
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/disk-io.c | 2 --
|
||||||
|
fs/btrfs/volumes.c | 9 +++++++--
|
||||||
|
2 files changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
|
||||||
|
index d0bc3c5..beb1d19 100644
|
||||||
|
--- a/fs/btrfs/disk-io.c
|
||||||
|
+++ b/fs/btrfs/disk-io.c
|
||||||
|
@@ -2287,9 +2287,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
||||||
|
(unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
|
||||||
|
BTRFS_UUID_SIZE);
|
||||||
|
|
||||||
|
- mutex_lock(&fs_info->chunk_mutex);
|
||||||
|
ret = btrfs_read_chunk_tree(chunk_root);
|
||||||
|
- mutex_unlock(&fs_info->chunk_mutex);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_WARNING "btrfs: failed to read chunk tree on %s\n",
|
||||||
|
sb->s_id);
|
||||||
|
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
|
||||||
|
index d136915..fc94228 100644
|
||||||
|
--- a/fs/btrfs/volumes.c
|
||||||
|
+++ b/fs/btrfs/volumes.c
|
||||||
|
@@ -4264,7 +4264,7 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid)
|
||||||
|
struct btrfs_fs_devices *fs_devices;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- mutex_lock(&uuid_mutex);
|
||||||
|
+ BUG_ON(!mutex_is_locked(&uuid_mutex));
|
||||||
|
|
||||||
|
fs_devices = root->fs_info->fs_devices->seed;
|
||||||
|
while (fs_devices) {
|
||||||
|
@@ -4302,7 +4302,6 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid)
|
||||||
|
fs_devices->seed = root->fs_info->fs_devices->seed;
|
||||||
|
root->fs_info->fs_devices->seed = fs_devices;
|
||||||
|
out:
|
||||||
|
- mutex_unlock(&uuid_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4459,6 +4458,9 @@ int btrfs_read_chunk_tree(struct btrfs_root *root)
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
+ mutex_lock(&uuid_mutex);
|
||||||
|
+ lock_chunks(root);
|
||||||
|
+
|
||||||
|
/* first we search for all of the device items, and then we
|
||||||
|
* read in all of the chunk items. This way we can create chunk
|
||||||
|
* mappings that reference all of the devices that are afound
|
||||||
|
@@ -4509,6 +4511,9 @@ again:
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
error:
|
||||||
|
+ unlock_chunks(root);
|
||||||
|
+ mutex_unlock(&uuid_mutex);
|
||||||
|
+
|
||||||
|
btrfs_free_path(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.7.6.233.gd79bc
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Mon, 1 Aug 2011 18:11:57 +0200
|
||||||
|
Subject: [PATCH] btrfs: allow cross-subvolume file clone
|
||||||
|
Reference: bnc#698540
|
||||||
|
Patch-mainline: pending
|
||||||
|
|
||||||
|
Lift the EXDEV condition and allow different root trees for files being
|
||||||
|
cloned, then pass source inode's root when searching for extents.
|
||||||
|
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
fs/btrfs/ioctl.c | 7 ++++---
|
||||||
|
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
|
||||||
|
index 0b980af..58eb0ef 100644
|
||||||
|
--- a/fs/btrfs/ioctl.c
|
||||||
|
+++ b/fs/btrfs/ioctl.c
|
||||||
|
@@ -2183,7 +2183,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||||
|
goto out_fput;
|
||||||
|
|
||||||
|
ret = -EXDEV;
|
||||||
|
- if (src->i_sb != inode->i_sb || BTRFS_I(src)->root != root)
|
||||||
|
+ if (src->i_sb != inode->i_sb)
|
||||||
|
goto out_fput;
|
||||||
|
|
||||||
|
ret = -ENOMEM;
|
||||||
|
@@ -2247,13 +2247,14 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||||
|
* note the key will change type as we walk through the
|
||||||
|
* tree.
|
||||||
|
*/
|
||||||
|
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||||
|
+ ret = btrfs_search_slot(NULL, BTRFS_I(src)->root, &key, path,
|
||||||
|
+ 0, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
nritems = btrfs_header_nritems(path->nodes[0]);
|
||||||
|
if (path->slots[0] >= nritems) {
|
||||||
|
- ret = btrfs_next_leaf(root, path);
|
||||||
|
+ ret = btrfs_next_leaf(BTRFS_I(src)->root, path);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
if (ret > 0)
|
||||||
|
--
|
||||||
|
1.7.6
|
||||||
|
|
68
3.2.34/series
Normal file
68
3.2.34/series
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
bump/1021_linux-3.2.22.patch
|
||||||
|
bump/1022_linux-3.2.23.patch
|
||||||
|
bump/1023_linux-3.2.24.patch
|
||||||
|
bump/1024_linux-3.2.25.patch
|
||||||
|
bump/1025_linux-3.2.26.patch
|
||||||
|
bump/1026_linux-3.2.27.patch
|
||||||
|
bump/1027_linux-3.2.28.patch
|
||||||
|
bump/1028_linux-3.2.29.patch
|
||||||
|
bump/1029_linux-3.2.30.patch
|
||||||
|
bump/1030_linux-3.2.31.patch
|
||||||
|
bump/1031_linux-3.2.32.patch
|
||||||
|
bump/1032_linux-3.2.33.patch
|
||||||
|
bump/1033_linux-3.2.34.patch
|
||||||
|
|
||||||
|
|
||||||
|
0001-block-prepare-I-O-context-code-for-BFQ-v5-for-3.2.patch
|
||||||
|
0002-block-cgroups-kconfig-build-bits-for-BFQ-v5-3.2.patch
|
||||||
|
0003-block-introduce-the-BFQ-v5-I-O-sched-for-3.2.patch
|
||||||
|
|
||||||
|
0001-AppArmor-compatibility-patch-for-v5-network-controll.patch
|
||||||
|
0002-AppArmor-compatibility-patch-for-v5-interface.patch
|
||||||
|
0003-AppArmor-Allow-dfa-backward-compatibility-with-broke.patch
|
||||||
|
|
||||||
|
cloneconfig.patch
|
||||||
|
kbuild-compress-kernel-modules-on-installation.patch
|
||||||
|
ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch
|
||||||
|
colored-printk-3.2.33.patch
|
||||||
|
910-kobject_uevent.patch
|
||||||
|
911-kobject_add_broadcast_uevent.patch
|
||||||
|
|
||||||
|
linux-2.6-x86-tune-generic.patch
|
||||||
|
hz-432-kconfig-option.patch
|
||||||
|
hz-864-kconfig-option.patch
|
||||||
|
|
||||||
|
Add_CONFIG_VFAT_FS_DUALNAMES_option.patch
|
||||||
|
linux-2.6-defaults-fat-utf8.patch
|
||||||
|
aufs3-standalone-3.2.patch
|
||||||
|
accessfs-3.2-0.26.patch
|
||||||
|
wrapfs-v3.2.2-45-ga5296eb.patch
|
||||||
|
|
||||||
|
imqmq-3.2.patch
|
||||||
|
|
||||||
|
vserver-3.2.34-vs2.3.2.15.patch
|
||||||
|
uksm-0.1.2.1-for-v3.2.ge.31.patch
|
||||||
|
kernel-3.4.0-layer7-2.22.patch
|
||||||
|
net-netfilter-IFWLOG.patch
|
||||||
|
net-netfilter-IFWLOG-mdv.patch
|
||||||
|
net-netfilter-IFWLOG-2.6.35-buildfix.patch
|
||||||
|
net-netfilter-IFWLOG-2.6.37-buildfix.patch
|
||||||
|
net-netfilter-psd.patch
|
||||||
|
net-netfilter-psd-mdv.patch
|
||||||
|
net-netfilter-psd-2.6.35-buildfix.patch
|
||||||
|
netfilter-implement-rfc-1123-for-ftp-conntrack.patch
|
||||||
|
netfilter-ip_conntrack_slp.patch
|
||||||
|
|
||||||
|
kernel-3.2-lsxhl.patch
|
||||||
|
kernel-3.2-lsproduo.patch
|
||||||
|
kernel-3.2-lsql.patch
|
||||||
|
v3.2-ARM-kirkwood-Add-support-for-Buffalo-LS-VL.patch
|
||||||
|
v3.2-ARM-kirkwood-Add-support-for-Buffalo-LS-WVL.patch
|
||||||
|
lschlv2.patch
|
||||||
|
|
||||||
|
3rd-3rdparty-1.0-tree.patch
|
||||||
|
3rd-3rdparty-merge.patch
|
||||||
|
3rd-3rdparty-netatop-0.1.1.patch
|
||||||
|
3rd-3rdparty-button_hotplug-0.4.1.patch
|
||||||
|
3rd-3rdparty-gpio_button_hotplug-0.1.patch
|
||||||
|
3rd-3rdparty-gpio_event_drv-0.1.patch
|
7032
3.2.34/uksm-0.1.2.1-for-v3.2.ge.31.patch
Normal file
7032
3.2.34/uksm-0.1.2.1-for-v3.2.ge.31.patch
Normal file
File diff suppressed because it is too large
Load Diff
381
3.2.34/v3.2-ARM-kirkwood-Add-support-for-Buffalo-LS-VL.patch
Normal file
381
3.2.34/v3.2-ARM-kirkwood-Add-support-for-Buffalo-LS-VL.patch
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/mach-kirkwood/Kconfig linux-3.2.33-go/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/mach-kirkwood/Kconfig 2012-11-14 21:20:22.326388580 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/mach-kirkwood/Kconfig 2012-11-14 21:21:02.353908681 +0100
|
||||||
|
@@ -136,6 +136,12 @@
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Buffalo LS-XHL Series.
|
||||||
|
|
||||||
|
+config MACH_LSVL
|
||||||
|
+ bool "Buffalo LS-VL Series"
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the
|
||||||
|
+ Buffalo LS-VL Series.
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/mach-kirkwood/lsvl-setup.c linux-3.2.33-go/arch/arm/mach-kirkwood/lsvl-setup.c
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/mach-kirkwood/lsvl-setup.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/mach-kirkwood/lsvl-setup.c 2012-11-14 21:22:54.158568343 +0100
|
||||||
|
@@ -0,0 +1,340 @@
|
||||||
|
+/*
|
||||||
|
+ * arch/arm/mach-kirkwood/lsvl-setup.c
|
||||||
|
+ *
|
||||||
|
+ * Buffalo LS-VL Series Setup
|
||||||
|
+ *
|
||||||
|
+ * This file is licensed under the terms of the GNU General Public
|
||||||
|
+ * License version 2. This program is licensed "as is" without any
|
||||||
|
+ * warranty of any kind, whether express or implied.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/ata_platform.h>
|
||||||
|
+#include <linux/mtd/partitions.h>
|
||||||
|
+#include <linux/spi/flash.h>
|
||||||
|
+#include <linux/spi/spi.h>
|
||||||
|
+#include <linux/mv643xx_eth.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+#include <linux/gpio-fan.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+#include <asm/mach/arch.h>
|
||||||
|
+#include <mach/kirkwood.h>
|
||||||
|
+#include <plat/mvsdio.h>
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "mpp.h"
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 512KB SPI Flash on BOOT Device
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mtd_partition lsvl_partitions[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "u-boot",
|
||||||
|
+ .size = 0x80000,
|
||||||
|
+ .offset = 0x00000,
|
||||||
|
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct flash_platform_data lsvl_spi_slave_data = {
|
||||||
|
+ .type = "m25p40-nonjedec",
|
||||||
|
+ .parts = lsvl_partitions,
|
||||||
|
+ .nr_parts = ARRAY_SIZE(lsvl_partitions),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct spi_board_info __initdata lsvl_spi_slave_info[] = {
|
||||||
|
+ {
|
||||||
|
+ .modalias = "m25p80",
|
||||||
|
+ .platform_data = &lsvl_spi_slave_data,
|
||||||
|
+ .irq = -1,
|
||||||
|
+ .max_speed_hz = 20000000,
|
||||||
|
+ .bus_num = 0,
|
||||||
|
+ .chip_select = 0,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Ethernet
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv643xx_eth_platform_data lsvl_ge00_data = {
|
||||||
|
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * SATA
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv_sata_platform_data lsvl_sata_data = {
|
||||||
|
+ .n_ports = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LEDs attached to GPIO
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSVL_GPIO_LED_ALARM 36
|
||||||
|
+#define LSVL_GPIO_LED_FUNC_RED 37
|
||||||
|
+#define LSVL_GPIO_LED_INFO 38
|
||||||
|
+#define LSVL_GPIO_LED_FUNC_BLUE 39
|
||||||
|
+#define LSVL_GPIO_LED_PWR 40
|
||||||
|
+
|
||||||
|
+static struct gpio_led lsvl_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "alarm:red",
|
||||||
|
+ .gpio = LSVL_GPIO_LED_ALARM,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "func:red:bottom",
|
||||||
|
+ .gpio = LSVL_GPIO_LED_FUNC_RED,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "info:amber",
|
||||||
|
+ .gpio = LSVL_GPIO_LED_INFO,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "func:blue:bottom",
|
||||||
|
+ .gpio = LSVL_GPIO_LED_FUNC_BLUE,
|
||||||
|
+ },
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ .name = "power:blue",
|
||||||
|
+ .default_trigger = "default-on",
|
||||||
|
+ .gpio = LSVL_GPIO_LED_PWR,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_led_platform_data lsvl_led_data = {
|
||||||
|
+ .leds = lsvl_led_pins,
|
||||||
|
+ .num_leds = ARRAY_SIZE(lsvl_led_pins),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsvl_leds = {
|
||||||
|
+ .name = "leds-gpio",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsvl_led_data,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * General Setup
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSVL_GPIO_HDD_POWER 8
|
||||||
|
+#define LSVL_GPIO_USB_POWER 12
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Attached Keys
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*#define LSVL_GPIO_KEY_FUNC 45
|
||||||
|
+#define LSVL_GPIO_KEY_POWER 46
|
||||||
|
+#define LSVL_GPIO_KEY_AUTOPOWER 47
|
||||||
|
+#define LSVL_SW_POWER 0x00
|
||||||
|
+#define LSVL_SW_AUTOPOWER 0x01
|
||||||
|
+#define LSVL_SW_FUNC 0x02
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lsvl_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSVL_SW_POWER,
|
||||||
|
+ .gpio = LSVL_GPIO_KEY_POWER,
|
||||||
|
+ .desc = "Power-on Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSVL_SW_AUTOPOWER,
|
||||||
|
+ .gpio = LSVL_GPIO_KEY_AUTOPOWER,
|
||||||
|
+ .desc = "Power-auto Switch",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_SW,
|
||||||
|
+ .code = LSVL_SW_FUNC,
|
||||||
|
+ .gpio = LSVL_GPIO_KEY_FUNC,
|
||||||
|
+ .desc = "Function Button",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_platform_data lsvl_button_data = {
|
||||||
|
+ .buttons = lsvl_buttons,
|
||||||
|
+ .nbuttons = ARRAY_SIZE(lsvl_buttons),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsvl_button_device = {
|
||||||
|
+ .name = "gpio-keys",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsvl_button_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Fan
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSVL_GPIO_FAN_HIGH 16
|
||||||
|
+#define LSVL_GPIO_FAN_LOW 17
|
||||||
|
+#define LSVL_GPIO_FAN_LOCK 43
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_alarm lsvl_alarm = {
|
||||||
|
+ .gpio = LSVL_GPIO_FAN_LOCK,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_speed lsvl_speeds[] = {
|
||||||
|
+ {
|
||||||
|
+ .rpm = 0,
|
||||||
|
+ .ctrl_val = 3,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 1500,
|
||||||
|
+ .ctrl_val = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 3250,
|
||||||
|
+ .ctrl_val = 2,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 5000,
|
||||||
|
+ .ctrl_val = 0,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int lsvl_gpio_list[] = {
|
||||||
|
+ LSVL_GPIO_FAN_HIGH, LSVL_GPIO_FAN_LOW,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_platform_data lsvl_fan_data = {
|
||||||
|
+ .num_ctrl = ARRAY_SIZE(lsvl_gpio_list),
|
||||||
|
+ .ctrl = lsvl_gpio_list,
|
||||||
|
+ .alarm = &lsvl_alarm,
|
||||||
|
+ .num_speed = ARRAY_SIZE(lsvl_speeds),
|
||||||
|
+ .speed = lsvl_speeds,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lsvl_fan_device = {
|
||||||
|
+ .name = "gpio-fan",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lsvl_fan_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Data
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static unsigned int lsvl_mpp_config[] __initdata = {
|
||||||
|
+ MPP0_NF_IO2,
|
||||||
|
+ MPP1_NF_IO3,
|
||||||
|
+ MPP2_NF_IO4,
|
||||||
|
+ MPP3_NF_IO5,
|
||||||
|
+ MPP4_NF_IO6,
|
||||||
|
+ MPP5_NF_IO7,
|
||||||
|
+ MPP6_SYSRST_OUTn,
|
||||||
|
+ MPP7_SPI_SCn,
|
||||||
|
+ MPP8_GPIO, /* HDD Power */
|
||||||
|
+ MPP9_GPIO,
|
||||||
|
+ MPP10_UART0_TXD,
|
||||||
|
+ MPP11_UART0_RXD,
|
||||||
|
+ MPP12_GPO, /* USB VBUS EN */
|
||||||
|
+ MPP13_GPIO,
|
||||||
|
+ MPP14_GPIO,
|
||||||
|
+ MPP15_GPIO,
|
||||||
|
+ MPP16_GPIO, /* FAN HIGH: on:0, off:1 */
|
||||||
|
+ MPP17_GPIO, /* FAN LOW: on:0, off:1 */
|
||||||
|
+ MPP18_NF_IO0,
|
||||||
|
+ MPP19_NF_IO1,
|
||||||
|
+ MPP20_GPIO,
|
||||||
|
+ MPP21_GPIO,
|
||||||
|
+ MPP22_GPIO,
|
||||||
|
+ MPP23_GPIO,
|
||||||
|
+ MPP24_GPIO,
|
||||||
|
+ MPP25_GPIO,
|
||||||
|
+ MPP26_GPIO,
|
||||||
|
+ MPP27_GPIO,
|
||||||
|
+ MPP28_GPIO,
|
||||||
|
+ MPP29_GPIO,
|
||||||
|
+ MPP30_GPIO,
|
||||||
|
+ MPP31_GPIO,
|
||||||
|
+ MPP32_GPIO,
|
||||||
|
+ MPP33_GPO,
|
||||||
|
+ MPP34_GPIO,
|
||||||
|
+ MPP35_GPIO,
|
||||||
|
+ MPP36_GPIO, /* ALARM LED */
|
||||||
|
+ MPP37_GPIO, /* FUNC RED LED */
|
||||||
|
+ MPP38_GPIO, /* INFO LED */
|
||||||
|
+ MPP39_GPIO, /* FUNC LED */
|
||||||
|
+ MPP40_GPIO, /* POWER LED */
|
||||||
|
+ MPP41_GPIO,
|
||||||
|
+ MPP42_GPIO,
|
||||||
|
+ MPP43_GPIO, /* FAN LOCK */
|
||||||
|
+ MPP44_GPIO,
|
||||||
|
+ MPP45_GPIO, /* FUNC SW */
|
||||||
|
+ MPP46_GPIO, /* POWER SW */
|
||||||
|
+ MPP47_GPIO, /* POWER AUTO SW */
|
||||||
|
+ MPP48_GPIO, /* UART EN */
|
||||||
|
+ MPP49_GPIO,
|
||||||
|
+ 0
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LS-VL specific power off method: reboot
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * On the LS-VL, the shutdown process is following:
|
||||||
|
+ * - Userland monitors key events until the power switch goes to off position
|
||||||
|
+ * - The board reboots
|
||||||
|
+ * - U-boot starts and goes into an idle mode waiting for the user
|
||||||
|
+ * to move the switch to ON position
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void lsvl_power_off(void)
|
||||||
|
+{
|
||||||
|
+ arm_machine_restart('h', NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __init lsvl_init(void)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Basic setup. Needs to be called early.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_init();
|
||||||
|
+ kirkwood_mpp_conf(lsvl_mpp_config);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Configure peripherals.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_uart0_init();
|
||||||
|
+ kirkwood_ehci_init();
|
||||||
|
+ kirkwood_ge00_init(&lsvl_ge00_data);
|
||||||
|
+ kirkwood_sata_init(&lsvl_sata_data);
|
||||||
|
+ kirkwood_spi_init();
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lsvl_leds);
|
||||||
|
+// platform_device_register(&lsvl_button_device);
|
||||||
|
+ platform_device_register(&lsvl_fan_device);
|
||||||
|
+
|
||||||
|
+ spi_register_board_info(lsvl_spi_slave_info,
|
||||||
|
+ ARRAY_SIZE(lsvl_spi_slave_info));
|
||||||
|
+
|
||||||
|
+ /* usb power on */
|
||||||
|
+ gpio_set_value(LSVL_GPIO_USB_POWER, 1);
|
||||||
|
+
|
||||||
|
+ /* register power-off method */
|
||||||
|
+ pm_power_off = lsvl_power_off;
|
||||||
|
+
|
||||||
|
+ pr_info("%s: finished\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MACHINE_START(LSVL, "Buffalo LS-VL Series")
|
||||||
|
+ .atag_offset = 0x100,
|
||||||
|
+ .init_machine = lsvl_init,
|
||||||
|
+ .map_io = kirkwood_map_io,
|
||||||
|
+ .init_early = kirkwood_init_early,
|
||||||
|
+ .init_irq = kirkwood_init_irq,
|
||||||
|
+ .timer = &kirkwood_timer,
|
||||||
|
+MACHINE_END
|
||||||
|
+
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/mach-kirkwood/Makefile linux-3.2.33-go/arch/arm/mach-kirkwood/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/mach-kirkwood/Makefile 2012-11-14 21:20:22.326388580 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/mach-kirkwood/Makefile 2012-11-14 21:22:20.882968794 +0100
|
||||||
|
@@ -19,5 +19,6 @@
|
||||||
|
obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
|
||||||
|
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LSXHL) += lsxhl-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_LSVL) += lsvl-setup.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/tools/mach-types linux-3.2.33-go/arch/arm/tools/mach-types
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/tools/mach-types 2012-11-14 21:20:22.348388327 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/tools/mach-types 2012-11-14 21:21:02.356908648 +0100
|
||||||
|
@@ -118,6 +118,7 @@
|
||||||
|
omap_osk MACH_OMAP_OSK OMAP_OSK 515
|
||||||
|
tosa MACH_TOSA TOSA 520
|
||||||
|
avila MACH_AVILA AVILA 526
|
||||||
|
+lsvl MACH_LSVL LSVL 5277
|
||||||
|
edb9302 MACH_EDB9302 EDB9302 538
|
||||||
|
husky MACH_HUSKY HUSKY 543
|
||||||
|
shepherd MACH_SHEPHERD SHEPHERD 545
|
538
3.2.34/v3.2-ARM-kirkwood-Add-support-for-Buffalo-LS-WVL.patch
Normal file
538
3.2.34/v3.2-ARM-kirkwood-Add-support-for-Buffalo-LS-WVL.patch
Normal file
@ -0,0 +1,538 @@
|
|||||||
|
diff -uNr linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Kconfig linux-3.2.34-go/arch/arm/mach-kirkwood/Kconfig
|
||||||
|
--- linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Kconfig 2012-11-19 21:03:42.654743005 +0100
|
||||||
|
+++ linux-3.2.34-go/arch/arm/mach-kirkwood/Kconfig 2012-11-19 21:04:02.744505974 +0100
|
||||||
|
@@ -148,6 +148,12 @@
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Buffalo LS-CHLv2 Series.
|
||||||
|
|
||||||
|
+config MACH_LSWVL
|
||||||
|
+ bool "Buffalo LS-WVL Series"
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the
|
||||||
|
+ Buffalo LS-WVL/E-AP NAS
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
||||||
|
diff -uNr linux-3.2.34-go.orig/arch/arm/mach-kirkwood/lswvl-setup.c linux-3.2.34-go/arch/arm/mach-kirkwood/lswvl-setup.c
|
||||||
|
--- linux-3.2.34-go.orig/arch/arm/mach-kirkwood/lswvl-setup.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-3.2.34-go/arch/arm/mach-kirkwood/lswvl-setup.c 2012-11-19 21:04:02.745505962 +0100
|
||||||
|
@@ -0,0 +1,366 @@
|
||||||
|
+/*
|
||||||
|
+ * arch/arm/mach-kirkwood/lswvl-setup.c
|
||||||
|
+ *
|
||||||
|
+ * Buffalo LS-WVL Series Setup
|
||||||
|
+ *
|
||||||
|
+ * This file is licensed under the terms of the GNU General Public
|
||||||
|
+ * License version 2. This program is licensed "as is" without any
|
||||||
|
+ * warranty of any kind, whether express or implied.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/mtd/physmap.h>
|
||||||
|
+#include <linux/ata_platform.h>
|
||||||
|
+#include <linux/mtd/partitions.h>
|
||||||
|
+#include <linux/spi/flash.h>
|
||||||
|
+#include <linux/spi/spi.h>
|
||||||
|
+#include <linux/mv643xx_eth.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+#include <linux/gpio-fan.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+#include <asm/mach/arch.h>
|
||||||
|
+#include <mach/kirkwood.h>
|
||||||
|
+#include <plat/orion_nand.h>
|
||||||
|
+#include <plat/mvsdio.h>
|
||||||
|
+#include "common.h"
|
||||||
|
+#include "mpp.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 512MB NAND Flash on Device bus CS0
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mtd_partition lswvl_nand_parts[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "boot",
|
||||||
|
+ .offset = 0,
|
||||||
|
+ .size = 16 * 1024 * 1024,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "rootfs",
|
||||||
|
+ .offset = MTDPART_OFS_NXTBLK,
|
||||||
|
+ .size = 488 * 1024 * 1024,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "reserve",
|
||||||
|
+ .offset = MTDPART_OFS_NXTBLK,
|
||||||
|
+ .size = MTDPART_SIZ_FULL,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * 512KB NOR Flash on BOOT Device
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mtd_partition lswvl_partitions[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "u-boot",
|
||||||
|
+ .size = 0x80000,
|
||||||
|
+ .offset = 0x00000,
|
||||||
|
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct flash_platform_data lswvl_spi_slave_data = {
|
||||||
|
+ .parts = lswvl_partitions,
|
||||||
|
+ .nr_parts = ARRAY_SIZE(lswvl_partitions),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct spi_board_info __initdata lswvl_spi_slave_info[] = {
|
||||||
|
+ {
|
||||||
|
+ .modalias = "m25p80",
|
||||||
|
+ .platform_data = &lswvl_spi_slave_data,
|
||||||
|
+ .irq = -1,
|
||||||
|
+ .max_speed_hz = 20000000,
|
||||||
|
+ .bus_num = 0,
|
||||||
|
+ .chip_select = 0,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * Ethernet
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv643xx_eth_platform_data lswvl_ge00_data = {
|
||||||
|
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * SATA
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+static struct mv_sata_platform_data lswvl_sata_data = {
|
||||||
|
+ .n_ports = 2,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LEDs attached to GPIO
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSWVL_GPIO_LED_HDDERR0 34
|
||||||
|
+#define LSWVL_GPIO_LED_HDDERR1 35
|
||||||
|
+#define LSWVL_GPIO_LED_ALARM 36
|
||||||
|
+#define LSWVL_GPIO_LED_FUNC_RED 37
|
||||||
|
+#define LSWVL_GPIO_LED_INFO 38
|
||||||
|
+#define LSWVL_GPIO_LED_FUNC_BLUE 39
|
||||||
|
+#define LSWVL_GPIO_LED_PWR 40
|
||||||
|
+
|
||||||
|
+static struct gpio_led lswvl_led_pins[] = {
|
||||||
|
+ {
|
||||||
|
+ .name = "lswvl:hdderr:0",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_HDDERR0,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "lswvl:hdderr:1",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_HDDERR1,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "lswvl:alarm:red",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_ALARM,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "lswvl:func:red",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_FUNC_RED,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "lswvl:info:amber",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_INFO,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "lswvl:func:blue",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_FUNC_BLUE,
|
||||||
|
+ }, {
|
||||||
|
+ .name = "lswvl:power:blue",
|
||||||
|
+ .default_trigger = "default-on",
|
||||||
|
+ .gpio = LSWVL_GPIO_LED_PWR,
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_led_platform_data lswvl_led_data = {
|
||||||
|
+ .leds = lswvl_led_pins,
|
||||||
|
+ .num_leds = ARRAY_SIZE(lswvl_led_pins),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lswvl_leds = {
|
||||||
|
+ .name = "leds-gpio",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lswvl_led_data,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * General Setup
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSWVL_GPIO_HDD0_POWER 8
|
||||||
|
+#define LSWVL_GPIO_HDD1_POWER 9
|
||||||
|
+#define LSWVL_GPIO_USB_POWER 12
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Attached Keys
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSWVL_GPIO_KEY_FUNC 45
|
||||||
|
+#define LSWVL_GPIO_KEY_POWER 46
|
||||||
|
+#define LSWVL_GPIO_KEY_AUTOPOWER 47
|
||||||
|
+#define LSWVL_SW_POWER 0x00
|
||||||
|
+#define LSWVL_SW_AUTOPOWER 0x01
|
||||||
|
+#define LSWVL_SW_FUNC 0x02
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_button lswvl_buttons[] = {
|
||||||
|
+ {
|
||||||
|
+ .type = EV_KEY,
|
||||||
|
+ .code = BTN_1,
|
||||||
|
+ .gpio = LSWVL_GPIO_KEY_POWER,
|
||||||
|
+ .desc = "power-on",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_KEY,
|
||||||
|
+ .code = BTN_2,
|
||||||
|
+ .gpio = LSWVL_GPIO_KEY_AUTOPOWER,
|
||||||
|
+ .desc = "power-auto",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .type = EV_KEY,
|
||||||
|
+ .code = BTN_0,
|
||||||
|
+ .gpio = LSWVL_GPIO_KEY_FUNC,
|
||||||
|
+ .desc = "function",
|
||||||
|
+ .active_low = 1,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_keys_platform_data lswvl_button_data = {
|
||||||
|
+ .buttons = lswvl_buttons,
|
||||||
|
+ .nbuttons = ARRAY_SIZE(lswvl_buttons),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lswvl_button_device = {
|
||||||
|
+ .name = "gpio-keys",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lswvl_button_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Fan
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+#define LSWVL_GPIO_FAN_HIGH 16
|
||||||
|
+#define LSWVL_GPIO_FAN_LOW 17
|
||||||
|
+#define LSWVL_GPIO_FAN_LOCK 43
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_alarm lswvl_alarm = {
|
||||||
|
+ .gpio = LSWVL_GPIO_FAN_LOCK,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_speed lswvl_speeds[] = {
|
||||||
|
+ {
|
||||||
|
+ .rpm = 0,
|
||||||
|
+ .ctrl_val = 3,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 1500,
|
||||||
|
+ .ctrl_val = 1,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 3250,
|
||||||
|
+ .ctrl_val = 2,
|
||||||
|
+ }, {
|
||||||
|
+ .rpm = 5000,
|
||||||
|
+ .ctrl_val = 0,
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int lswvl_gpio_list[] = {
|
||||||
|
+ LSWVL_GPIO_FAN_HIGH, LSWVL_GPIO_FAN_LOW,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_fan_platform_data lswvl_fan_data = {
|
||||||
|
+ .num_ctrl = ARRAY_SIZE(lswvl_gpio_list),
|
||||||
|
+ .ctrl = lswvl_gpio_list,
|
||||||
|
+ .alarm = &lswvl_alarm,
|
||||||
|
+ .num_speed = ARRAY_SIZE(lswvl_speeds),
|
||||||
|
+ .speed = lswvl_speeds,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device lswvl_fan_device = {
|
||||||
|
+ .name = "gpio-fan",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .num_resources = 0,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &lswvl_fan_data,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * GPIO Data
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+
|
||||||
|
+static unsigned int lswvl_mpp_config[] __initdata = {
|
||||||
|
+ MPP0_NF_IO2,
|
||||||
|
+ MPP1_NF_IO3,
|
||||||
|
+ MPP2_NF_IO4,
|
||||||
|
+ MPP3_NF_IO5,
|
||||||
|
+ MPP4_NF_IO6,
|
||||||
|
+ MPP5_NF_IO7,
|
||||||
|
+ MPP6_SYSRST_OUTn,
|
||||||
|
+ MPP7_SPI_SCn,
|
||||||
|
+ MPP8_GPIO, /* HDD Power */
|
||||||
|
+ MPP9_GPIO, /* HDD Power */
|
||||||
|
+ MPP10_UART0_TXD,
|
||||||
|
+ MPP11_UART0_RXD,
|
||||||
|
+ MPP12_GPO, /* USB VBUS EN */
|
||||||
|
+ MPP13_GPIO,
|
||||||
|
+ MPP14_GPIO,
|
||||||
|
+ MPP15_GPIO,
|
||||||
|
+ MPP16_GPIO, /* FAN HIGH: on:0, off:1 */
|
||||||
|
+ MPP17_GPIO, /* FAN LOW: on:0, off:1 */
|
||||||
|
+ MPP18_NF_IO0,
|
||||||
|
+ MPP19_NF_IO1,
|
||||||
|
+ MPP20_GPIO,
|
||||||
|
+ MPP21_GPIO,
|
||||||
|
+ MPP22_GPIO,
|
||||||
|
+ MPP23_GPIO,
|
||||||
|
+ MPP24_GPIO,
|
||||||
|
+ MPP25_GPIO,
|
||||||
|
+ MPP26_GPIO,
|
||||||
|
+ MPP27_GPIO,
|
||||||
|
+ MPP28_GPIO,
|
||||||
|
+ MPP29_GPIO,
|
||||||
|
+ MPP30_GPIO,
|
||||||
|
+ MPP31_GPIO,
|
||||||
|
+ MPP32_GPIO,
|
||||||
|
+ MPP33_GPO,
|
||||||
|
+ MPP34_GPIO, /*HDD ERROR LED 0*/
|
||||||
|
+ MPP35_GPIO, /*HDD ERROR LED 1*/
|
||||||
|
+ MPP36_GPIO, /* ALARM LED */
|
||||||
|
+ MPP37_GPIO, /* FUNC RED LED */
|
||||||
|
+ MPP38_GPIO, /* INFO LED */
|
||||||
|
+ MPP39_GPIO, /* FUNC LED */
|
||||||
|
+ MPP40_GPIO, /* POWER LED */
|
||||||
|
+ MPP41_GPIO,
|
||||||
|
+ MPP42_GPIO,
|
||||||
|
+ MPP43_GPIO, /* FAN LOCK */
|
||||||
|
+ MPP44_GPIO,
|
||||||
|
+ MPP45_GPIO, /* FUNC SW */
|
||||||
|
+ MPP46_GPIO, /* POWER SW */
|
||||||
|
+ MPP47_GPIO, /* POWER AUTO SW */
|
||||||
|
+ MPP48_GPIO, /* UART EN */
|
||||||
|
+ MPP49_GPIO,
|
||||||
|
+ 0
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*****************************************************************************
|
||||||
|
+ * LS-WVL specific power off method: reboot
|
||||||
|
+ ****************************************************************************/
|
||||||
|
+/*
|
||||||
|
+ * On the LS-WVL, the shutdown process is following:
|
||||||
|
+ * - Userland monitors key events until the power switch goes to off position
|
||||||
|
+ * - The board reboots
|
||||||
|
+ * - U-boot starts and goes into an idle mode waiting for the user
|
||||||
|
+ * to move the switch to ON position
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void lswvl_power_off(void)
|
||||||
|
+{
|
||||||
|
+ arm_machine_restart('h', NULL); //kirkwood_restart('h', NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __init lswvl_init(void)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Basic setup. Needs to be called early.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_init();
|
||||||
|
+ kirkwood_mpp_conf(lswvl_mpp_config);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Configure peripherals.
|
||||||
|
+ */
|
||||||
|
+ kirkwood_ge00_init(&lswvl_ge00_data);
|
||||||
|
+ kirkwood_uart0_init();
|
||||||
|
+ kirkwood_uart1_init();
|
||||||
|
+ kirkwood_ehci_init();
|
||||||
|
+ kirkwood_sata_init(&lswvl_sata_data);
|
||||||
|
+
|
||||||
|
+ spi_register_board_info(lswvl_spi_slave_info,
|
||||||
|
+ ARRAY_SIZE(lswvl_spi_slave_info));
|
||||||
|
+ kirkwood_spi_init();
|
||||||
|
+ kirkwood_nand_init(ARRAY_AND_SIZE(lswvl_nand_parts), 25);
|
||||||
|
+
|
||||||
|
+ platform_device_register(&lswvl_leds);
|
||||||
|
+ platform_device_register(&lswvl_button_device);
|
||||||
|
+ platform_device_register(&lswvl_fan_device);
|
||||||
|
+
|
||||||
|
+ /* usb power on */
|
||||||
|
+ gpio_set_value(LSWVL_GPIO_USB_POWER, 1);
|
||||||
|
+
|
||||||
|
+ /* register power-off method */
|
||||||
|
+ pm_power_off = lswvl_power_off;
|
||||||
|
+
|
||||||
|
+ pr_info("%s: finished\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MACHINE_START(LSWVL, "Buffalo LS-WVL Series")
|
||||||
|
+ .atag_offset = 0x100,
|
||||||
|
+ .map_io = kirkwood_map_io,
|
||||||
|
+ .init_early = kirkwood_init_early,
|
||||||
|
+ .init_irq = kirkwood_init_irq,
|
||||||
|
+ .timer = &kirkwood_timer,
|
||||||
|
+ .init_machine = lswvl_init,
|
||||||
|
+ // .restart = kirkwood_restart,
|
||||||
|
+MACHINE_END
|
||||||
|
+
|
||||||
|
diff -uNr linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Makefile linux-3.2.34-go/arch/arm/mach-kirkwood/Makefile
|
||||||
|
--- linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Makefile 2012-11-19 21:03:42.653743017 +0100
|
||||||
|
+++ linux-3.2.34-go/arch/arm/mach-kirkwood/Makefile 2012-11-19 21:04:42.686036907 +0100
|
||||||
|
@@ -21,5 +21,6 @@
|
||||||
|
obj-$(CONFIG_MACH_LINKSTATION_CHLV2) += lschlv2-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LSXHL) += lsxhl-setup.o
|
||||||
|
obj-$(CONFIG_MACH_LSVL) += lsvl-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_LSWVL) += lswvl-setup.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||||
|
diff -uNr linux-3.2.34-go.orig/arch/arm/plat-orion/mpp.c linux-3.2.34-go/arch/arm/plat-orion/mpp.c
|
||||||
|
--- linux-3.2.34-go.orig/arch/arm/plat-orion/mpp.c 2012-11-19 21:03:42.766741717 +0100
|
||||||
|
+++ linux-3.2.34-go/arch/arm/plat-orion/mpp.c 2012-11-19 21:04:02.747505938 +0100
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <plat/mpp.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
|
||||||
|
/* Address of the ith MPP control register */
|
||||||
|
static __init unsigned long mpp_ctrl_addr(unsigned int i,
|
||||||
|
@@ -75,3 +76,37 @@
|
||||||
|
}
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+
|
||||||
|
+static u32 boot_mpp_value = 0x21111111;
|
||||||
|
+/*
|
||||||
|
+ * change MPP[3:1] to SPI mode
|
||||||
|
+ */
|
||||||
|
+void lswvl_setup_spi_mpp(void)
|
||||||
|
+{
|
||||||
|
+ u32 spival = 0;
|
||||||
|
+ u32 bootval = 0;
|
||||||
|
+
|
||||||
|
+ spival = 0x00002220;
|
||||||
|
+ boot_mpp_value = bootval = readl(mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE));
|
||||||
|
+ bootval &= 0xffff000f;
|
||||||
|
+ writel(spival | bootval, mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * change back MPP[3:1] to default configuration
|
||||||
|
+ */
|
||||||
|
+void lswvl_reset_mpp(void)
|
||||||
|
+{
|
||||||
|
+ u32 spival = 0;
|
||||||
|
+ u32 bootval = 0;
|
||||||
|
+
|
||||||
|
+ spival = readl(mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE));
|
||||||
|
+ spival &= 0xffff000f;
|
||||||
|
+ bootval = boot_mpp_value & ~0xffff000f;
|
||||||
|
+ writel(spival | bootval, mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
diff -uNr linux-3.2.34-go.orig/arch/arm/tools/mach-types linux-3.2.34-go/arch/arm/tools/mach-types
|
||||||
|
--- linux-3.2.34-go.orig/arch/arm/tools/mach-types 2012-11-19 21:03:42.675742765 +0100
|
||||||
|
+++ linux-3.2.34-go/arch/arm/tools/mach-types 2012-11-19 21:22:29.653445807 +0100
|
||||||
|
@@ -119,6 +119,7 @@
|
||||||
|
tosa MACH_TOSA TOSA 520
|
||||||
|
avila MACH_AVILA AVILA 526
|
||||||
|
lsvl MACH_LSVL LSVL 5277
|
||||||
|
+lswvl MACH_LSWVL LSWVL 5278
|
||||||
|
edb9302 MACH_EDB9302 EDB9302 538
|
||||||
|
husky MACH_HUSKY HUSKY 543
|
||||||
|
shepherd MACH_SHEPHERD SHEPHERD 545
|
||||||
|
diff -uNr linux-3.2.34-go.orig/drivers/spi/spi-orion.c linux-3.2.34-go/drivers/spi/spi-orion.c
|
||||||
|
--- linux-3.2.34-go.orig/drivers/spi/spi-orion.c 2012-11-19 21:03:41.809752734 +0100
|
||||||
|
+++ linux-3.2.34-go/drivers/spi/spi-orion.c 2012-11-19 21:20:55.123558883 +0100
|
||||||
|
@@ -19,6 +19,12 @@
|
||||||
|
#include <linux/spi/orion_spi.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
+#include <asm/mach-types.h>
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+void lswvl_setup_spi_mpp(void);
|
||||||
|
+void lswvl_reset_mpp(void);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#define DRIVER_NAME "orion_spi"
|
||||||
|
|
||||||
|
@@ -141,6 +147,9 @@
|
||||||
|
unsigned int bits_per_word = spi->bits_per_word;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+ lswvl_setup_spi_mpp();
|
||||||
|
+#endif
|
||||||
|
orion_spi = spi_master_get_devdata(spi->master);
|
||||||
|
|
||||||
|
if ((t != NULL) && t->speed_hz)
|
||||||
|
@@ -153,15 +162,37 @@
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+ rc = orion_spi_set_transfer_size(orion_spi, bits_per_word);
|
||||||
|
+ lswvl_reset_mpp();
|
||||||
|
+ return rc;
|
||||||
|
+#else
|
||||||
|
return orion_spi_set_transfer_size(orion_spi, bits_per_word);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+ {
|
||||||
|
+ lswvl_setup_spi_mpp();
|
||||||
|
+ udelay(1);
|
||||||
|
+ orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
|
||||||
|
+#endif
|
||||||
|
else
|
||||||
|
orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+ {
|
||||||
|
+ orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
|
||||||
|
+ lswvl_reset_mpp();
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
+ orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
|
||||||
|
@@ -361,8 +392,17 @@
|
||||||
|
|
||||||
|
/* Fix ac timing if required. */
|
||||||
|
if (orion_spi->spi_info->enable_clock_fix)
|
||||||
|
+#ifdef CONFIG_MACH_LSWVL
|
||||||
|
+ {
|
||||||
|
+ lswvl_setup_spi_mpp();
|
||||||
|
+ orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
|
||||||
|
+ (1 << 14));
|
||||||
|
+ lswvl_reset_mpp();
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
|
||||||
|
(1 << 14));
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if ((spi->max_speed_hz == 0)
|
||||||
|
|| (spi->max_speed_hz > orion_spi->max_speed))
|
26125
3.2.34/vserver-3.2.34-vs2.3.2.15.patch
Normal file
26125
3.2.34/vserver-3.2.34-vs2.3.2.15.patch
Normal file
File diff suppressed because it is too large
Load Diff
2084
3.2.34/wrapfs-v3.2.2-45-ga5296eb.patch
Normal file
2084
3.2.34/wrapfs-v3.2.2-45-ga5296eb.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,553 @@
|
|||||||
|
From dc13dec93dbd04bfa7a9ba67df1b8ed3431d8d48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
|
Date: Wed, 10 Aug 2011 22:02:39 -0700
|
||||||
|
Subject: [PATCH 1/3] AppArmor: compatibility patch for v5 network controll
|
||||||
|
|
||||||
|
Add compatibility for v5 network rules.
|
||||||
|
|
||||||
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
---
|
||||||
|
include/linux/lsm_audit.h | 4 +
|
||||||
|
security/apparmor/Makefile | 19 ++++-
|
||||||
|
security/apparmor/include/net.h | 40 +++++++++
|
||||||
|
security/apparmor/include/policy.h | 3 +
|
||||||
|
security/apparmor/lsm.c | 112 +++++++++++++++++++++++
|
||||||
|
security/apparmor/net.c | 170 ++++++++++++++++++++++++++++++++++++
|
||||||
|
security/apparmor/policy.c | 1 +
|
||||||
|
security/apparmor/policy_unpack.c | 48 ++++++++++-
|
||||||
|
8 files changed, 394 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 security/apparmor/include/net.h
|
||||||
|
create mode 100644 security/apparmor/net.c
|
||||||
|
|
||||||
|
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
|
||||||
|
index 88e78de..c63979a 100644
|
||||||
|
--- a/include/linux/lsm_audit.h
|
||||||
|
+++ b/include/linux/lsm_audit.h
|
||||||
|
@@ -124,6 +124,10 @@ struct common_audit_data {
|
||||||
|
u32 denied;
|
||||||
|
uid_t ouid;
|
||||||
|
} fs;
|
||||||
|
+ struct {
|
||||||
|
+ int type, protocol;
|
||||||
|
+ struct sock *sk;
|
||||||
|
+ } net;
|
||||||
|
};
|
||||||
|
} apparmor_audit_data;
|
||||||
|
#endif
|
||||||
|
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||||
|
index 2dafe50..7cefef9 100644
|
||||||
|
--- a/security/apparmor/Makefile
|
||||||
|
+++ b/security/apparmor/Makefile
|
||||||
|
@@ -4,9 +4,9 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||||
|
|
||||||
|
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||||
|
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||||
|
- resource.o sid.o file.o
|
||||||
|
+ resource.o sid.o file.o net.o
|
||||||
|
|
||||||
|
-clean-files := capability_names.h rlim_names.h
|
||||||
|
+clean-files := capability_names.h rlim_names.h af_names.h
|
||||||
|
|
||||||
|
|
||||||
|
# Build a lower case string table of capability names
|
||||||
|
@@ -44,9 +44,24 @@ cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ;\
|
||||||
|
sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
|
||||||
|
echo "};" >> $@
|
||||||
|
|
||||||
|
+# Build a lower case string table of address family names.
|
||||||
|
+# Transform lines from
|
||||||
|
+# #define AF_INET 2 /* Internet IP Protocol */
|
||||||
|
+# to
|
||||||
|
+# [2] = "inet",
|
||||||
|
+quiet_cmd_make-af = GEN $@
|
||||||
|
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
|
||||||
|
+ sed $< >> $@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
|
||||||
|
+ 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+).*/[\2] = "\L\1",/p';\
|
||||||
|
+ echo "};" >> $@
|
||||||
|
+
|
||||||
|
+
|
||||||
|
$(obj)/capability.o : $(obj)/capability_names.h
|
||||||
|
$(obj)/resource.o : $(obj)/rlim_names.h
|
||||||
|
+$(obj)/net.o : $(obj)/af_names.h
|
||||||
|
$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
|
||||||
|
$(call cmd,make-caps)
|
||||||
|
$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h
|
||||||
|
$(call cmd,make-rlim)
|
||||||
|
+$(obj)/af_names.h : $(srctree)/include/linux/socket.h
|
||||||
|
+ $(call cmd,make-af)
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3c7d599
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/security/apparmor/include/net.h
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+/*
|
||||||
|
+ * AppArmor security module
|
||||||
|
+ *
|
||||||
|
+ * This file contains AppArmor network mediation definitions.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||||
|
+ * Copyright 2009-2010 Canonical Ltd.
|
||||||
|
+ *
|
||||||
|
+ * 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, version 2 of the
|
||||||
|
+ * License.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __AA_NET_H
|
||||||
|
+#define __AA_NET_H
|
||||||
|
+
|
||||||
|
+#include <net/sock.h>
|
||||||
|
+
|
||||||
|
+/* struct aa_net - network confinement data
|
||||||
|
+ * @allowed: basic network families permissions
|
||||||
|
+ * @audit_network: which network permissions to force audit
|
||||||
|
+ * @quiet_network: which network permissions to quiet rejects
|
||||||
|
+ */
|
||||||
|
+struct aa_net {
|
||||||
|
+ u16 allow[AF_MAX];
|
||||||
|
+ u16 audit[AF_MAX];
|
||||||
|
+ u16 quiet[AF_MAX];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
|
||||||
|
+ int type, int protocol, struct sock *sk);
|
||||||
|
+extern int aa_revalidate_sk(int op, struct sock *sk);
|
||||||
|
+
|
||||||
|
+static inline void aa_free_net_rules(struct aa_net *new)
|
||||||
|
+{
|
||||||
|
+ /* NOP */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* __AA_NET_H */
|
||||||
|
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
|
||||||
|
index aeda5cf..6776929 100644
|
||||||
|
--- a/security/apparmor/include/policy.h
|
||||||
|
+++ b/security/apparmor/include/policy.h
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include "capability.h"
|
||||||
|
#include "domain.h"
|
||||||
|
#include "file.h"
|
||||||
|
+#include "net.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
extern const char *profile_mode_names[];
|
||||||
|
@@ -145,6 +146,7 @@ struct aa_namespace {
|
||||||
|
* @size: the memory consumed by this profiles rules
|
||||||
|
* @file: The set of rules governing basic file access and domain transitions
|
||||||
|
* @caps: capabilities for the profile
|
||||||
|
+ * @net: network controls for the profile
|
||||||
|
* @rlimits: rlimits for the profile
|
||||||
|
*
|
||||||
|
* The AppArmor profile contains the basic confinement data. Each profile
|
||||||
|
@@ -181,6 +183,7 @@ struct aa_profile {
|
||||||
|
|
||||||
|
struct aa_file_rules file;
|
||||||
|
struct aa_caps caps;
|
||||||
|
+ struct aa_net net;
|
||||||
|
struct aa_rlimit rlimits;
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||||
|
index 3d2fd14..aa293ae 100644
|
||||||
|
--- a/security/apparmor/lsm.c
|
||||||
|
+++ b/security/apparmor/lsm.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include "include/context.h"
|
||||||
|
#include "include/file.h"
|
||||||
|
#include "include/ipc.h"
|
||||||
|
+#include "include/net.h"
|
||||||
|
#include "include/path.h"
|
||||||
|
#include "include/policy.h"
|
||||||
|
#include "include/procattr.h"
|
||||||
|
@@ -621,6 +622,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile;
|
||||||
|
+ int error = 0;
|
||||||
|
+
|
||||||
|
+ if (kern)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ profile = __aa_current_profile();
|
||||||
|
+ if (!unconfined(profile))
|
||||||
|
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
|
||||||
|
+ NULL);
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_bind(struct socket *sock,
|
||||||
|
+ struct sockaddr *address, int addrlen)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_BIND, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_connect(struct socket *sock,
|
||||||
|
+ struct sockaddr *address, int addrlen)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_CONNECT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_listen(struct socket *sock, int backlog)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_LISTEN, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_ACCEPT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_sendmsg(struct socket *sock,
|
||||||
|
+ struct msghdr *msg, int size)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_SENDMSG, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_recvmsg(struct socket *sock,
|
||||||
|
+ struct msghdr *msg, int size, int flags)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_RECVMSG, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_getsockname(struct socket *sock)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_getpeername(struct socket *sock)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
|
||||||
|
+ int optname)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
|
||||||
|
+ int optname)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int apparmor_socket_shutdown(struct socket *sock, int how)
|
||||||
|
+{
|
||||||
|
+ struct sock *sk = sock->sk;
|
||||||
|
+
|
||||||
|
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct security_operations apparmor_ops = {
|
||||||
|
.name = "apparmor",
|
||||||
|
|
||||||
|
@@ -652,6 +751,19 @@ static struct security_operations apparmor_ops = {
|
||||||
|
.getprocattr = apparmor_getprocattr,
|
||||||
|
.setprocattr = apparmor_setprocattr,
|
||||||
|
|
||||||
|
+ .socket_create = apparmor_socket_create,
|
||||||
|
+ .socket_bind = apparmor_socket_bind,
|
||||||
|
+ .socket_connect = apparmor_socket_connect,
|
||||||
|
+ .socket_listen = apparmor_socket_listen,
|
||||||
|
+ .socket_accept = apparmor_socket_accept,
|
||||||
|
+ .socket_sendmsg = apparmor_socket_sendmsg,
|
||||||
|
+ .socket_recvmsg = apparmor_socket_recvmsg,
|
||||||
|
+ .socket_getsockname = apparmor_socket_getsockname,
|
||||||
|
+ .socket_getpeername = apparmor_socket_getpeername,
|
||||||
|
+ .socket_getsockopt = apparmor_socket_getsockopt,
|
||||||
|
+ .socket_setsockopt = apparmor_socket_setsockopt,
|
||||||
|
+ .socket_shutdown = apparmor_socket_shutdown,
|
||||||
|
+
|
||||||
|
.cred_alloc_blank = apparmor_cred_alloc_blank,
|
||||||
|
.cred_free = apparmor_cred_free,
|
||||||
|
.cred_prepare = apparmor_cred_prepare,
|
||||||
|
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1765901
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/security/apparmor/net.c
|
||||||
|
@@ -0,0 +1,170 @@
|
||||||
|
+/*
|
||||||
|
+ * AppArmor security module
|
||||||
|
+ *
|
||||||
|
+ * This file contains AppArmor network mediation
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||||
|
+ * Copyright 2009-2010 Canonical Ltd.
|
||||||
|
+ *
|
||||||
|
+ * 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, version 2 of the
|
||||||
|
+ * License.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "include/apparmor.h"
|
||||||
|
+#include "include/audit.h"
|
||||||
|
+#include "include/context.h"
|
||||||
|
+#include "include/net.h"
|
||||||
|
+#include "include/policy.h"
|
||||||
|
+
|
||||||
|
+#include "af_names.h"
|
||||||
|
+
|
||||||
|
+static const char *sock_type_names[] = {
|
||||||
|
+ "unknown(0)",
|
||||||
|
+ "stream",
|
||||||
|
+ "dgram",
|
||||||
|
+ "raw",
|
||||||
|
+ "rdm",
|
||||||
|
+ "seqpacket",
|
||||||
|
+ "dccp",
|
||||||
|
+ "unknown(7)",
|
||||||
|
+ "unknown(8)",
|
||||||
|
+ "unknown(9)",
|
||||||
|
+ "packet",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* audit callback for net specific fields */
|
||||||
|
+static void audit_cb(struct audit_buffer *ab, void *va)
|
||||||
|
+{
|
||||||
|
+ struct common_audit_data *sa = va;
|
||||||
|
+
|
||||||
|
+ audit_log_format(ab, " family=");
|
||||||
|
+ if (address_family_names[sa->u.net.family]) {
|
||||||
|
+ audit_log_string(ab, address_family_names[sa->u.net.family]);
|
||||||
|
+ } else {
|
||||||
|
+ audit_log_format(ab, " \"unknown(%d)\"", sa->u.net.family);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ audit_log_format(ab, " sock_type=");
|
||||||
|
+ if (sock_type_names[sa->aad.net.type]) {
|
||||||
|
+ audit_log_string(ab, sock_type_names[sa->aad.net.type]);
|
||||||
|
+ } else {
|
||||||
|
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad.net.type);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ audit_log_format(ab, " protocol=%d", sa->aad.net.protocol);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * audit_net - audit network access
|
||||||
|
+ * @profile: profile being enforced (NOT NULL)
|
||||||
|
+ * @op: operation being checked
|
||||||
|
+ * @family: network family
|
||||||
|
+ * @type: network type
|
||||||
|
+ * @protocol: network protocol
|
||||||
|
+ * @sk: socket auditing is being applied to
|
||||||
|
+ * @error: error code for failure else 0
|
||||||
|
+ *
|
||||||
|
+ * Returns: %0 or sa->error else other errorcode on failure
|
||||||
|
+ */
|
||||||
|
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||||
|
+ int protocol, struct sock *sk, int error)
|
||||||
|
+{
|
||||||
|
+ int audit_type = AUDIT_APPARMOR_AUTO;
|
||||||
|
+ struct common_audit_data sa;
|
||||||
|
+ if (sk) {
|
||||||
|
+ COMMON_AUDIT_DATA_INIT(&sa, NET);
|
||||||
|
+ } else {
|
||||||
|
+ COMMON_AUDIT_DATA_INIT(&sa, NONE);
|
||||||
|
+ }
|
||||||
|
+ /* todo fill in socket addr info */
|
||||||
|
+
|
||||||
|
+ sa.aad.op = op,
|
||||||
|
+ sa.u.net.family = family;
|
||||||
|
+ sa.u.net.sk = sk;
|
||||||
|
+ sa.aad.net.type = type;
|
||||||
|
+ sa.aad.net.protocol = protocol;
|
||||||
|
+ sa.aad.error = error;
|
||||||
|
+
|
||||||
|
+ if (likely(!sa.aad.error)) {
|
||||||
|
+ u16 audit_mask = profile->net.audit[sa.u.net.family];
|
||||||
|
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
|
||||||
|
+ !(1 << sa.aad.net.type & audit_mask)))
|
||||||
|
+ return 0;
|
||||||
|
+ audit_type = AUDIT_APPARMOR_AUDIT;
|
||||||
|
+ } else {
|
||||||
|
+ u16 quiet_mask = profile->net.quiet[sa.u.net.family];
|
||||||
|
+ u16 kill_mask = 0;
|
||||||
|
+ u16 denied = (1 << sa.aad.net.type) & ~quiet_mask;
|
||||||
|
+
|
||||||
|
+ if (denied & kill_mask)
|
||||||
|
+ audit_type = AUDIT_APPARMOR_KILL;
|
||||||
|
+
|
||||||
|
+ if ((denied & quiet_mask) &&
|
||||||
|
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
|
||||||
|
+ AUDIT_MODE(profile) != AUDIT_ALL)
|
||||||
|
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad.error;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * aa_net_perm - very course network access check
|
||||||
|
+ * @op: operation being checked
|
||||||
|
+ * @profile: profile being enforced (NOT NULL)
|
||||||
|
+ * @family: network family
|
||||||
|
+ * @type: network type
|
||||||
|
+ * @protocol: network protocol
|
||||||
|
+ *
|
||||||
|
+ * Returns: %0 else error if permission denied
|
||||||
|
+ */
|
||||||
|
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
|
||||||
|
+ int protocol, struct sock *sk)
|
||||||
|
+{
|
||||||
|
+ u16 family_mask;
|
||||||
|
+ int error;
|
||||||
|
+
|
||||||
|
+ if ((family < 0) || (family >= AF_MAX))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ if ((type < 0) || (type >= SOCK_MAX))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* unix domain and netlink sockets are handled by ipc */
|
||||||
|
+ if (family == AF_UNIX || family == AF_NETLINK)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ family_mask = profile->net.allow[family];
|
||||||
|
+
|
||||||
|
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
|
||||||
|
+
|
||||||
|
+ return audit_net(profile, op, family, type, protocol, sk, error);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * aa_revalidate_sk - Revalidate access to a sock
|
||||||
|
+ * @op: operation being checked
|
||||||
|
+ * @sk: sock being revalidated (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: %0 else error if permission denied
|
||||||
|
+ */
|
||||||
|
+int aa_revalidate_sk(int op, struct sock *sk)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile;
|
||||||
|
+ int error = 0;
|
||||||
|
+
|
||||||
|
+ /* aa_revalidate_sk should not be called from interrupt context
|
||||||
|
+ * don't mediate these calls as they are not task related
|
||||||
|
+ */
|
||||||
|
+ if (in_interrupt())
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ profile = __aa_current_profile();
|
||||||
|
+ if (!unconfined(profile))
|
||||||
|
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
|
||||||
|
+ sk->sk_protocol, sk);
|
||||||
|
+
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
|
||||||
|
index 4f0eade..4d5ce13 100644
|
||||||
|
--- a/security/apparmor/policy.c
|
||||||
|
+++ b/security/apparmor/policy.c
|
||||||
|
@@ -745,6 +745,7 @@ static void free_profile(struct aa_profile *profile)
|
||||||
|
|
||||||
|
aa_free_file_rules(&profile->file);
|
||||||
|
aa_free_cap_rules(&profile->caps);
|
||||||
|
+ aa_free_net_rules(&profile->net);
|
||||||
|
aa_free_rlimit_rules(&profile->rlimits);
|
||||||
|
|
||||||
|
aa_free_sid(profile->sid);
|
||||||
|
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
||||||
|
index d6d9a57..f4874c4 100644
|
||||||
|
--- a/security/apparmor/policy_unpack.c
|
||||||
|
+++ b/security/apparmor/policy_unpack.c
|
||||||
|
@@ -190,6 +190,19 @@ fail:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||||
|
+{
|
||||||
|
+ if (unpack_nameX(e, AA_U16, name)) {
|
||||||
|
+ if (!inbounds(e, sizeof(u16)))
|
||||||
|
+ return 0;
|
||||||
|
+ if (data)
|
||||||
|
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||||
|
+ e->pos += sizeof(u16);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||||
|
{
|
||||||
|
if (unpack_nameX(e, AA_U32, name)) {
|
||||||
|
@@ -468,7 +481,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||||
|
{
|
||||||
|
struct aa_profile *profile = NULL;
|
||||||
|
const char *name = NULL;
|
||||||
|
- int error = -EPROTO;
|
||||||
|
+ size_t size = 0;
|
||||||
|
+ int i, error = -EPROTO;
|
||||||
|
kernel_cap_t tmpcap;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
@@ -559,6 +573,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
||||||
|
if (!unpack_rlimits(e, profile))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
+ size = unpack_array(e, "net_allowed_af");
|
||||||
|
+ if (size) {
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < size; i++) {
|
||||||
|
+ /* discard extraneous rules that this kernel will
|
||||||
|
+ * never request
|
||||||
|
+ */
|
||||||
|
+ if (i >= AF_MAX) {
|
||||||
|
+ u16 tmp;
|
||||||
|
+ if (!unpack_u16(e, &tmp, NULL) ||
|
||||||
|
+ !unpack_u16(e, &tmp, NULL) ||
|
||||||
|
+ !unpack_u16(e, &tmp, NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
|
||||||
|
+ goto fail;
|
||||||
|
+ /*
|
||||||
|
+ * allow unix domain and netlink sockets they are handled
|
||||||
|
+ * by IPC
|
||||||
|
+ */
|
||||||
|
+ }
|
||||||
|
+ profile->net.allow[AF_UNIX] = 0xffff;
|
||||||
|
+ profile->net.allow[AF_NETLINK] = 0xffff;
|
||||||
|
+
|
||||||
|
/* get file rules */
|
||||||
|
profile->file.dfa = unpack_dfa(e);
|
||||||
|
if (IS_ERR(profile->file.dfa)) {
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
@ -0,0 +1,99 @@
|
|||||||
|
From 2ddeb856c43f60139fc5c8e2ed9bc350b9bed590 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Arianna Avanzini <avanzini.arianna@gmail.com>
|
||||||
|
Date: Sat, 4 Feb 2012 10:55:51 +0100
|
||||||
|
Subject: [PATCH 1/2] block: cgroups, kconfig, build bits for BFQ-v5-3.3
|
||||||
|
|
||||||
|
Update Kconfig.iosched to include kernel configuration options
|
||||||
|
for BFQ. Add a Kconfig option and do the related Makefile changes
|
||||||
|
to compile the scheduler. Also let the cgroups subsystem know about
|
||||||
|
the BFQ I/O controller.
|
||||||
|
|
||||||
|
Signed-off-by: Fabio Checconi <fabio@gandalf.sssup.it>
|
||||||
|
Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
|
||||||
|
Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
|
||||||
|
---
|
||||||
|
block/Kconfig.iosched | 26 ++++++++++++++++++++++++++
|
||||||
|
block/Makefile | 1 +
|
||||||
|
include/linux/cgroup_subsys.h | 6 ++++++
|
||||||
|
3 files changed, 33 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
|
||||||
|
index 3199b76..5905452 100644
|
||||||
|
--- a/block/Kconfig.iosched
|
||||||
|
+++ b/block/Kconfig.iosched
|
||||||
|
@@ -43,6 +43,28 @@ config CFQ_GROUP_IOSCHED
|
||||||
|
---help---
|
||||||
|
Enable group IO scheduling in CFQ.
|
||||||
|
|
||||||
|
+config IOSCHED_BFQ
|
||||||
|
+ tristate "BFQ I/O scheduler"
|
||||||
|
+ depends on EXPERIMENTAL
|
||||||
|
+ default n
|
||||||
|
+ ---help---
|
||||||
|
+ The BFQ I/O scheduler tries to distribute bandwidth among
|
||||||
|
+ all processes according to their weights.
|
||||||
|
+ It aims at distributing the bandwidth as desired, independently of
|
||||||
|
+ the disk parameters and with any workload. It also tries to
|
||||||
|
+ guarantee low latency to interactive and soft real-time
|
||||||
|
+ applications. If compiled built-in (saying Y here), BFQ can
|
||||||
|
+ be configured to support hierarchical scheduling.
|
||||||
|
+
|
||||||
|
+config CGROUP_BFQIO
|
||||||
|
+ bool "BFQ hierarchical scheduling support"
|
||||||
|
+ depends on CGROUPS && IOSCHED_BFQ=y
|
||||||
|
+ default n
|
||||||
|
+ ---help---
|
||||||
|
+ Enable hierarchical scheduling in BFQ, using the cgroups
|
||||||
|
+ filesystem interface. The name of the subsystem will be
|
||||||
|
+ bfqio.
|
||||||
|
+
|
||||||
|
choice
|
||||||
|
prompt "Default I/O scheduler"
|
||||||
|
default DEFAULT_CFQ
|
||||||
|
@@ -56,6 +78,9 @@ choice
|
||||||
|
config DEFAULT_CFQ
|
||||||
|
bool "CFQ" if IOSCHED_CFQ=y
|
||||||
|
|
||||||
|
+ config DEFAULT_BFQ
|
||||||
|
+ bool "BFQ" if IOSCHED_BFQ=y
|
||||||
|
+
|
||||||
|
config DEFAULT_NOOP
|
||||||
|
bool "No-op"
|
||||||
|
|
||||||
|
@@ -65,6 +90,7 @@ config DEFAULT_IOSCHED
|
||||||
|
string
|
||||||
|
default "deadline" if DEFAULT_DEADLINE
|
||||||
|
default "cfq" if DEFAULT_CFQ
|
||||||
|
+ default "bfq" if DEFAULT_BFQ
|
||||||
|
default "noop" if DEFAULT_NOOP
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
diff --git a/block/Makefile b/block/Makefile
|
||||||
|
index 39b76ba..c0d20fa 100644
|
||||||
|
--- a/block/Makefile
|
||||||
|
+++ b/block/Makefile
|
||||||
|
@@ -15,6 +15,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o
|
||||||
|
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
|
||||||
|
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
|
||||||
|
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
|
||||||
|
+obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
|
||||||
|
obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
|
||||||
|
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
|
||||||
|
index 0bd390c..cbf22b1 100644
|
||||||
|
--- a/include/linux/cgroup_subsys.h
|
||||||
|
+++ b/include/linux/cgroup_subsys.h
|
||||||
|
@@ -72,3 +72,9 @@ SUBSYS(net_prio)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_CGROUP_BFQIO
|
||||||
|
+SUBSYS(bfqio)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* */
|
||||||
|
--
|
||||||
|
1.7.10.4
|
||||||
|
|
391
3.3.8/0002-AppArmor-compatibility-patch-for-v5-interface.patch
Normal file
391
3.3.8/0002-AppArmor-compatibility-patch-for-v5-interface.patch
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
From a2515f25ad5a7833ddc5a032d34eee6a5ddee3a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
|
Date: Wed, 10 Aug 2011 22:02:40 -0700
|
||||||
|
Subject: [PATCH 2/3] AppArmor: compatibility patch for v5 interface
|
||||||
|
|
||||||
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
---
|
||||||
|
security/apparmor/Kconfig | 9 +
|
||||||
|
security/apparmor/Makefile | 1 +
|
||||||
|
security/apparmor/apparmorfs-24.c | 287 ++++++++++++++++++++++++++++++++
|
||||||
|
security/apparmor/apparmorfs.c | 18 ++-
|
||||||
|
security/apparmor/include/apparmorfs.h | 6 +
|
||||||
|
5 files changed, 319 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 security/apparmor/apparmorfs-24.c
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
|
||||||
|
index 9b9013b..51ebf96 100644
|
||||||
|
--- a/security/apparmor/Kconfig
|
||||||
|
+++ b/security/apparmor/Kconfig
|
||||||
|
@@ -29,3 +29,12 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
|
||||||
|
boot.
|
||||||
|
|
||||||
|
If you are unsure how to answer this question, answer 1.
|
||||||
|
+
|
||||||
|
+config SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ bool "Enable AppArmor 2.4 compatability"
|
||||||
|
+ depends on SECURITY_APPARMOR
|
||||||
|
+ default y
|
||||||
|
+ help
|
||||||
|
+ This option enables compatability with AppArmor 2.4. It is
|
||||||
|
+ recommended if compatability with older versions of AppArmor
|
||||||
|
+ is desired.
|
||||||
|
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
|
||||||
|
index 7cefef9..0bb604b 100644
|
||||||
|
--- a/security/apparmor/Makefile
|
||||||
|
+++ b/security/apparmor/Makefile
|
||||||
|
@@ -5,6 +5,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
|
||||||
|
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||||
|
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||||
|
resource.o sid.o file.o net.o
|
||||||
|
+apparmor-$(CONFIG_SECURITY_APPARMOR_COMPAT_24) += apparmorfs-24.o
|
||||||
|
|
||||||
|
clean-files := capability_names.h rlim_names.h af_names.h
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/apparmorfs-24.c b/security/apparmor/apparmorfs-24.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..dc8c744
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/security/apparmor/apparmorfs-24.c
|
||||||
|
@@ -0,0 +1,287 @@
|
||||||
|
+/*
|
||||||
|
+ * AppArmor security module
|
||||||
|
+ *
|
||||||
|
+ * This file contains AppArmor /sys/kernel/secrutiy/apparmor interface functions
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||||
|
+ * Copyright 2009-2010 Canonical Ltd.
|
||||||
|
+ *
|
||||||
|
+ * 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, version 2 of the
|
||||||
|
+ * License.
|
||||||
|
+ *
|
||||||
|
+ *
|
||||||
|
+ * This file contain functions providing an interface for <= AppArmor 2.4
|
||||||
|
+ * compatibility. It is dependent on CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ * being set (see Makefile).
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/security.h>
|
||||||
|
+#include <linux/vmalloc.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/seq_file.h>
|
||||||
|
+#include <linux/uaccess.h>
|
||||||
|
+#include <linux/namei.h>
|
||||||
|
+
|
||||||
|
+#include "include/apparmor.h"
|
||||||
|
+#include "include/audit.h"
|
||||||
|
+#include "include/context.h"
|
||||||
|
+#include "include/policy.h"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* apparmor/matching */
|
||||||
|
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
|
||||||
|
+ size_t size, loff_t *ppos)
|
||||||
|
+{
|
||||||
|
+ const char matching[] = "pattern=aadfa audit perms=crwxamlk/ "
|
||||||
|
+ "user::other";
|
||||||
|
+
|
||||||
|
+ return simple_read_from_buffer(buf, size, ppos, matching,
|
||||||
|
+ sizeof(matching) - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct file_operations aa_fs_matching_fops = {
|
||||||
|
+ .read = aa_matching_read,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* apparmor/features */
|
||||||
|
+static ssize_t aa_features_read(struct file *file, char __user *buf,
|
||||||
|
+ size_t size, loff_t *ppos)
|
||||||
|
+{
|
||||||
|
+ const char features[] = "file=3.1 capability=2.0 network=1.0 "
|
||||||
|
+ "change_hat=1.5 change_profile=1.1 " "aanamespaces=1.1 rlimit=1.1";
|
||||||
|
+
|
||||||
|
+ return simple_read_from_buffer(buf, size, ppos, features,
|
||||||
|
+ sizeof(features) - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct file_operations aa_fs_features_fops = {
|
||||||
|
+ .read = aa_features_read,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * __next_namespace - find the next namespace to list
|
||||||
|
+ * @root: root namespace to stop search at (NOT NULL)
|
||||||
|
+ * @ns: current ns position (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Find the next namespace from @ns under @root and handle all locking needed
|
||||||
|
+ * while switching current namespace.
|
||||||
|
+ *
|
||||||
|
+ * Returns: next namespace or NULL if at last namespace under @root
|
||||||
|
+ * NOTE: will not unlock root->lock
|
||||||
|
+ */
|
||||||
|
+static struct aa_namespace *__next_namespace(struct aa_namespace *root,
|
||||||
|
+ struct aa_namespace *ns)
|
||||||
|
+{
|
||||||
|
+ struct aa_namespace *parent;
|
||||||
|
+
|
||||||
|
+ /* is next namespace a child */
|
||||||
|
+ if (!list_empty(&ns->sub_ns)) {
|
||||||
|
+ struct aa_namespace *next;
|
||||||
|
+ next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
|
||||||
|
+ read_lock(&next->lock);
|
||||||
|
+ return next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check if the next ns is a sibling, parent, gp, .. */
|
||||||
|
+ parent = ns->parent;
|
||||||
|
+ while (parent) {
|
||||||
|
+ read_unlock(&ns->lock);
|
||||||
|
+ list_for_each_entry_continue(ns, &parent->sub_ns, base.list) {
|
||||||
|
+ read_lock(&ns->lock);
|
||||||
|
+ return ns;
|
||||||
|
+ }
|
||||||
|
+ if (parent == root)
|
||||||
|
+ return NULL;
|
||||||
|
+ ns = parent;
|
||||||
|
+ parent = parent->parent;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * __first_profile - find the first profile in a namespace
|
||||||
|
+ * @root: namespace that is root of profiles being displayed (NOT NULL)
|
||||||
|
+ * @ns: namespace to start in (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: unrefcounted profile or NULL if no profile
|
||||||
|
+ */
|
||||||
|
+static struct aa_profile *__first_profile(struct aa_namespace *root,
|
||||||
|
+ struct aa_namespace *ns)
|
||||||
|
+{
|
||||||
|
+ for ( ; ns; ns = __next_namespace(root, ns)) {
|
||||||
|
+ if (!list_empty(&ns->base.profiles))
|
||||||
|
+ return list_first_entry(&ns->base.profiles,
|
||||||
|
+ struct aa_profile, base.list);
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * __next_profile - step to the next profile in a profile tree
|
||||||
|
+ * @profile: current profile in tree (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Perform a depth first taversal on the profile tree in a namespace
|
||||||
|
+ *
|
||||||
|
+ * Returns: next profile or NULL if done
|
||||||
|
+ * Requires: profile->ns.lock to be held
|
||||||
|
+ */
|
||||||
|
+static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *parent;
|
||||||
|
+ struct aa_namespace *ns = p->ns;
|
||||||
|
+
|
||||||
|
+ /* is next profile a child */
|
||||||
|
+ if (!list_empty(&p->base.profiles))
|
||||||
|
+ return list_first_entry(&p->base.profiles, typeof(*p),
|
||||||
|
+ base.list);
|
||||||
|
+
|
||||||
|
+ /* is next profile a sibling, parent sibling, gp, subling, .. */
|
||||||
|
+ parent = p->parent;
|
||||||
|
+ while (parent) {
|
||||||
|
+ list_for_each_entry_continue(p, &parent->base.profiles,
|
||||||
|
+ base.list)
|
||||||
|
+ return p;
|
||||||
|
+ p = parent;
|
||||||
|
+ parent = parent->parent;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* is next another profile in the namespace */
|
||||||
|
+ list_for_each_entry_continue(p, &ns->base.profiles, base.list)
|
||||||
|
+ return p;
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * next_profile - step to the next profile in where ever it may be
|
||||||
|
+ * @root: root namespace (NOT NULL)
|
||||||
|
+ * @profile: current profile (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: next profile or NULL if there isn't one
|
||||||
|
+ */
|
||||||
|
+static struct aa_profile *next_profile(struct aa_namespace *root,
|
||||||
|
+ struct aa_profile *profile)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *next = __next_profile(profile);
|
||||||
|
+ if (next)
|
||||||
|
+ return next;
|
||||||
|
+
|
||||||
|
+ /* finished all profiles in namespace move to next namespace */
|
||||||
|
+ return __first_profile(root, __next_namespace(root, profile->ns));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * p_start - start a depth first traversal of profile tree
|
||||||
|
+ * @f: seq_file to fill
|
||||||
|
+ * @pos: current position
|
||||||
|
+ *
|
||||||
|
+ * Returns: first profile under current namespace or NULL if none found
|
||||||
|
+ *
|
||||||
|
+ * acquires first ns->lock
|
||||||
|
+ */
|
||||||
|
+static void *p_start(struct seq_file *f, loff_t *pos)
|
||||||
|
+ __acquires(root->lock)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = NULL;
|
||||||
|
+ struct aa_namespace *root = aa_current_profile()->ns;
|
||||||
|
+ loff_t l = *pos;
|
||||||
|
+ f->private = aa_get_namespace(root);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /* find the first profile */
|
||||||
|
+ read_lock(&root->lock);
|
||||||
|
+ profile = __first_profile(root, root);
|
||||||
|
+
|
||||||
|
+ /* skip to position */
|
||||||
|
+ for (; profile && l > 0; l--)
|
||||||
|
+ profile = next_profile(root, profile);
|
||||||
|
+
|
||||||
|
+ return profile;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * p_next - read the next profile entry
|
||||||
|
+ * @f: seq_file to fill
|
||||||
|
+ * @p: profile previously returned
|
||||||
|
+ * @pos: current position
|
||||||
|
+ *
|
||||||
|
+ * Returns: next profile after @p or NULL if none
|
||||||
|
+ *
|
||||||
|
+ * may acquire/release locks in namespace tree as necessary
|
||||||
|
+ */
|
||||||
|
+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = p;
|
||||||
|
+ struct aa_namespace *root = f->private;
|
||||||
|
+ (*pos)++;
|
||||||
|
+
|
||||||
|
+ return next_profile(root, profile);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * p_stop - stop depth first traversal
|
||||||
|
+ * @f: seq_file we are filling
|
||||||
|
+ * @p: the last profile writen
|
||||||
|
+ *
|
||||||
|
+ * Release all locking done by p_start/p_next on namespace tree
|
||||||
|
+ */
|
||||||
|
+static void p_stop(struct seq_file *f, void *p)
|
||||||
|
+ __releases(root->lock)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = p;
|
||||||
|
+ struct aa_namespace *root = f->private, *ns;
|
||||||
|
+
|
||||||
|
+ if (profile) {
|
||||||
|
+ for (ns = profile->ns; ns && ns != root; ns = ns->parent)
|
||||||
|
+ read_unlock(&ns->lock);
|
||||||
|
+ }
|
||||||
|
+ read_unlock(&root->lock);
|
||||||
|
+ aa_put_namespace(root);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * seq_show_profile - show a profile entry
|
||||||
|
+ * @f: seq_file to file
|
||||||
|
+ * @p: current position (profile) (NOT NULL)
|
||||||
|
+ *
|
||||||
|
+ * Returns: error on failure
|
||||||
|
+ */
|
||||||
|
+static int seq_show_profile(struct seq_file *f, void *p)
|
||||||
|
+{
|
||||||
|
+ struct aa_profile *profile = (struct aa_profile *)p;
|
||||||
|
+ struct aa_namespace *root = f->private;
|
||||||
|
+
|
||||||
|
+ if (profile->ns != root)
|
||||||
|
+ seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
|
||||||
|
+ seq_printf(f, "%s (%s)\n", profile->base.hname,
|
||||||
|
+ COMPLAIN_MODE(profile) ? "complain" : "enforce");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct seq_operations aa_fs_profiles_op = {
|
||||||
|
+ .start = p_start,
|
||||||
|
+ .next = p_next,
|
||||||
|
+ .stop = p_stop,
|
||||||
|
+ .show = seq_show_profile,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int profiles_open(struct inode *inode, struct file *file)
|
||||||
|
+{
|
||||||
|
+ return seq_open(file, &aa_fs_profiles_op);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int profiles_release(struct inode *inode, struct file *file)
|
||||||
|
+{
|
||||||
|
+ return seq_release(inode, file);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct file_operations aa_fs_profiles_fops = {
|
||||||
|
+ .open = profiles_open,
|
||||||
|
+ .read = seq_read,
|
||||||
|
+ .llseek = seq_lseek,
|
||||||
|
+ .release = profiles_release,
|
||||||
|
+};
|
||||||
|
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
|
||||||
|
index 0848292..28c52ac 100644
|
||||||
|
--- a/security/apparmor/apparmorfs.c
|
||||||
|
+++ b/security/apparmor/apparmorfs.c
|
||||||
|
@@ -187,7 +187,11 @@ void __init aa_destroy_aafs(void)
|
||||||
|
aafs_remove(".remove");
|
||||||
|
aafs_remove(".replace");
|
||||||
|
aafs_remove(".load");
|
||||||
|
-
|
||||||
|
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ aafs_remove("profiles");
|
||||||
|
+ aafs_remove("matching");
|
||||||
|
+ aafs_remove("features");
|
||||||
|
+#endif
|
||||||
|
securityfs_remove(aa_fs_dentry);
|
||||||
|
aa_fs_dentry = NULL;
|
||||||
|
}
|
||||||
|
@@ -218,7 +222,17 @@ int __init aa_create_aafs(void)
|
||||||
|
aa_fs_dentry = NULL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+ error = aafs_create("matching", 0444, &aa_fs_matching_fops);
|
||||||
|
+ if (error)
|
||||||
|
+ goto error;
|
||||||
|
+ error = aafs_create("features", 0444, &aa_fs_features_fops);
|
||||||
|
+ if (error)
|
||||||
|
+ goto error;
|
||||||
|
+#endif
|
||||||
|
+ error = aafs_create("profiles", 0440, &aa_fs_profiles_fops);
|
||||||
|
+ if (error)
|
||||||
|
+ goto error;
|
||||||
|
error = aafs_create(".load", 0640, &aa_fs_profile_load);
|
||||||
|
if (error)
|
||||||
|
goto error;
|
||||||
|
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
|
||||||
|
index cb1e93a..14f955c 100644
|
||||||
|
--- a/security/apparmor/include/apparmorfs.h
|
||||||
|
+++ b/security/apparmor/include/apparmorfs.h
|
||||||
|
@@ -17,4 +17,10 @@
|
||||||
|
|
||||||
|
extern void __init aa_destroy_aafs(void);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||||
|
+extern const struct file_operations aa_fs_matching_fops;
|
||||||
|
+extern const struct file_operations aa_fs_features_fops;
|
||||||
|
+extern const struct file_operations aa_fs_profiles_fops;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#endif /* __AA_APPARMORFS_H */
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
5624
3.3.8/0002-block-introduce-the-BFQ-v5-I-O-sched-for-3.3.patch
Normal file
5624
3.3.8/0002-block-introduce-the-BFQ-v5-I-O-sched-for-3.3.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,69 @@
|
|||||||
|
From 7a10d093f9779f42cb8d6affcb6a4436d3ebd6d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Johansen <john.johansen@canonical.com>
|
||||||
|
Date: Wed, 10 Aug 2011 22:02:41 -0700
|
||||||
|
Subject: [PATCH 3/3] AppArmor: Allow dfa backward compatibility with broken
|
||||||
|
userspace
|
||||||
|
|
||||||
|
The apparmor_parser when compiling policy could generate invalid dfas
|
||||||
|
that did not have sufficient padding to avoid invalid references, when
|
||||||
|
used by the kernel. The kernels check to verify the next/check table
|
||||||
|
size was broken meaning invalid dfas were being created by userspace
|
||||||
|
and not caught.
|
||||||
|
|
||||||
|
To remain compatible with old tools that are not fixed, pad the loaded
|
||||||
|
dfas next/check table. The dfa's themselves are valid except for the
|
||||||
|
high padding for potentially invalid transitions (high bounds error),
|
||||||
|
which have a maximimum is 256 entries. So just allocate an extra null filled
|
||||||
|
256 entries for the next/check tables. This will guarentee all bounds
|
||||||
|
are good and invalid transitions go to the null (0) state.
|
||||||
|
|
||||||
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||||
|
---
|
||||||
|
security/apparmor/match.c | 17 +++++++++++++++++
|
||||||
|
1 files changed, 17 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
|
||||||
|
index 94de6b4..081491e 100644
|
||||||
|
--- a/security/apparmor/match.c
|
||||||
|
+++ b/security/apparmor/match.c
|
||||||
|
@@ -57,8 +57,17 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
|
||||||
|
if (bsize < tsize)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
+ /* Pad table allocation for next/check by 256 entries to remain
|
||||||
|
+ * backwards compatible with old (buggy) tools and remain safe without
|
||||||
|
+ * run time checks
|
||||||
|
+ */
|
||||||
|
+ if (th.td_id == YYTD_ID_NXT || th.td_id == YYTD_ID_CHK)
|
||||||
|
+ tsize += 256 * th.td_flags;
|
||||||
|
+
|
||||||
|
table = kvmalloc(tsize);
|
||||||
|
if (table) {
|
||||||
|
+ /* ensure the pad is clear, else there will be errors */
|
||||||
|
+ memset(table, 0, tsize);
|
||||||
|
*table = th;
|
||||||
|
if (th.td_flags == YYTD_DATA8)
|
||||||
|
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
|
||||||
|
@@ -134,11 +143,19 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (flags & DFA_FLAG_VERIFY_STATES) {
|
||||||
|
+ int warning = 0;
|
||||||
|
for (i = 0; i < state_count; i++) {
|
||||||
|
if (DEFAULT_TABLE(dfa)[i] >= state_count)
|
||||||
|
goto out;
|
||||||
|
/* TODO: do check that DEF state recursion terminates */
|
||||||
|
if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
|
||||||
|
+ if (warning)
|
||||||
|
+ continue;
|
||||||
|
+ printk(KERN_WARNING "AppArmor DFA next/check "
|
||||||
|
+ "upper bounds error fixed, upgrade "
|
||||||
|
+ "user space tools \n");
|
||||||
|
+ warning = 1;
|
||||||
|
+ } else if (BASE_TABLE(dfa)[i] >= trans_count) {
|
||||||
|
printk(KERN_ERR "AppArmor DFA next/check upper "
|
||||||
|
"bounds error\n");
|
||||||
|
goto out;
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
174
3.3.8/01patch-2.6.33_atopcnt.patch
Normal file
174
3.3.8/01patch-2.6.33_atopcnt.patch
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
diff --git a/block/blk-core.c b/block/blk-core.c
|
||||||
|
index d1a9a0a..8b54acb 100644
|
||||||
|
--- a/block/blk-core.c
|
||||||
|
+++ b/block/blk-core.c
|
||||||
|
@@ -73,6 +73,17 @@ static void drive_stat_acct(struct request *rq, int new_io)
|
||||||
|
part_inc_in_flight(part, rw);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ switch (rw) { /* ATOP */
|
||||||
|
+ case READ: /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_rio += new_io; /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_rsz += blk_rq_sectors(rq); /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case WRITE: /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_wio += new_io; /* ATOP */
|
||||||
|
+ current->group_leader->stat.dsk_wsz += blk_rq_sectors(rq); /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+
|
||||||
|
part_stat_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/fs/proc/array.c b/fs/proc/array.c
|
||||||
|
index 13b5d07..cac522e 100644
|
||||||
|
--- a/fs/proc/array.c
|
||||||
|
+++ b/fs/proc/array.c
|
||||||
|
@@ -515,6 +515,25 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
|
||||||
|
(unsigned long long)delayacct_blkio_ticks(task),
|
||||||
|
cputime_to_clock_t(gtime),
|
||||||
|
cputime_to_clock_t(cgtime));
|
||||||
|
+
|
||||||
|
+ seq_printf(m, /* ATOP */
|
||||||
|
+ "%lu %llu %lu %llu %lu %llu %lu " /* ATOP */
|
||||||
|
+ "%llu %lu %llu %lu %llu %lu %lu\n", /* ATOP */
|
||||||
|
+ task->stat.dsk_rio, /* ATOP */
|
||||||
|
+ task->stat.dsk_rsz, /* ATOP */
|
||||||
|
+ task->stat.dsk_wio, /* ATOP */
|
||||||
|
+ task->stat.dsk_wsz, /* ATOP */
|
||||||
|
+ task->stat.tcp_snd, /* ATOP */
|
||||||
|
+ task->stat.tcp_ssz, /* ATOP */
|
||||||
|
+ task->stat.tcp_rcv, /* ATOP */
|
||||||
|
+ task->stat.tcp_rsz, /* ATOP */
|
||||||
|
+ task->stat.udp_snd, /* ATOP */
|
||||||
|
+ task->stat.udp_ssz, /* ATOP */
|
||||||
|
+ task->stat.udp_rcv, /* ATOP */
|
||||||
|
+ task->stat.udp_rsz, /* ATOP */
|
||||||
|
+ task->stat.raw_snd, /* ATOP */
|
||||||
|
+ task->stat.raw_rcv); /* ATOP */
|
||||||
|
+
|
||||||
|
if (mm)
|
||||||
|
mmput(mm);
|
||||||
|
return 0;
|
||||||
|
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||||
|
index 78efe7c..22391bf 100644
|
||||||
|
--- a/include/linux/sched.h
|
||||||
|
+++ b/include/linux/sched.h
|
||||||
|
@@ -1512,6 +1512,17 @@ struct task_struct {
|
||||||
|
#endif
|
||||||
|
atomic_t fs_excl; /* holding fs exclusive resources */
|
||||||
|
struct rcu_head rcu;
|
||||||
|
+
|
||||||
|
+ struct { /* ATOP */
|
||||||
|
+ unsigned long dsk_rio, dsk_wio; /* ATOP */
|
||||||
|
+ unsigned long long dsk_rsz, dsk_wsz; /* ATOP */
|
||||||
|
+ unsigned long tcp_snd, tcp_rcv; /* ATOP */
|
||||||
|
+ unsigned long long tcp_ssz, tcp_rsz; /* ATOP */
|
||||||
|
+ unsigned long udp_snd, udp_rcv; /* ATOP */
|
||||||
|
+ unsigned long long udp_ssz, udp_rsz; /* ATOP */
|
||||||
|
+ unsigned long raw_snd, raw_rcv; /* ATOP */
|
||||||
|
+ } stat; /* ATOP */
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cache last used pipe for splice
|
||||||
|
diff --git a/kernel/acct.c b/kernel/acct.c
|
||||||
|
index a6605ca..d5df53a 100644
|
||||||
|
--- a/kernel/acct.c
|
||||||
|
+++ b/kernel/acct.c
|
||||||
|
@@ -565,7 +565,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
|
||||||
|
ac.ac_exitcode = pacct->ac_exitcode;
|
||||||
|
spin_unlock_irq(¤t->sighand->siglock);
|
||||||
|
ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
|
||||||
|
- ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
|
||||||
|
+ ac.ac_rw = encode_comp_t(current->stat.dsk_rio + current->stat.dsk_wio); /* ATOP */
|
||||||
|
ac.ac_swaps = encode_comp_t(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||||
|
index f88bd98..bab2085 100644
|
||||||
|
--- a/kernel/fork.c
|
||||||
|
+++ b/kernel/fork.c
|
||||||
|
@@ -683,6 +683,14 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
|
||||||
|
|
||||||
|
tsk->min_flt = tsk->maj_flt = 0;
|
||||||
|
tsk->nvcsw = tsk->nivcsw = 0;
|
||||||
|
+ tsk->stat.dsk_rio = tsk->stat.dsk_wio = 0; /* ATOP */
|
||||||
|
+ tsk->stat.dsk_rsz = tsk->stat.dsk_wsz = 0; /* ATOP */
|
||||||
|
+ tsk->stat.tcp_snd = tsk->stat.tcp_rcv = 0; /* ATOP */
|
||||||
|
+ tsk->stat.tcp_ssz = tsk->stat.tcp_rsz = 0; /* ATOP */
|
||||||
|
+ tsk->stat.udp_snd = tsk->stat.udp_rcv = 0; /* ATOP */
|
||||||
|
+ tsk->stat.udp_ssz = tsk->stat.udp_rsz = 0; /* ATOP */
|
||||||
|
+ tsk->stat.raw_snd = tsk->stat.raw_rcv = 0; /* ATOP */
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_DETECT_HUNG_TASK
|
||||||
|
tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
|
||||||
|
#endif
|
||||||
|
diff --git a/net/socket.c b/net/socket.c
|
||||||
|
index 769c386..3ba19f6 100644
|
||||||
|
--- a/net/socket.c
|
||||||
|
+++ b/net/socket.c
|
||||||
|
@@ -547,10 +547,28 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
|
si->size = size;
|
||||||
|
|
||||||
|
err = security_socket_sendmsg(sock, msg, size);
|
||||||
|
- if (err)
|
||||||
|
- return err;
|
||||||
|
-
|
||||||
|
- return sock->ops->sendmsg(iocb, sock, msg, size);
|
||||||
|
+ if (!err)
|
||||||
|
+ err = sock->ops->sendmsg(iocb, sock, msg, size);
|
||||||
|
+
|
||||||
|
+ if (err >= 0 && sock->sk) { /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_family) { /* ATOP */
|
||||||
|
+ case PF_INET: /* ATOP */
|
||||||
|
+ case PF_INET6: /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_type) { /* ATOP */
|
||||||
|
+ case SOCK_STREAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_snd++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_ssz+=size;/* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_DGRAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_snd++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_ssz+=size;/* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_RAW: /* ATOP */
|
||||||
|
+ current->group_leader->stat.raw_snd++; /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
|
||||||
|
@@ -682,7 +700,29 @@ static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||||
|
{
|
||||||
|
int err = security_socket_recvmsg(sock, msg, size, flags);
|
||||||
|
|
||||||
|
- return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
|
||||||
|
+ if (!err)
|
||||||
|
+ err = __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
|
||||||
|
+
|
||||||
|
+ if (err >= 0 && sock->sk) { /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_family) { /* ATOP */
|
||||||
|
+ case PF_INET: /* ATOP */
|
||||||
|
+ case PF_INET6: /* ATOP */
|
||||||
|
+ switch (sock->sk->sk_type) { /* ATOP */
|
||||||
|
+ case SOCK_STREAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_rcv++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.tcp_rsz+=err; /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_DGRAM: /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_rcv++; /* ATOP */
|
||||||
|
+ current->group_leader->stat.udp_rsz+=err; /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ case SOCK_RAW: /* ATOP */
|
||||||
|
+ current->group_leader->stat.raw_rcv++; /* ATOP */
|
||||||
|
+ break; /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ } /* ATOP */
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
125
3.3.8/02patch-2.6.33_atopacct.patch
Normal file
125
3.3.8/02patch-2.6.33_atopacct.patch
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
Index: linux-2.6.28/include/linux/acct.h
|
||||||
|
===================================================================
|
||||||
|
--- linux-2.6.28.orig/include/linux/acct.h 2009-01-14 13:02:24.000000000 +0100
|
||||||
|
+++ linux-2.6.28/include/linux/acct.h 2009-01-14 13:03:33.000000000 +0100
|
||||||
|
@@ -97,6 +97,54 @@
|
||||||
|
char ac_comm[ACCT_COMM]; /* Command Name */
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct acct_atop
|
||||||
|
+{
|
||||||
|
+ char ac_flag; /* Flags */
|
||||||
|
+ char ac_version; /* Always set to ACCT_VERSION */
|
||||||
|
+ __u32 ac_pid; /* Process ID */
|
||||||
|
+ __u32 ac_ppid; /* Parent Process ID */
|
||||||
|
+ __u16 ac_uid16; /* LSB of Real User ID */
|
||||||
|
+ __u16 ac_gid16; /* LSB of Real Group ID */
|
||||||
|
+ __u16 ac_tty; /* Control Terminal */
|
||||||
|
+ __u32 ac_btime; /* Process Creation Time */
|
||||||
|
+ comp_t ac_utime; /* User Time */
|
||||||
|
+ comp_t ac_stime; /* System Time */
|
||||||
|
+ comp_t ac_etime; /* Elapsed Time */
|
||||||
|
+ comp_t ac_mem; /* Virtual Memory */
|
||||||
|
+ comp_t ac_rss; /* Resident Memory */
|
||||||
|
+ comp_t ac_io; /* Chars Transferred */
|
||||||
|
+ comp_t ac_rw; /* Blocks Read or Written */
|
||||||
|
+ comp_t ac_bread; /* Blocks Read */
|
||||||
|
+ comp_t ac_bwrite; /* Blocks Written */
|
||||||
|
+ comp2_t ac_dskrsz; /* Cum. blocks read */
|
||||||
|
+ comp2_t ac_dskwsz; /* Cum. blocks written */
|
||||||
|
+ comp_t ac_tcpsnd; /* TCP send requests */
|
||||||
|
+ comp_t ac_tcprcv; /* TCP recv requests */
|
||||||
|
+ comp2_t ac_tcpssz; /* TCP cum. length */
|
||||||
|
+ comp2_t ac_tcprsz; /* TCP cum. length */
|
||||||
|
+ comp_t ac_udpsnd; /* UDP send requests */
|
||||||
|
+ comp_t ac_udprcv; /* UDP recv requests */
|
||||||
|
+ comp2_t ac_udpssz; /* UDP cum. length */
|
||||||
|
+ comp2_t ac_udprsz; /* UDP cum. length */
|
||||||
|
+ comp_t ac_rawsnd; /* RAW send requests */
|
||||||
|
+ comp_t ac_rawrcv; /* RAW recv requests */
|
||||||
|
+ comp_t ac_minflt; /* Minor Pagefaults */
|
||||||
|
+ comp_t ac_majflt; /* Major Pagefaults */
|
||||||
|
+ comp_t ac_swaps; /* Number of Swaps */
|
||||||
|
+/* m68k had no padding here. */
|
||||||
|
+#if !defined(CONFIG_M68K) || !defined(__KERNEL__)
|
||||||
|
+ __u16 ac_ahz; /* AHZ */
|
||||||
|
+#endif
|
||||||
|
+ __u32 ac_exitcode; /* Exitcode */
|
||||||
|
+ char ac_comm[ACCT_COMM + 1]; /* Command Name */
|
||||||
|
+ __u8 ac_etime_hi; /* Elapsed Time MSB */
|
||||||
|
+ __u16 ac_etime_lo; /* Elapsed Time LSB */
|
||||||
|
+ __u32 ac_uid; /* Real User ID */
|
||||||
|
+ __u32 ac_gid; /* Real Group ID */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* accounting flags
|
||||||
|
*/
|
||||||
|
@@ -146,7 +194,13 @@
|
||||||
|
* 5: new binary incompatible format (128 bytes, second half)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
+#define CONFIG_PROCESS_ACCT_ATOP
|
||||||
|
|
||||||
|
+#ifdef CONFIG_PROCESS_ACCT_ATOP
|
||||||
|
+#define ACCT_VERSION 6
|
||||||
|
+#define AHZ (USER_HZ)
|
||||||
|
+typedef struct acct_atop acct_t;
|
||||||
|
+#else
|
||||||
|
#ifdef CONFIG_BSD_PROCESS_ACCT_V3
|
||||||
|
#define ACCT_VERSION 3
|
||||||
|
#define AHZ 100
|
||||||
|
@@ -160,6 +214,7 @@
|
||||||
|
#define AHZ (USER_HZ)
|
||||||
|
typedef struct acct acct_t;
|
||||||
|
#endif
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define ACCT_VERSION 2
|
||||||
|
Index: linux-2.6.28/kernel/acct.c
|
||||||
|
===================================================================
|
||||||
|
--- linux-2.6.28.orig/kernel/acct.c 2009-01-14 13:03:31.000000000 +0100
|
||||||
|
+++ linux-2.6.28/kernel/acct.c 2009-01-14 13:03:33.000000000 +0100
|
||||||
|
@@ -405,7 +405,7 @@
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if ACCT_VERSION==1 || ACCT_VERSION==2
|
||||||
|
+#if ACCT_VERSION==1 || ACCT_VERSION==2 || ACCT_VERSION==6
|
||||||
|
/*
|
||||||
|
* encode an u64 into a comp2_t (24 bits)
|
||||||
|
*
|
||||||
|
@@ -552,6 +552,30 @@
|
||||||
|
ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns);
|
||||||
|
rcu_read_unlock();
|
||||||
|
#endif
|
||||||
|
+#if ACCT_VERSION==6 /* ATOP */
|
||||||
|
+ ac.ac_pid = current->pid;
|
||||||
|
+ ac.ac_ppid = current->parent->pid;
|
||||||
|
+ ac.ac_uid16 = ac.ac_uid;
|
||||||
|
+ ac.ac_gid16 = ac.ac_gid;
|
||||||
|
+ ac.ac_ahz = AHZ;
|
||||||
|
+ ac.ac_bread = encode_comp_t(current->stat.dsk_rio);
|
||||||
|
+ ac.ac_bwrite = encode_comp_t(current->stat.dsk_wio);
|
||||||
|
+ ac.ac_dskrsz = encode_comp2_t(current->stat.dsk_rsz);
|
||||||
|
+ ac.ac_dskwsz = encode_comp2_t(current->stat.dsk_wsz);
|
||||||
|
+ ac.ac_tcpsnd = encode_comp_t(current->stat.tcp_snd);
|
||||||
|
+ ac.ac_tcprcv = encode_comp_t(current->stat.tcp_rcv);
|
||||||
|
+ ac.ac_tcpssz = encode_comp2_t(current->stat.tcp_ssz);
|
||||||
|
+ ac.ac_tcprsz = encode_comp2_t(current->stat.tcp_rsz);
|
||||||
|
+ ac.ac_udpsnd = encode_comp_t(current->stat.udp_snd);
|
||||||
|
+ ac.ac_udprcv = encode_comp_t(current->stat.udp_rcv);
|
||||||
|
+ ac.ac_udpssz = encode_comp2_t(current->stat.udp_ssz);
|
||||||
|
+ ac.ac_udprsz = encode_comp2_t(current->stat.udp_rsz);
|
||||||
|
+ ac.ac_rawsnd = encode_comp_t(current->stat.raw_snd);
|
||||||
|
+ ac.ac_rawrcv = encode_comp_t(current->stat.raw_rcv);
|
||||||
|
+ ac.ac_rss = current->mm ?
|
||||||
|
+ encode_comp_t(get_mm_rss(current->mm)<<(PAGE_SHIFT-10)) :
|
||||||
|
+ encode_comp_t(0);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
spin_lock_irq(¤t->sighand->siglock);
|
||||||
|
tty = current->signal->tty; /* Safe as we hold the siglock */
|
8782
3.3.8/3.3-ck1.patch
Normal file
8782
3.3.8/3.3-ck1.patch
Normal file
File diff suppressed because it is too large
Load Diff
181
3.3.8/3rd-3rdparty-1.0-tree.patch
Normal file
181
3.3.8/3rd-3rdparty-1.0-tree.patch
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
|
||||||
|
3rdparty/mkbuild.pl | 92 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
Documentation/3rdparty.txt | 76 +++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 168 insertions(+)
|
||||||
|
|
||||||
|
diff -Nurp linux-2.6.37/3rdparty/mkbuild.pl 3rdparty/mkbuild.pl
|
||||||
|
--- linux-2.6.37/3rdparty/mkbuild.pl 1970-01-01 02:00:00.000000000 +0200
|
||||||
|
+++ 3rdparty/mkbuild.pl 2004-04-23 14:59:03.000000000 +0300
|
||||||
|
@@ -0,0 +1,92 @@
|
||||||
|
+#!/usr/bin/perl -w
|
||||||
|
+#
|
||||||
|
+# Version 1.0
|
||||||
|
+#
|
||||||
|
+# Copyright 2001 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||||
|
+# Copyright 2002 Juan Quintela <quintela@mandrakesoft.com>
|
||||||
|
+# Copyright 2003 Nicolas Planel <nplanel@mandrakesoft.com>
|
||||||
|
+#
|
||||||
|
+# This software may be used and distributed according to the terms
|
||||||
|
+# of the GNU General Public License, incorporated herein by reference.
|
||||||
|
+#
|
||||||
|
+#
|
||||||
|
+# Run "mkbuild.pl"
|
||||||
|
+#
|
||||||
|
+# This program generates the following files
|
||||||
|
+# Makefile
|
||||||
|
+# Makefile.drivers
|
||||||
|
+# Config.in
|
||||||
|
+# using the information in the subdirs of this directory.
|
||||||
|
+#
|
||||||
|
+# subdirs need to have:
|
||||||
|
+# a Config.in file
|
||||||
|
+# a Makefile with a O_TARGET/L_TARGET targets
|
||||||
|
+# The config.in should set a CONFIG_<module_dir_name> to m/y.
|
||||||
|
+
|
||||||
|
+use strict;
|
||||||
|
+
|
||||||
|
+opendir(THISDIR, ".");
|
||||||
|
+# get dirs without . and .. garbage
|
||||||
|
+my (@modules) = grep(!/\.\.?$/,grep(-d, readdir(THISDIR)));
|
||||||
|
+closedir(THISDIR);
|
||||||
|
+
|
||||||
|
+generate_kconfig(@modules);
|
||||||
|
+generate_makefile(@modules);
|
||||||
|
+exit(0);
|
||||||
|
+
|
||||||
|
+##########################################################################
|
||||||
|
+
|
||||||
|
+sub generate_makefile {
|
||||||
|
+ my (@modules) = @_;
|
||||||
|
+
|
||||||
|
+ local *F;
|
||||||
|
+ open F, "> Makefile" or die "Cannot create new Makefile: $!\n";
|
||||||
|
+ print F <<'EOM';
|
||||||
|
+#
|
||||||
|
+# THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+EOM
|
||||||
|
+ printf F "obj- := 3rdparty.o # Dummy rule to force built-in.o to be made\n";
|
||||||
|
+ printf F "obj-\$(%s) += %s\n", to_CONFIG($_), $_ . '/' foreach @modules;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+sub generate_kconfig {
|
||||||
|
+ my (@modules) = @_;
|
||||||
|
+
|
||||||
|
+ local *F;
|
||||||
|
+ open F, "> Kconfig" or die "Cannot create Kconfig: $!\n";
|
||||||
|
+ print F <<"EOM";
|
||||||
|
+#
|
||||||
|
+# THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+menu "Unofficial 3rd party kernel additions"
|
||||||
|
+
|
||||||
|
+EOM
|
||||||
|
+
|
||||||
|
+ foreach (@modules) {
|
||||||
|
+ die "No Kconfig in $_.\n" if ! -r "$_/Kconfig";
|
||||||
|
+ print F "source 3rdparty/$_/Kconfig\n";
|
||||||
|
+ }
|
||||||
|
+ print F "\n\nendmenu\n";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+sub to_CONFIG {
|
||||||
|
+ local $_ = $_[0];
|
||||||
|
+ tr/a-z/A-Z/;
|
||||||
|
+ s/[\-\. ]/_/g;
|
||||||
|
+ "CONFIG_$_";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+sub find_target {
|
||||||
|
+ my ($module_dir) = @_;
|
||||||
|
+
|
||||||
|
+ local *F;
|
||||||
|
+ open(F, "$module_dir/Makefile") or die "$module_dir/Makefile: $!\n";
|
||||||
|
+ while (<F>) {
|
||||||
|
+ chomp;
|
||||||
|
+ return $1 if (/[LO]_TARGET.*:=\s+(\S+)/);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff -Nurp linux-2.6.37/Documentation/3rdparty.txt Documentation/3rdparty.txt
|
||||||
|
--- linux-2.6.37/Documentation/3rdparty.txt 1970-01-01 02:00:00.000000000 +0200
|
||||||
|
+++ Documentation/3rdparty.txt 2003-11-22 01:07:26.000000000 +0200
|
||||||
|
@@ -0,0 +1,76 @@
|
||||||
|
+
|
||||||
|
+Third-Party Kernel Source Module Support, or
|
||||||
|
+an easy way to add modules to your kernel build.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Vendors quite often add additional drivers and features to the kernel
|
||||||
|
+which require nothing more than modifying Kconfig, Makefile, and
|
||||||
|
+adding one or more files to a sub-directory. As a single discrete task,
|
||||||
|
+this is not a problem. However, using patches to add modules to the
|
||||||
|
+kernel very often results in patch conflicts, resulting in needless time
|
||||||
|
+wastage as developers regenerate an otherwise working kernel patch.
|
||||||
|
+
|
||||||
|
+This is designed as a solution to these problems. It is NOT designed as
|
||||||
|
+a replacement for the kernel build system, but merely as a tool for
|
||||||
|
+vendors and system administrators to ease the pain of patch management.
|
||||||
|
+
|
||||||
|
+The key feature of this system is the distinct lack of patches. Drivers
|
||||||
|
+are installed via unpacking a tarball.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Adding a directory to the build (usually from a tarball)
|
||||||
|
+--------------------------------------------------------
|
||||||
|
+If a directory exists inside the 3rdparty sub-directory that contains a
|
||||||
|
+proper Makefile, it can be added to the build. It also needs a
|
||||||
|
+Kconfig file.
|
||||||
|
+
|
||||||
|
+ cd /usr/src/linux-2.4.3/3rdparty
|
||||||
|
+ bzcat /tmp/my-driver2.tar.bz2 | tar xf - # creates "my2" dir
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Limitations
|
||||||
|
+-----------
|
||||||
|
+There are some limitations to this system. This system is only
|
||||||
|
+designed to support a very common case. If you find yourself running
|
||||||
|
+into limitations (kernel build experts can spot them right off),
|
||||||
|
+then you should probably be patching the kernel instead of using
|
||||||
|
+mkbuild.pl for that particular module.
|
||||||
|
+
|
||||||
|
+FIXME: actually list the limitations
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Other notes
|
||||||
|
+-----------
|
||||||
|
+Link order is controlled by the order of mkbuild.pl executions.
|
||||||
|
+
|
||||||
|
+"make mrproper" will erase Makefile.meta, and empty Kconfig, Makefile,
|
||||||
|
+and Makefile.drivers.
|
||||||
|
+
|
||||||
|
+IMPORTANT NOTE: Because this feature modifies the kernel's makefiles and
|
||||||
|
+configuration system, you MUST complete all mkbuild.pl runs before
|
||||||
|
+running any "make" command.
|
||||||
|
+
|
||||||
|
+Building in the 3rdparty dir
|
||||||
|
+----------------------------
|
||||||
|
+
|
||||||
|
+If you use modules that:
|
||||||
|
+ - are contained in one subdir with the name of the module
|
||||||
|
+ - has a Makefile
|
||||||
|
+ - has a Kconfig file
|
||||||
|
+
|
||||||
|
+The system calls the ./mkbuild.pl script. It will search for
|
||||||
|
+subdirectories, and will try to build each of them as a module.
|
||||||
|
+Things to note:
|
||||||
|
+
|
||||||
|
+ The dependencies will be done in a module called:
|
||||||
|
+
|
||||||
|
+ 3rdparty/<module_dir_name>/<module_name>
|
||||||
|
+
|
||||||
|
+depending of CONFIG_<module_name_in_uppercase>.
|
||||||
|
+
|
||||||
|
+<module_name> is the value of O_TARGET/L_TARGET.
|
||||||
|
+
|
||||||
|
+
|
372
3.3.8/3rd-3rdparty-button_hotplug-0.4.1.patch
Normal file
372
3.3.8/3rd-3rdparty-button_hotplug-0.4.1.patch
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
Submitted By: Mario Fetka (mario dot fetka at gmail dot com)
|
||||||
|
Date: 2012-11-18
|
||||||
|
Initial Package Version: 3.2.33
|
||||||
|
Origin: openwtr.org packages/system/button-hotplug
|
||||||
|
Upstream Status: unknown
|
||||||
|
Description: create uevents from button usage
|
||||||
|
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/button_hotplug/Kconfig 3rdparty/button_hotplug/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/button_hotplug/Kconfig 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/button_hotplug/Kconfig 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+config BUTTON_HOTPLUG
|
||||||
|
+ tristate "Button Hotplug driver"
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/button_hotplug/Makefile 3rdparty/button_hotplug/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/button_hotplug/Makefile 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/button_hotplug/Makefile 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+obj-${CONFIG_BUTTON_HOTPLUG} += button-hotplug.o
|
||||||
|
\ No newline at end of file
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/button_hotplug/button-hotplug.c 3rdparty/button_hotplug/button-hotplug.c
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/button_hotplug/button-hotplug.c 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/button_hotplug/button-hotplug.c 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1,349 @@
|
||||||
|
+/*
|
||||||
|
+ * Button Hotplug driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * Based on the diag.c - GPIO interface driver for Broadcom boards
|
||||||
|
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
|
||||||
|
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
+ * Copyright (C) 2008 Andy Boyett <agb@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/module.h>
|
||||||
|
+#include <linux/version.h>
|
||||||
|
+#include <linux/kmod.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+
|
||||||
|
+#include <linux/workqueue.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/netlink.h>
|
||||||
|
+#include <linux/kobject.h>
|
||||||
|
+
|
||||||
|
+#define DRV_NAME "button-hotplug"
|
||||||
|
+#define DRV_VERSION "0.4.1"
|
||||||
|
+#define DRV_DESC "Button Hotplug driver"
|
||||||
|
+
|
||||||
|
+#define BH_SKB_SIZE 2048
|
||||||
|
+
|
||||||
|
+#define PFX DRV_NAME ": "
|
||||||
|
+
|
||||||
|
+#undef BH_DEBUG
|
||||||
|
+
|
||||||
|
+#ifdef BH_DEBUG
|
||||||
|
+#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+#else
|
||||||
|
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+
|
||||||
|
+#ifndef BIT_MASK
|
||||||
|
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+struct bh_priv {
|
||||||
|
+ unsigned long *seen;
|
||||||
|
+ struct input_handle handle;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_event {
|
||||||
|
+ const char *name;
|
||||||
|
+ char *action;
|
||||||
|
+ unsigned long seen;
|
||||||
|
+
|
||||||
|
+ struct sk_buff *skb;
|
||||||
|
+ struct work_struct work;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_map {
|
||||||
|
+ unsigned int code;
|
||||||
|
+ const char *name;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern u64 uevent_next_seqnum(void);
|
||||||
|
+
|
||||||
|
+#define BH_MAP(_code, _name) \
|
||||||
|
+ { \
|
||||||
|
+ .code = (_code), \
|
||||||
|
+ .name = (_name), \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+static struct bh_map button_map[] = {
|
||||||
|
+ BH_MAP(BTN_0, "BTN_0"),
|
||||||
|
+ BH_MAP(BTN_1, "BTN_1"),
|
||||||
|
+ BH_MAP(BTN_2, "BTN_2"),
|
||||||
|
+ BH_MAP(BTN_3, "BTN_3"),
|
||||||
|
+ BH_MAP(BTN_4, "BTN_4"),
|
||||||
|
+ BH_MAP(BTN_5, "BTN_5"),
|
||||||
|
+ BH_MAP(BTN_6, "BTN_6"),
|
||||||
|
+ BH_MAP(BTN_7, "BTN_7"),
|
||||||
|
+ BH_MAP(BTN_8, "BTN_8"),
|
||||||
|
+ BH_MAP(BTN_9, "BTN_9"),
|
||||||
|
+ BH_MAP(KEY_RESTART, "reset"),
|
||||||
|
+#ifdef KEY_WPS_BUTTON
|
||||||
|
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
|
||||||
|
+#endif /* KEY_WPS_BUTTON */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||||
|
+ const char *format, ...)
|
||||||
|
+{
|
||||||
|
+ static char buf[128];
|
||||||
|
+ char *s;
|
||||||
|
+ va_list args;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ if (argv)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ va_start(args, format);
|
||||||
|
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||||
|
+ va_end(args);
|
||||||
|
+
|
||||||
|
+ if (len >= sizeof(buf)) {
|
||||||
|
+ BH_ERR("buffer size too small\n");
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = skb_put(event->skb, len + 1);
|
||||||
|
+ strcpy(s, buf);
|
||||||
|
+
|
||||||
|
+ BH_DBG("added variable '%s'\n", s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_fill_event(struct bh_event *event)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||||
|
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void button_hotplug_work(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||||
|
+ if (!event->skb)
|
||||||
|
+ goto out_free_event;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "%s@", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ ret = button_hotplug_fill_event(event);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||||
|
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ out_free_skb:
|
||||||
|
+ if (ret) {
|
||||||
|
+ BH_ERR("work error %d\n", ret);
|
||||||
|
+ kfree_skb(event->skb);
|
||||||
|
+ }
|
||||||
|
+ out_free_event:
|
||||||
|
+ kfree(event);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_create_event(const char *name, unsigned long seen,
|
||||||
|
+ int pressed)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event;
|
||||||
|
+
|
||||||
|
+ BH_DBG("create event, name=%s, seen=%lu, pressed=%d\n",
|
||||||
|
+ name, seen, pressed);
|
||||||
|
+
|
||||||
|
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||||
|
+ if (!event)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ event->name = name;
|
||||||
|
+ event->seen = seen;
|
||||||
|
+ event->action = pressed ? "pressed" : "released";
|
||||||
|
+
|
||||||
|
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
|
||||||
|
+ schedule_work(&event->work);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_HOTPLUG
|
||||||
|
+static int button_get_index(unsigned int code)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
|
||||||
|
+ if (button_map[i].code == code)
|
||||||
|
+ return i;
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+static void button_hotplug_event(struct input_handle *handle,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv = handle->private;
|
||||||
|
+ unsigned long seen = jiffies;
|
||||||
|
+ int btn;
|
||||||
|
+
|
||||||
|
+ BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value);
|
||||||
|
+
|
||||||
|
+ if (type != EV_KEY)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ btn = button_get_index(code);
|
||||||
|
+ if (btn < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ button_hotplug_create_event(button_map[btn].name,
|
||||||
|
+ (seen - priv->seen[btn]) / HZ, value);
|
||||||
|
+ priv->seen[btn] = seen;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static void button_hotplug_event(struct input_handle *handle,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif /* CONFIG_HOTPLUG */
|
||||||
|
+
|
||||||
|
+static int button_hotplug_connect(struct input_handler *handler,
|
||||||
|
+ struct input_dev *dev, const struct input_device_id *id)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv;
|
||||||
|
+ int ret;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
|
||||||
|
+ if (test_bit(button_map[i].code, dev->keybit))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (i == ARRAY_SIZE(button_map))
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ priv = kzalloc(sizeof(*priv) +
|
||||||
|
+ (sizeof(unsigned long) * ARRAY_SIZE(button_map)),
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!priv)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ priv->seen = (unsigned long *) &priv[1];
|
||||||
|
+ priv->handle.private = priv;
|
||||||
|
+ priv->handle.dev = dev;
|
||||||
|
+ priv->handle.handler = handler;
|
||||||
|
+ priv->handle.name = DRV_NAME;
|
||||||
|
+
|
||||||
|
+ ret = input_register_handle(&priv->handle);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto err_free_priv;
|
||||||
|
+
|
||||||
|
+ ret = input_open_device(&priv->handle);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto err_unregister_handle;
|
||||||
|
+
|
||||||
|
+ BH_DBG("connected to %s\n", dev->name);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ err_unregister_handle:
|
||||||
|
+ input_unregister_handle(&priv->handle);
|
||||||
|
+
|
||||||
|
+ err_free_priv:
|
||||||
|
+ kfree(priv);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void button_hotplug_disconnect(struct input_handle *handle)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv = handle->private;
|
||||||
|
+
|
||||||
|
+ input_close_device(handle);
|
||||||
|
+ input_unregister_handle(handle);
|
||||||
|
+
|
||||||
|
+ kfree(priv);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct input_device_id button_hotplug_ids[] = {
|
||||||
|
+ {
|
||||||
|
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
|
||||||
|
+ .evbit = { BIT_MASK(EV_KEY) },
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ /* Terminating entry */
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+MODULE_DEVICE_TABLE(input, button_hotplug_ids);
|
||||||
|
+
|
||||||
|
+static struct input_handler button_hotplug_handler = {
|
||||||
|
+ .event = button_hotplug_event,
|
||||||
|
+ .connect = button_hotplug_connect,
|
||||||
|
+ .disconnect = button_hotplug_disconnect,
|
||||||
|
+ .name = DRV_NAME,
|
||||||
|
+ .id_table = button_hotplug_ids,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+static int __init button_hotplug_init(void)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n");
|
||||||
|
+ ret = input_register_handler(&button_hotplug_handler);
|
||||||
|
+ if (ret)
|
||||||
|
+ BH_ERR("unable to register input handler\n");
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+module_init(button_hotplug_init);
|
||||||
|
+
|
||||||
|
+static void __exit button_hotplug_exit(void)
|
||||||
|
+{
|
||||||
|
+ input_unregister_handler(&button_hotplug_handler);
|
||||||
|
+}
|
||||||
|
+module_exit(button_hotplug_exit);
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION(DRV_DESC);
|
||||||
|
+MODULE_VERSION(DRV_VERSION);
|
||||||
|
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+
|
472
3.3.8/3rd-3rdparty-gpio_button_hotplug-0.1.patch
Normal file
472
3.3.8/3rd-3rdparty-gpio_button_hotplug-0.1.patch
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
Submitted By: Mario Fetka (mario dot fetka at gmail dot com)
|
||||||
|
Date: 2012-11-18
|
||||||
|
Initial Package Version: 3.2.33
|
||||||
|
Origin: openwtr.org packages/system/gpio-button-hotplug
|
||||||
|
Upstream Status: unknown
|
||||||
|
Description: gpio button uevent
|
||||||
|
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Kconfig 3rdparty/gpio_button_hotplug/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Kconfig 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/gpio_button_hotplug/Kconfig 2012-11-18 18:41:43.048939468 +0000
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+config GPIO_BUTTON_HOTPLUG
|
||||||
|
+ tristate "GPIO Button Hotplug driver"
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Makefile 3rdparty/gpio_button_hotplug/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/Makefile 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/gpio_button_hotplug/Makefile 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+obj-${CONFIG_GPIO_BUTTON_HOTPLUG} += gpio-button-hotplug.o
|
||||||
|
diff -Naur linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/gpio-button-hotplug.c 3rdparty/gpio_button_hotplug/gpio-button-hotplug.c
|
||||||
|
--- linux-3.2.33-go.orig/3rdparty/gpio_button_hotplug/gpio-button-hotplug.c 1970-01-01 00:00:00.000000000 +0000
|
||||||
|
+++ 3rdparty/gpio_button_hotplug/gpio-button-hotplug.c 2012-11-18 14:45:26.000000000 +0000
|
||||||
|
@@ -0,0 +1,450 @@
|
||||||
|
+/*
|
||||||
|
+ * GPIO Button Hotplug driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * Based on the diag.c - GPIO interface driver for Broadcom boards
|
||||||
|
+ * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>,
|
||||||
|
+ * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
+ * Copyright (C) 2008 Andy Boyett <agb@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/module.h>
|
||||||
|
+#include <linux/version.h>
|
||||||
|
+#include <linux/kmod.h>
|
||||||
|
+
|
||||||
|
+#include <linux/workqueue.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/netlink.h>
|
||||||
|
+#include <linux/kobject.h>
|
||||||
|
+#include <linux/input.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio_keys.h>
|
||||||
|
+
|
||||||
|
+#define DRV_NAME "gpio-keys-polled"
|
||||||
|
+
|
||||||
|
+#define BH_SKB_SIZE 2048
|
||||||
|
+
|
||||||
|
+#define PFX DRV_NAME ": "
|
||||||
|
+
|
||||||
|
+#undef BH_DEBUG
|
||||||
|
+
|
||||||
|
+#ifdef BH_DEBUG
|
||||||
|
+#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+#else
|
||||||
|
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args )
|
||||||
|
+
|
||||||
|
+struct bh_priv {
|
||||||
|
+ unsigned long seen;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_event {
|
||||||
|
+ const char *name;
|
||||||
|
+ char *action;
|
||||||
|
+ unsigned long seen;
|
||||||
|
+
|
||||||
|
+ struct sk_buff *skb;
|
||||||
|
+ struct work_struct work;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct bh_map {
|
||||||
|
+ unsigned int code;
|
||||||
|
+ const char *name;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct gpio_keys_button_data {
|
||||||
|
+ struct delayed_work work;
|
||||||
|
+ struct bh_priv bh;
|
||||||
|
+ int last_state;
|
||||||
|
+ int count;
|
||||||
|
+ int threshold;
|
||||||
|
+ int can_sleep;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern u64 uevent_next_seqnum(void);
|
||||||
|
+
|
||||||
|
+#define BH_MAP(_code, _name) \
|
||||||
|
+ { \
|
||||||
|
+ .code = (_code), \
|
||||||
|
+ .name = (_name), \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+static struct bh_map button_map[] = {
|
||||||
|
+ BH_MAP(BTN_0, "BTN_0"),
|
||||||
|
+ BH_MAP(BTN_1, "BTN_1"),
|
||||||
|
+ BH_MAP(BTN_2, "BTN_2"),
|
||||||
|
+ BH_MAP(BTN_3, "BTN_3"),
|
||||||
|
+ BH_MAP(BTN_4, "BTN_4"),
|
||||||
|
+ BH_MAP(BTN_5, "BTN_5"),
|
||||||
|
+ BH_MAP(BTN_6, "BTN_6"),
|
||||||
|
+ BH_MAP(BTN_7, "BTN_7"),
|
||||||
|
+ BH_MAP(BTN_8, "BTN_8"),
|
||||||
|
+ BH_MAP(BTN_9, "BTN_9"),
|
||||||
|
+ BH_MAP(KEY_RESTART, "reset"),
|
||||||
|
+#ifdef KEY_WPS_BUTTON
|
||||||
|
+ BH_MAP(KEY_WPS_BUTTON, "wps"),
|
||||||
|
+#endif /* KEY_WPS_BUTTON */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||||
|
+ const char *format, ...)
|
||||||
|
+{
|
||||||
|
+ static char buf[128];
|
||||||
|
+ char *s;
|
||||||
|
+ va_list args;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ if (argv)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ va_start(args, format);
|
||||||
|
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||||
|
+ va_end(args);
|
||||||
|
+
|
||||||
|
+ if (len >= sizeof(buf)) {
|
||||||
|
+ BH_ERR("buffer size too small\n");
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ s = skb_put(event->skb, len + 1);
|
||||||
|
+ strcpy(s, buf);
|
||||||
|
+
|
||||||
|
+ BH_DBG("added variable '%s'\n", s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_fill_event(struct bh_event *event)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||||
|
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=%s", "button");
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "ACTION=%s", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "BUTTON=%s", event->name);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEEN=%ld", event->seen);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void button_hotplug_work(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||||
|
+ if (!event->skb)
|
||||||
|
+ goto out_free_event;
|
||||||
|
+
|
||||||
|
+ ret = bh_event_add_var(event, 0, "%s@", event->action);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ ret = button_hotplug_fill_event(event);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_skb;
|
||||||
|
+
|
||||||
|
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||||
|
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ out_free_skb:
|
||||||
|
+ if (ret) {
|
||||||
|
+ BH_ERR("work error %d\n", ret);
|
||||||
|
+ kfree_skb(event->skb);
|
||||||
|
+ }
|
||||||
|
+ out_free_event:
|
||||||
|
+ kfree(event);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int button_hotplug_create_event(const char *name, unsigned long seen,
|
||||||
|
+ int pressed)
|
||||||
|
+{
|
||||||
|
+ struct bh_event *event;
|
||||||
|
+
|
||||||
|
+ BH_DBG("create event, name=%s, seen=%lu, pressed=%d\n",
|
||||||
|
+ name, seen, pressed);
|
||||||
|
+
|
||||||
|
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||||
|
+ if (!event)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ event->name = name;
|
||||||
|
+ event->seen = seen;
|
||||||
|
+ event->action = pressed ? "pressed" : "released";
|
||||||
|
+
|
||||||
|
+ INIT_WORK(&event->work, (void *)(void *)button_hotplug_work);
|
||||||
|
+ schedule_work(&event->work);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* -------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_HOTPLUG
|
||||||
|
+static int button_get_index(unsigned int code)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(button_map); i++)
|
||||||
|
+ if (button_map[i].code == code)
|
||||||
|
+ return i;
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+static void button_hotplug_event(struct gpio_keys_button_data *data,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+ struct bh_priv *priv = &data->bh;
|
||||||
|
+ unsigned long seen = jiffies;
|
||||||
|
+ int btn;
|
||||||
|
+
|
||||||
|
+ BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value);
|
||||||
|
+
|
||||||
|
+ if (type != EV_KEY)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ btn = button_get_index(code);
|
||||||
|
+ if (btn < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ button_hotplug_create_event(button_map[btn].name,
|
||||||
|
+ (seen - priv->seen) / HZ, value);
|
||||||
|
+ priv->seen = seen;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static void button_hotplug_event(struct gpio_keys_button_data *data,
|
||||||
|
+ unsigned int type, unsigned int code, int value)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif /* CONFIG_HOTPLUG */
|
||||||
|
+
|
||||||
|
+struct gpio_keys_polled_dev {
|
||||||
|
+ struct delayed_work work;
|
||||||
|
+
|
||||||
|
+ struct device *dev;
|
||||||
|
+ struct gpio_keys_platform_data *pdata;
|
||||||
|
+ struct gpio_keys_button_data data[0];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void gpio_keys_polled_check_state(struct gpio_keys_button *button,
|
||||||
|
+ struct gpio_keys_button_data *bdata)
|
||||||
|
+{
|
||||||
|
+ int state;
|
||||||
|
+
|
||||||
|
+ if (bdata->can_sleep)
|
||||||
|
+ state = !!gpio_get_value_cansleep(button->gpio);
|
||||||
|
+ else
|
||||||
|
+ state = !!gpio_get_value(button->gpio);
|
||||||
|
+
|
||||||
|
+ state = !!(state ^ button->active_low);
|
||||||
|
+ if (state != bdata->last_state) {
|
||||||
|
+ unsigned int type = button->type ?: EV_KEY;
|
||||||
|
+
|
||||||
|
+ button_hotplug_event(bdata, type, button->code, state);
|
||||||
|
+ bdata->count = 0;
|
||||||
|
+ bdata->last_state = state;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void gpio_keys_polled_queue_work(struct gpio_keys_polled_dev *bdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ unsigned long delay = msecs_to_jiffies(pdata->poll_interval);
|
||||||
|
+
|
||||||
|
+ if (delay >= HZ)
|
||||||
|
+ delay = round_jiffies_relative(delay);
|
||||||
|
+ schedule_delayed_work(&bdev->work, delay);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void gpio_keys_polled_poll(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_polled_dev *bdev =
|
||||||
|
+ container_of(work, struct gpio_keys_polled_dev, work.work);
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < bdev->pdata->nbuttons; i++) {
|
||||||
|
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
|
||||||
|
+
|
||||||
|
+ if (bdata->count < bdata->threshold)
|
||||||
|
+ bdata->count++;
|
||||||
|
+ else
|
||||||
|
+ gpio_keys_polled_check_state(&pdata->buttons[i], bdata);
|
||||||
|
+ }
|
||||||
|
+ gpio_keys_polled_queue_work(bdev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __devinit gpio_keys_polled_open(struct gpio_keys_polled_dev *bdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (pdata->enable)
|
||||||
|
+ pdata->enable(bdev->dev);
|
||||||
|
+
|
||||||
|
+ /* report initial state of the buttons */
|
||||||
|
+ for (i = 0; i < pdata->nbuttons; i++)
|
||||||
|
+ gpio_keys_polled_check_state(&pdata->buttons[i], &bdev->data[i]);
|
||||||
|
+
|
||||||
|
+ gpio_keys_polled_queue_work(bdev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __devexit gpio_keys_polled_close(struct gpio_keys_polled_dev *bdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+
|
||||||
|
+ cancel_delayed_work_sync(&bdev->work);
|
||||||
|
+
|
||||||
|
+ if (pdata->disable)
|
||||||
|
+ pdata->disable(bdev->dev);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __devinit gpio_keys_polled_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ struct gpio_keys_polled_dev *bdev;
|
||||||
|
+ int error;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (!pdata || !pdata->poll_interval)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) +
|
||||||
|
+ pdata->nbuttons * sizeof(struct gpio_keys_button_data),
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!bdev) {
|
||||||
|
+ dev_err(dev, "no memory for private data\n");
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < pdata->nbuttons; i++) {
|
||||||
|
+ struct gpio_keys_button *button = &pdata->buttons[i];
|
||||||
|
+ struct gpio_keys_button_data *bdata = &bdev->data[i];
|
||||||
|
+ unsigned int gpio = button->gpio;
|
||||||
|
+
|
||||||
|
+ if (button->wakeup) {
|
||||||
|
+ dev_err(dev, DRV_NAME " does not support wakeup\n");
|
||||||
|
+ error = -EINVAL;
|
||||||
|
+ goto err_free_gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ error = gpio_request(gpio,
|
||||||
|
+ button->desc ? button->desc : DRV_NAME);
|
||||||
|
+ if (error) {
|
||||||
|
+ dev_err(dev, "unable to claim gpio %u, err=%d\n",
|
||||||
|
+ gpio, error);
|
||||||
|
+ goto err_free_gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ error = gpio_direction_input(gpio);
|
||||||
|
+ if (error) {
|
||||||
|
+ dev_err(dev,
|
||||||
|
+ "unable to set direction on gpio %u, err=%d\n",
|
||||||
|
+ gpio, error);
|
||||||
|
+ goto err_free_gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bdata->can_sleep = gpio_cansleep(gpio);
|
||||||
|
+ bdata->last_state = 0;
|
||||||
|
+ bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
|
||||||
|
+ pdata->poll_interval);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bdev->dev = &pdev->dev;
|
||||||
|
+ bdev->pdata = pdata;
|
||||||
|
+ platform_set_drvdata(pdev, bdev);
|
||||||
|
+
|
||||||
|
+ INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll);
|
||||||
|
+
|
||||||
|
+ gpio_keys_polled_open(bdev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+err_free_gpio:
|
||||||
|
+ while (--i >= 0)
|
||||||
|
+ gpio_free(pdata->buttons[i].gpio);
|
||||||
|
+
|
||||||
|
+ kfree(bdev);
|
||||||
|
+ platform_set_drvdata(pdev, NULL);
|
||||||
|
+
|
||||||
|
+ return error;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __devexit gpio_keys_polled_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev);
|
||||||
|
+ struct gpio_keys_platform_data *pdata = bdev->pdata;
|
||||||
|
+ int i = pdata->nbuttons;
|
||||||
|
+
|
||||||
|
+ gpio_keys_polled_close(bdev);
|
||||||
|
+
|
||||||
|
+ while (--i >= 0)
|
||||||
|
+ gpio_free(pdata->buttons[i].gpio);
|
||||||
|
+
|
||||||
|
+ kfree(bdev);
|
||||||
|
+ platform_set_drvdata(pdev, NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct platform_driver gpio_keys_polled_driver = {
|
||||||
|
+ .probe = gpio_keys_polled_probe,
|
||||||
|
+ .remove = __devexit_p(gpio_keys_polled_remove),
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = DRV_NAME,
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init gpio_keys_polled_init(void)
|
||||||
|
+{
|
||||||
|
+ return platform_driver_register(&gpio_keys_polled_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit gpio_keys_polled_exit(void)
|
||||||
|
+{
|
||||||
|
+ platform_driver_unregister(&gpio_keys_polled_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(gpio_keys_polled_init);
|
||||||
|
+module_exit(gpio_keys_polled_exit);
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||||
|
+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
|
||||||
|
+MODULE_DESCRIPTION("Polled GPIO Buttons hotplug driver");
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+MODULE_ALIAS("platform:" DRV_NAME);
|
1354
3.3.8/3rd-3rdparty-gpio_event_drv-0.1.patch
Normal file
1354
3.3.8/3rd-3rdparty-gpio_event_drv-0.1.patch
Normal file
File diff suppressed because it is too large
Load Diff
156
3.3.8/3rd-3rdparty-merge.patch
Normal file
156
3.3.8/3rd-3rdparty-merge.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
diff -uNr linux-3.2.33-go.orig/arch/alpha/Kconfig linux-3.2.33-go/arch/alpha/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/alpha/Kconfig 2012-11-15 22:08:02.768806792 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/alpha/Kconfig 2012-11-15 22:08:29.937483632 +0100
|
||||||
|
@@ -673,3 +673,4 @@
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/arm/Kconfig linux-3.2.33-go/arch/arm/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/arm/Kconfig 2012-11-15 22:07:59.952839378 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/arm/Kconfig 2012-11-15 22:14:01.950566716 +0100
|
||||||
|
@@ -2259,3 +2259,5 @@
|
||||||
|
source "crypto/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/ia64/Kconfig linux-3.2.33-go/arch/ia64/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/ia64/Kconfig 2012-11-15 22:08:00.893828523 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/ia64/Kconfig 2012-11-15 22:08:29.938483621 +0100
|
||||||
|
@@ -669,3 +669,5 @@
|
||||||
|
|
||||||
|
config IOMMU_HELPER
|
||||||
|
def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB)
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/mips/Kconfig linux-3.2.33-go/arch/mips/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/mips/Kconfig 2012-11-15 22:08:02.698807597 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/mips/Kconfig 2012-11-15 22:08:29.939483610 +0100
|
||||||
|
@@ -2485,3 +2485,5 @@
|
||||||
|
source "crypto/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/powerpc/Kconfig linux-3.2.33-go/arch/powerpc/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/powerpc/Kconfig 2012-11-15 22:08:01.893816938 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/powerpc/Kconfig 2012-11-15 22:08:29.940483598 +0100
|
||||||
|
@@ -980,3 +980,5 @@
|
||||||
|
bool
|
||||||
|
|
||||||
|
source "arch/powerpc/kvm/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/sparc/Kconfig linux-3.2.33-go/arch/sparc/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/sparc/Kconfig 2012-11-15 22:08:00.130837331 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/sparc/Kconfig 2012-11-15 22:08:29.941483586 +0100
|
||||||
|
@@ -605,3 +605,5 @@
|
||||||
|
source "crypto/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/arch/x86/Kconfig linux-3.2.33-go/arch/x86/Kconfig
|
||||||
|
--- linux-3.2.33-go.orig/arch/x86/Kconfig 2012-11-15 22:08:00.435833823 +0100
|
||||||
|
+++ linux-3.2.33-go/arch/x86/Kconfig 2012-11-15 22:08:29.945483540 +0100
|
||||||
|
@@ -2179,3 +2179,5 @@
|
||||||
|
source "arch/x86/kvm/Kconfig"
|
||||||
|
|
||||||
|
source "lib/Kconfig"
|
||||||
|
+
|
||||||
|
+source "3rdparty/Kconfig"
|
||||||
|
diff -uNr linux-3.2.33-go.orig/Makefile linux-3.2.33-go/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/Makefile 2012-11-15 22:08:03.435799123 +0100
|
||||||
|
+++ linux-3.2.33-go/Makefile 2012-11-15 22:08:29.946483529 +0100
|
||||||
|
@@ -507,7 +507,7 @@
|
||||||
|
|
||||||
|
# Objects we will link into vmlinux / subdirs we need to visit
|
||||||
|
init-y := init/
|
||||||
|
-drivers-y := drivers/ sound/ firmware/
|
||||||
|
+drivers-y := drivers/ sound/ firmware/ 3rdparty/
|
||||||
|
net-y := net/
|
||||||
|
libs-y := lib/
|
||||||
|
core-y := usr/
|
||||||
|
diff -uNr linux-3.2.33-go.orig/scripts/kconfig/Makefile linux-3.2.33-go/scripts/kconfig/Makefile
|
||||||
|
--- linux-3.2.33-go.orig/scripts/kconfig/Makefile 2012-11-15 22:07:58.064861094 +0100
|
||||||
|
+++ linux-3.2.33-go/scripts/kconfig/Makefile 2012-11-15 22:08:55.603180188 +0100
|
||||||
|
@@ -11,29 +11,29 @@
|
||||||
|
Kconfig := Kconfig
|
||||||
|
endif
|
||||||
|
|
||||||
|
-xconfig: $(obj)/qconf
|
||||||
|
+xconfig: $(obj)/qconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-gconfig: $(obj)/gconf
|
||||||
|
+gconfig: $(obj)/gconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-menuconfig: $(obj)/mconf
|
||||||
|
+menuconfig: $(obj)/mconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-config: $(obj)/conf
|
||||||
|
+config: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --oldaskconfig $(Kconfig)
|
||||||
|
|
||||||
|
-nconfig: $(obj)/nconf
|
||||||
|
+nconfig: $(obj)/nconf 3rdparty/Makefile
|
||||||
|
$< $(Kconfig)
|
||||||
|
|
||||||
|
-oldconfig: $(obj)/conf
|
||||||
|
+oldconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
|
||||||
|
-silentoldconfig: $(obj)/conf
|
||||||
|
+silentoldconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$(Q)mkdir -p include/generated
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
|
||||||
|
-localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
|
||||||
|
+localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 3rdparty/Makefile
|
||||||
|
$(Q)mkdir -p include/generated
|
||||||
|
$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
|
||||||
|
$(Q)if [ -f .config ]; then \
|
||||||
|
@@ -90,18 +90,18 @@
|
||||||
|
*) cat $(CLONECONFIG) > .config.running ;; \
|
||||||
|
esac && \
|
||||||
|
echo -e "Cloning configuration file $(CLONECONFIG)\n"
|
||||||
|
- $(Q)$< --defconfig=.config.running arch/$(SRCARCH)/Kconfig
|
||||||
|
+ $(Q)$< --defconfig=.config.running arch/$(SRCARCH)/Kconfig 3rdparty/Makefile
|
||||||
|
|
||||||
|
|
||||||
|
PHONY += listnewconfig oldnoconfig savedefconfig defconfig
|
||||||
|
|
||||||
|
-listnewconfig oldnoconfig: $(obj)/conf
|
||||||
|
+listnewconfig oldnoconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --$@ $(Kconfig)
|
||||||
|
|
||||||
|
-savedefconfig: $(obj)/conf
|
||||||
|
+savedefconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$< --$@=defconfig $(Kconfig)
|
||||||
|
|
||||||
|
-defconfig: $(obj)/conf
|
||||||
|
+defconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
ifeq ($(KBUILD_DEFCONFIG),)
|
||||||
|
$< --defconfig $(Kconfig)
|
||||||
|
else
|
||||||
|
@@ -109,7 +109,7 @@
|
||||||
|
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-%_defconfig: $(obj)/conf
|
||||||
|
+%_defconfig: $(obj)/conf 3rdparty/Makefile
|
||||||
|
$(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
|
||||||
|
|
||||||
|
# Help text used by make help
|
||||||
|
@@ -186,6 +186,8 @@
|
||||||
|
gconf-target := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
+3rdparty/Makefile:
|
||||||
|
+ pushd $(srctree)/3rdparty ; $(PERL) ./mkbuild.pl ; popd
|
||||||
|
|
||||||
|
ifeq ($(qconf-target),1)
|
||||||
|
hostprogs-y += qconf
|
1769
3.3.8/3rd-3rdparty-netatop-0.1.1.patch
Normal file
1769
3.3.8/3rd-3rdparty-netatop-0.1.1.patch
Normal file
File diff suppressed because it is too large
Load Diff
2142
3.3.8/600-netfilter_layer7_2.22.patch
Normal file
2142
3.3.8/600-netfilter_layer7_2.22.patch
Normal file
File diff suppressed because it is too large
Load Diff
108
3.3.8/601-netfilter_layer7_pktmatch.patch
Normal file
108
3.3.8/601-netfilter_layer7_pktmatch.patch
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
--- 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){
|
51
3.3.8/602-netfilter_layer7_match.patch
Normal file
51
3.3.8/602-netfilter_layer7_match.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
--- a/net/netfilter/xt_layer7.c
|
||||||
|
+++ b/net/netfilter/xt_layer7.c
|
||||||
|
@@ -415,7 +415,9 @@ static int layer7_write_proc(struct file
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
|
||||||
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||||
|
+match(const struct sk_buff *skbin, struct xt_action_param *par)
|
||||||
|
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
|
||||||
|
match(const struct sk_buff *skbin, const struct xt_match_param *par)
|
||||||
|
#else
|
||||||
|
match(const struct sk_buff *skbin,
|
||||||
|
@@ -597,14 +599,19 @@ match(const struct sk_buff *skbin,
|
||||||
|
}
|
||||||
|
|
||||||
|
// load nf_conntrack_ipv4
|
||||||
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||||
|
+static int
|
||||||
|
+#else
|
||||||
|
+static bool
|
||||||
|
+#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
|
||||||
|
-static bool check(const struct xt_mtchk_param *par)
|
||||||
|
+check(const struct xt_mtchk_param *par)
|
||||||
|
{
|
||||||
|
if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
|
||||||
|
printk(KERN_WARNING "can't load conntrack support for "
|
||||||
|
"proto=%d\n", par->match->family);
|
||||||
|
#else
|
||||||
|
-static bool check(const char *tablename, const void *inf,
|
||||||
|
+check(const char *tablename, const void *inf,
|
||||||
|
const struct xt_match *match, void *matchinfo,
|
||||||
|
unsigned int hook_mask)
|
||||||
|
{
|
||||||
|
@@ -612,9 +619,15 @@ static bool check(const char *tablename,
|
||||||
|
printk(KERN_WARNING "can't load conntrack support for "
|
||||||
|
"proto=%d\n", match->family);
|
||||||
|
#endif
|
||||||
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+#else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
61
3.3.8/603-netfilter_layer7_2.6.36_fix.patch
Normal file
61
3.3.8/603-netfilter_layer7_2.6.36_fix.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
--- a/net/netfilter/Kconfig
|
||||||
|
+++ b/net/netfilter/Kconfig
|
||||||
|
@@ -857,6 +857,27 @@ config NETFILTER_XT_MATCH_IPVS
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
|
+config NETFILTER_XT_MATCH_LAYER7
|
||||||
|
+ tristate '"layer7" match support'
|
||||||
|
+ depends on EXPERIMENTAL
|
||||||
|
+ depends on NETFILTER_XTABLES
|
||||||
|
+ depends on NETFILTER_ADVANCED
|
||||||
|
+ depends on NF_CONNTRACK
|
||||||
|
+ help
|
||||||
|
+ Say Y if you want to be able to classify connections (and their
|
||||||
|
+ packets) based on regular expression matching of their application
|
||||||
|
+ layer data. This is one way to classify applications such as
|
||||||
|
+ peer-to-peer filesharing systems that do not always use the same
|
||||||
|
+ port.
|
||||||
|
+
|
||||||
|
+ To compile it as a module, choose M here. If unsure, say N.
|
||||||
|
+
|
||||||
|
+config NETFILTER_XT_MATCH_LAYER7_DEBUG
|
||||||
|
+ bool 'Layer 7 debugging output'
|
||||||
|
+ depends on NETFILTER_XT_MATCH_LAYER7
|
||||||
|
+ help
|
||||||
|
+ Say Y to get lots of debugging output.
|
||||||
|
+
|
||||||
|
config NETFILTER_XT_MATCH_LENGTH
|
||||||
|
tristate '"length" match support'
|
||||||
|
depends on NETFILTER_ADVANCED
|
||||||
|
@@ -1053,26 +1074,11 @@ config NETFILTER_XT_MATCH_STATE
|
||||||
|
|
||||||
|
To compile it as a module, choose M here. If unsure, say N.
|
||||||
|
|
||||||
|
-config NETFILTER_XT_MATCH_LAYER7
|
||||||
|
- tristate '"layer7" match support'
|
||||||
|
- depends on NETFILTER_XTABLES
|
||||||
|
- depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK)
|
||||||
|
- depends on NETFILTER_ADVANCED
|
||||||
|
- help
|
||||||
|
- Say Y if you want to be able to classify connections (and their
|
||||||
|
- packets) based on regular expression matching of their application
|
||||||
|
- layer data. This is one way to classify applications such as
|
||||||
|
- peer-to-peer filesharing systems that do not always use the same
|
||||||
|
- port.
|
||||||
|
-
|
||||||
|
- To compile it as a module, choose M here. If unsure, say N.
|
||||||
|
-
|
||||||
|
config NETFILTER_XT_MATCH_LAYER7_DEBUG
|
||||||
|
- bool 'Layer 7 debugging output'
|
||||||
|
- depends on NETFILTER_XT_MATCH_LAYER7
|
||||||
|
- help
|
||||||
|
- Say Y to get lots of debugging output.
|
||||||
|
-
|
||||||
|
+ bool 'Layer 7 debugging output'
|
||||||
|
+ depends on NETFILTER_XT_MATCH_LAYER7
|
||||||
|
+ help
|
||||||
|
+ Say Y to get lots of debugging output.
|
||||||
|
|
||||||
|
config NETFILTER_XT_MATCH_STATISTIC
|
||||||
|
tristate '"statistic" match support'
|
118
3.3.8/604-netfilter_cisco_794x_iphone.patch
Normal file
118
3.3.8/604-netfilter_cisco_794x_iphone.patch
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
--- a/include/linux/netfilter/nf_conntrack_sip.h
|
||||||
|
+++ b/include/linux/netfilter/nf_conntrack_sip.h
|
||||||
|
@@ -2,12 +2,15 @@
|
||||||
|
#define __NF_CONNTRACK_SIP_H__
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
+#include <linux/types.h>
|
||||||
|
+
|
||||||
|
#define SIP_PORT 5060
|
||||||
|
#define SIP_TIMEOUT 3600
|
||||||
|
|
||||||
|
struct nf_ct_sip_master {
|
||||||
|
unsigned int register_cseq;
|
||||||
|
unsigned int invite_cseq;
|
||||||
|
+ __be16 forced_dport;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum sip_expectation_classes {
|
||||||
|
--- a/net/ipv4/netfilter/nf_nat_sip.c
|
||||||
|
+++ b/net/ipv4/netfilter/nf_nat_sip.c
|
||||||
|
@@ -73,6 +73,7 @@ static int map_addr(struct sk_buff *skb,
|
||||||
|
enum ip_conntrack_info ctinfo;
|
||||||
|
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||||
|
+ struct nf_conn_help *help = nfct_help(ct);
|
||||||
|
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
|
||||||
|
unsigned int buflen;
|
||||||
|
__be32 newaddr;
|
||||||
|
@@ -85,7 +86,8 @@ static int map_addr(struct sk_buff *skb,
|
||||||
|
} else if (ct->tuplehash[dir].tuple.dst.u3.ip == addr->ip &&
|
||||||
|
ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
|
||||||
|
newaddr = ct->tuplehash[!dir].tuple.src.u3.ip;
|
||||||
|
- newport = ct->tuplehash[!dir].tuple.src.u.udp.port;
|
||||||
|
+ newport = help->help.ct_sip_info.forced_dport ? :
|
||||||
|
+ ct->tuplehash[!dir].tuple.src.u.udp.port;
|
||||||
|
} else
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
@@ -121,6 +123,7 @@ static unsigned int ip_nat_sip(struct sk
|
||||||
|
enum ip_conntrack_info ctinfo;
|
||||||
|
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||||
|
+ struct nf_conn_help *help = nfct_help(ct);
|
||||||
|
unsigned int coff, matchoff, matchlen;
|
||||||
|
enum sip_header_types hdr;
|
||||||
|
union nf_inet_addr addr;
|
||||||
|
@@ -229,6 +232,20 @@ next:
|
||||||
|
!map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_TO))
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
|
+ /* Mangle destination port for Cisco phones, then fix up checksums */
|
||||||
|
+ if (dir == IP_CT_DIR_REPLY && help->help.ct_sip_info.forced_dport) {
|
||||||
|
+ struct udphdr *uh;
|
||||||
|
+
|
||||||
|
+ if (!skb_make_writable(skb, skb->len))
|
||||||
|
+ return NF_DROP;
|
||||||
|
+
|
||||||
|
+ uh = (struct udphdr *)(skb->data + ip_hdrlen(skb));
|
||||||
|
+ uh->dest = help->help.ct_sip_info.forced_dport;
|
||||||
|
+
|
||||||
|
+ if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, 0, 0, NULL, 0))
|
||||||
|
+ return NF_DROP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -280,8 +297,10 @@ static unsigned int ip_nat_sip_expect(st
|
||||||
|
enum ip_conntrack_info ctinfo;
|
||||||
|
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||||
|
+ struct nf_conn_help *help = nfct_help(ct);
|
||||||
|
__be32 newip;
|
||||||
|
u_int16_t port;
|
||||||
|
+ __be16 srcport;
|
||||||
|
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
|
||||||
|
unsigned buflen;
|
||||||
|
|
||||||
|
@@ -294,8 +313,9 @@ static unsigned int ip_nat_sip_expect(st
|
||||||
|
/* If the signalling port matches the connection's source port in the
|
||||||
|
* original direction, try to use the destination port in the opposite
|
||||||
|
* direction. */
|
||||||
|
- if (exp->tuple.dst.u.udp.port ==
|
||||||
|
- ct->tuplehash[dir].tuple.src.u.udp.port)
|
||||||
|
+ srcport = help->help.ct_sip_info.forced_dport ? :
|
||||||
|
+ ct->tuplehash[dir].tuple.src.u.udp.port;
|
||||||
|
+ if (exp->tuple.dst.u.udp.port == srcport)
|
||||||
|
port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
|
||||||
|
else
|
||||||
|
port = ntohs(exp->tuple.dst.u.udp.port);
|
||||||
|
--- a/net/netfilter/nf_conntrack_sip.c
|
||||||
|
+++ b/net/netfilter/nf_conntrack_sip.c
|
||||||
|
@@ -1363,8 +1363,25 @@ static int process_sip_request(struct sk
|
||||||
|
{
|
||||||
|
enum ip_conntrack_info ctinfo;
|
||||||
|
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
+ struct nf_conn_help *help = nfct_help(ct);
|
||||||
|
+ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||||
|
unsigned int matchoff, matchlen;
|
||||||
|
unsigned int cseq, i;
|
||||||
|
+ union nf_inet_addr addr;
|
||||||
|
+ __be16 port;
|
||||||
|
+
|
||||||
|
+ /* Many Cisco IP phones use a high source port for SIP requests, but
|
||||||
|
+ * listen for the response on port 5060. If we are the local
|
||||||
|
+ * router for one of these phones, save the port number from the
|
||||||
|
+ * Via: header so that nf_nat_sip can redirect the responses to
|
||||||
|
+ * the correct port.
|
||||||
|
+ */
|
||||||
|
+ if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
|
||||||
|
+ SIP_HDR_VIA_UDP, NULL, &matchoff,
|
||||||
|
+ &matchlen, &addr, &port) > 0 &&
|
||||||
|
+ port != ct->tuplehash[dir].tuple.src.u.udp.port &&
|
||||||
|
+ nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3))
|
||||||
|
+ help->help.ct_sip_info.forced_dport = port;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
|
||||||
|
const struct sip_handler *handler;
|
93
3.3.8/610-netfilter_match_bypass_default_checks.patch
Normal file
93
3.3.8/610-netfilter_match_bypass_default_checks.patch
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
--- a/include/linux/netfilter_ipv4/ip_tables.h
|
||||||
|
+++ b/include/linux/netfilter_ipv4/ip_tables.h
|
||||||
|
@@ -93,6 +93,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
|
||||||
|
@@ -81,6 +81,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,
|
||||||
|
@@ -134,6 +137,29 @@ ip_packet_match(const struct iphdr *ip,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+ip_checkdefault(struct ipt_ip *ip)
|
||||||
|
+{
|
||||||
|
+ static const char iface_mask[IFNAMSIZ] = {};
|
||||||
|
+
|
||||||
|
+ if (ip->invflags || ip->flags & IPT_F_FRAG)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (ip->smsk.s_addr || ip->dmsk.s_addr)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (ip->proto)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ip->flags |= IPT_F_NO_DEF_MATCH;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool
|
||||||
|
ip_checkentry(const struct ipt_ip *ip)
|
||||||
|
{
|
||||||
|
@@ -561,7 +587,7 @@ static void cleanup_match(struct xt_entr
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-check_entry(const struct ipt_entry *e, const char *name)
|
||||||
|
+check_entry(struct ipt_entry *e, const char *name)
|
||||||
|
{
|
||||||
|
const struct xt_entry_target *t;
|
||||||
|
|
||||||
|
@@ -570,6 +596,8 @@ check_entry(const struct ipt_entry *e, c
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ip_checkdefault(&e->ip);
|
||||||
|
+
|
||||||
|
if (e->target_offset + sizeof(struct xt_entry_target) >
|
||||||
|
e->next_offset)
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -931,6 +959,7 @@ copy_entries_to_user(unsigned int total_
|
||||||
|
const struct xt_table_info *private = table->private;
|
||||||
|
int ret = 0;
|
||||||
|
const void *loc_cpu_entry;
|
||||||
|
+ u8 flags;
|
||||||
|
|
||||||
|
counters = alloc_counters(table);
|
||||||
|
if (IS_ERR(counters))
|
||||||
|
@@ -961,6 +990,14 @@ copy_entries_to_user(unsigned int total_
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto free_counters;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ flags = e->ip.flags & IPT_F_MASK;
|
||||||
|
+ 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;
|
81
3.3.8/611-netfilter_match_bypass_default_table.patch
Normal file
81
3.3.8/611-netfilter_match_bypass_default_table.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
--- a/net/ipv4/netfilter/ip_tables.c
|
||||||
|
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||||
|
@@ -310,6 +310,33 @@ struct ipt_entry *ipt_next_entry(const s
|
||||||
|
return (void *)entry + entry->next_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
|
||||||
|
+{
|
||||||
|
+ struct xt_entry_target *t;
|
||||||
|
+ struct xt_standard_target *st;
|
||||||
|
+
|
||||||
|
+ if (e->target_offset != sizeof(struct ipt_entry))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ t = ipt_get_target(e);
|
||||||
|
+ if (t->u.kernel.target->target)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ st = (struct xt_standard_target *) t;
|
||||||
|
+ if (st->verdict == XT_RETURN)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (st->verdict >= 0)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ *verdict = (unsigned)(-st->verdict) - 1;
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
|
||||||
|
unsigned int
|
||||||
|
ipt_do_table(struct sk_buff *skb,
|
||||||
|
@@ -334,6 +361,25 @@ ipt_do_table(struct sk_buff *skb,
|
||||||
|
ip = ip_hdr(skb);
|
||||||
|
indev = in ? in->name : nulldevname;
|
||||||
|
outdev = out ? out->name : nulldevname;
|
||||||
|
+
|
||||||
|
+ IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||||
|
+ local_bh_disable();
|
||||||
|
+ addend = xt_write_recseq_begin();
|
||||||
|
+ private = table->private;
|
||||||
|
+ cpu = smp_processor_id();
|
||||||
|
+ table_base = private->entries[cpu];
|
||||||
|
+ jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
|
||||||
|
+ stackptr = per_cpu_ptr(private->stackptr, cpu);
|
||||||
|
+ origptr = *stackptr;
|
||||||
|
+
|
||||||
|
+ e = get_entry(table_base, private->hook_entry[hook]);
|
||||||
|
+ if (ipt_handle_default_rule(e, &verdict)) {
|
||||||
|
+ ADD_COUNTER(e->counters, skb->len, 1);
|
||||||
|
+ xt_write_recseq_end(addend);
|
||||||
|
+ local_bh_enable();
|
||||||
|
+ return verdict;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* We handle fragments by dealing with the first fragment as
|
||||||
|
* if it was a normal packet. All other fragments are treated
|
||||||
|
* normally, except that they will NEVER match rules that ask
|
||||||
|
@@ -348,18 +394,6 @@ ipt_do_table(struct sk_buff *skb,
|
||||||
|
acpar.family = NFPROTO_IPV4;
|
||||||
|
acpar.hooknum = hook;
|
||||||
|
|
||||||
|
- IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||||
|
- local_bh_disable();
|
||||||
|
- addend = xt_write_recseq_begin();
|
||||||
|
- private = table->private;
|
||||||
|
- cpu = smp_processor_id();
|
||||||
|
- table_base = private->entries[cpu];
|
||||||
|
- jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
|
||||||
|
- stackptr = per_cpu_ptr(private->stackptr, cpu);
|
||||||
|
- origptr = *stackptr;
|
||||||
|
-
|
||||||
|
- e = get_entry(table_base, private->hook_entry[hook]);
|
||||||
|
-
|
||||||
|
pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
|
||||||
|
table->name, hook, origptr,
|
||||||
|
get_entry(table_base, private->underflow[hook]));
|
16
3.3.8/612-netfilter_match_reduce_memory_access.patch
Normal file
16
3.3.8/612-netfilter_match_reduce_memory_access.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
--- a/net/ipv4/netfilter/ip_tables.c
|
||||||
|
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||||
|
@@ -84,9 +84,11 @@ ip_packet_match(const struct iphdr *ip,
|
||||||
|
if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
- if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
|
||||||
|
+ if (FWINV(ipinfo->smsk.s_addr &&
|
||||||
|
+ (ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
|
||||||
|
IPT_INV_SRCIP) ||
|
||||||
|
- FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
|
||||||
|
+ FWINV(ipinfo->dmsk.s_addr &&
|
||||||
|
+ (ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
|
||||||
|
IPT_INV_DSTIP)) {
|
||||||
|
dprintf("Source or dest mismatch.\n");
|
||||||
|
|
36
3.3.8/613-netfilter_optional_tcp_window_check.patch
Normal file
36
3.3.8/613-netfilter_optional_tcp_window_check.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--- a/net/netfilter/nf_conntrack_proto_tcp.c
|
||||||
|
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
|
||||||
|
@@ -29,6 +29,9 @@
|
||||||
|
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
|
||||||
|
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
||||||
|
|
||||||
|
+/* Do not check the TCP window for incoming packets */
|
||||||
|
+static int nf_ct_tcp_no_window_check __read_mostly = 1;
|
||||||
|
+
|
||||||
|
/* "Be conservative in what you do,
|
||||||
|
be liberal in what you accept from others."
|
||||||
|
If it's non-zero, we mark only out of window RST segments as INVALID. */
|
||||||
|
@@ -524,6 +527,9 @@ static bool tcp_in_window(const struct n
|
||||||
|
s16 receiver_offset;
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
+ if (nf_ct_tcp_no_window_check)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Get the required data from the packet.
|
||||||
|
*/
|
||||||
|
@@ -1321,6 +1327,13 @@ static struct ctl_table tcp_sysctl_table
|
||||||
|
.proc_handler = proc_dointvec,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
+ .procname = "nf_conntrack_tcp_no_window_check",
|
||||||
|
+ .data = &nf_ct_tcp_no_window_check,
|
||||||
|
+ .maxlen = sizeof(unsigned int),
|
||||||
|
+ .mode = 0644,
|
||||||
|
+ .proc_handler = proc_dointvec,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
.procname = "nf_conntrack_tcp_be_liberal",
|
||||||
|
.data = &nf_ct_tcp_be_liberal,
|
||||||
|
.maxlen = sizeof(unsigned int),
|
791
3.3.8/620-sched_esfq.patch
Normal file
791
3.3.8/620-sched_esfq.patch
Normal file
@ -0,0 +1,791 @@
|
|||||||
|
--- a/include/linux/pkt_sched.h
|
||||||
|
+++ b/include/linux/pkt_sched.h
|
||||||
|
@@ -193,6 +193,33 @@ struct tc_sfq_xstats {
|
||||||
|
__s32 allot;
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* 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
|
||||||
|
@@ -148,6 +148,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
|
||||||
|
@@ -26,6 +26,7 @@ obj-$(CONFIG_NET_SCH_INGRESS) += sch_ing
|
||||||
|
obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o
|
||||||
|
obj-$(CONFIG_NET_SCH_SFB) += sch_sfb.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");
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user