aboutsummaryrefslogtreecommitdiff
path: root/network/ndiswrapper-kernel
diff options
context:
space:
mode:
authorRobby Workman <rworkman@slackbuilds.org>2013-11-03 10:45:00 -0600
committerRobby Workman <rworkman@slackbuilds.org>2013-11-03 11:12:15 -0600
commit14428f0756c6cb532756f34dd14eef9f14b78e1a (patch)
treefc39ea652c44431a67e6e688ba7014bf1b10ecbd /network/ndiswrapper-kernel
parent518cd3e68ac7baac792bec0ad0609830e72b6fdd (diff)
network/ndiswrapper-kernel: Included some patches for 3.8-3.10.x
Signed-off-by: Robby Workman <rworkman@slackbuilds.org>
Diffstat (limited to 'network/ndiswrapper-kernel')
-rw-r--r--network/ndiswrapper-kernel/ndiswrapper-kernel.SlackBuild8
-rw-r--r--network/ndiswrapper-kernel/patches/0001-Use-KERNELRELEASE-as-target-kernel-version.patch38
-rw-r--r--network/ndiswrapper-kernel/patches/0002-Add-support-for-kernel-3.9.patch54
-rw-r--r--network/ndiswrapper-kernel/patches/0003-Add-support-for-3.x-kernel-versions.patch35
-rw-r--r--network/ndiswrapper-kernel/patches/0004-Support-3.10-kernel-and-older-versions.patch649
-rw-r--r--network/ndiswrapper-kernel/patches/0005-Fix-compilation-on-pre-3.9.patch30
6 files changed, 814 insertions, 0 deletions
diff --git a/network/ndiswrapper-kernel/ndiswrapper-kernel.SlackBuild b/network/ndiswrapper-kernel/ndiswrapper-kernel.SlackBuild
index 13ae765ff5c6..b53c0b440faf 100644
--- a/network/ndiswrapper-kernel/ndiswrapper-kernel.SlackBuild
+++ b/network/ndiswrapper-kernel/ndiswrapper-kernel.SlackBuild
@@ -78,6 +78,14 @@ find . \
\( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
-exec chmod 644 {} \;
+# Thanks to Andrey Utkin <andrey.krieger.utkin@gmail.com> for putting all
+# of the necessary patches in one place
+patch -p1 < $CWD/patches/0001-Use-KERNELRELEASE-as-target-kernel-version.patch
+patch -p1 < $CWD/patches/0002-Add-support-for-kernel-3.9.patch
+patch -p1 < $CWD/patches/0003-Add-support-for-3.x-kernel-versions.patch
+patch -p1 < $CWD/patches/0004-Support-3.10-kernel-and-older-versions.patch
+patch -p1 < $CWD/patches/0005-Fix-compilation-on-pre-3.9.patch
+
EXTRA_CFLAGS="$SLKCFLAGS" \
make -C driver KVERS=$KERNEL V=1
make install -C driver KVERS=$KERNEL DESTDIR=$PKG
diff --git a/network/ndiswrapper-kernel/patches/0001-Use-KERNELRELEASE-as-target-kernel-version.patch b/network/ndiswrapper-kernel/patches/0001-Use-KERNELRELEASE-as-target-kernel-version.patch
new file mode 100644
index 000000000000..63031be58ea9
--- /dev/null
+++ b/network/ndiswrapper-kernel/patches/0001-Use-KERNELRELEASE-as-target-kernel-version.patch
@@ -0,0 +1,38 @@
+From f92374a3e3b1952f6ee882872b7b74686ccfc940 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 8 Oct 2013 20:47:16 +0300
+Subject: [PATCH 1/5] Use $KERNELRELEASE as target kernel version
+
+We must not assume that the running kernel version is the target
+version! DKMS and later Kbuild set $KERNELRELEASE to be the target
+kernel version.
+
+---
+
+Taken from git://anonscm.debian.org/collab-maint/ndiswrapper.git
+debian/patches/ndiswrapper-use-KERNELRELEASE.patch
+
+Signed-off-by: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+---
+ driver/Makefile | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/driver/Makefile b/driver/Makefile
+index fd5cebf..37dda9c 100644
+--- a/driver/Makefile
++++ b/driver/Makefile
+@@ -12,7 +12,11 @@ DISTFILES = \
+ # By default, we try to compile the modules for the currently running
+ # kernel. But it's the first approximation, as we will re-read the
+ # version from the kernel sources.
++ifeq (,$(KERNELRELEASE))
+ KVERS_UNAME ?= $(shell uname -r)
++else
++KVERS_UNAME ?= $(KERNELRELEASE)
++endif
+
+ # KBUILD is the path to the Linux kernel build tree. It is usually the
+ # same as the kernel source tree, except when the kernel was compiled in
+--
+1.8.4
+
diff --git a/network/ndiswrapper-kernel/patches/0002-Add-support-for-kernel-3.9.patch b/network/ndiswrapper-kernel/patches/0002-Add-support-for-kernel-3.9.patch
new file mode 100644
index 000000000000..3f7516933830
--- /dev/null
+++ b/network/ndiswrapper-kernel/patches/0002-Add-support-for-kernel-3.9.patch
@@ -0,0 +1,54 @@
+From a2577406f5d76ec02562f083e8b345702b74fce5 Mon Sep 17 00:00:00 2001
+From: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+Date: Tue, 8 Oct 2013 20:51:14 +0300
+Subject: [PATCH 2/5] Add support for kernel 3.9
+
+Taken from git://anonscm.debian.org/collab-maint/ndiswrapper.git
+debian/patches/support-kernel-3.9.patch
+Patch authorship is not clear, the committer was
+Julian Andres Klode <jak@debian.org>
+
+Gentoo ebuild uses similar patch, but with LOCKDEP_STILL_OK instead of
+LOCKDEP_NOW_UNRELIABLE. I don't know yet which is more correct.
+
+Signed-off-by: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+---
+ driver/loader.c | 4 ++++
+ driver/wrapper.c | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/driver/loader.c b/driver/loader.c
+index 406e6ba..2b27252 100644
+--- a/driver/loader.c
++++ b/driver/loader.c
+@@ -575,7 +575,11 @@ static int load_user_space_driver(struct load_driver *load_driver)
+ } else {
+ printk(KERN_INFO "%s: driver %s (%s) loaded\n",
+ DRIVER_NAME, wrap_driver->name, wrap_driver->version);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
+ add_taint(TAINT_PROPRIETARY_MODULE);
++#else
++ add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE);
++#endif
+ EXIT1(return 0);
+ }
+ }
+diff --git a/driver/wrapper.c b/driver/wrapper.c
+index f77c879..1bd3116 100644
+--- a/driver/wrapper.c
++++ b/driver/wrapper.c
+@@ -72,7 +72,11 @@ static void module_cleanup(void)
+ static int __init wrapper_init(void)
+ {
+ #ifdef TAINT_OOT_MODULE
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
+ add_taint(TAINT_OOT_MODULE);
++#else
++ add_taint(TAINT_OOT_MODULE, LOCKDEP_NOW_UNRELIABLE);
++#endif
+ #endif
+ printk(KERN_INFO "%s version %s loaded (smp=%s, preempt=%s)\n",
+ DRIVER_NAME, DRIVER_VERSION,
+--
+1.8.4
+
diff --git a/network/ndiswrapper-kernel/patches/0003-Add-support-for-3.x-kernel-versions.patch b/network/ndiswrapper-kernel/patches/0003-Add-support-for-3.x-kernel-versions.patch
new file mode 100644
index 000000000000..56c3fe114b58
--- /dev/null
+++ b/network/ndiswrapper-kernel/patches/0003-Add-support-for-3.x-kernel-versions.patch
@@ -0,0 +1,35 @@
+From 84a300f96343825fdf289bb452f9aea17a7f1a31 Mon Sep 17 00:00:00 2001
+From: Tim Gardner <tim.gardner@canonical.com>
+Date: Mon, 13 Feb 2012 14:19:58 -0700
+Subject: [PATCH 3/5] Add support for 3.x kernel versions
+
+As suggested by Kano on Freenode #ubuntu-kernel
+
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+
+---
+
+Taken from git://anonscm.debian.org/collab-maint/ndiswrapper.git
+debian/patches/Add-support-for-3.x-kernel-versions.patch
+
+Signed-off-by: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+---
+ utils/ndiswrapper | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/utils/ndiswrapper b/utils/ndiswrapper
+index 4bb91f2..ba082a3 100755
+--- a/utils/ndiswrapper
++++ b/utils/ndiswrapper
+@@ -55,7 +55,7 @@ if (@ARGV < 1) {
+
+ my $modconf;
+ if (`uname -r` =~ /(\d+)\.(\d+)\.(\d+)/) {
+- if ($2 > 4) {
++ if (($2 > 4) || ($1 > 2)) {
+ if (-d "/etc/modprobe.d") {
+ $modconf = "/etc/modprobe.d/ndiswrapper.conf";
+ } else {
+--
+1.8.4
+
diff --git a/network/ndiswrapper-kernel/patches/0004-Support-3.10-kernel-and-older-versions.patch b/network/ndiswrapper-kernel/patches/0004-Support-3.10-kernel-and-older-versions.patch
new file mode 100644
index 000000000000..5471c2565037
--- /dev/null
+++ b/network/ndiswrapper-kernel/patches/0004-Support-3.10-kernel-and-older-versions.patch
@@ -0,0 +1,649 @@
+From 250a815b20c18719ae0c2858e56611de447accf8 Mon Sep 17 00:00:00 2001
+From: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+Date: Tue, 8 Oct 2013 21:00:15 +0300
+Subject: [PATCH 4/5] Support 3.10 kernel and older versions
+
+Taken from git://anonscm.debian.org/collab-maint/ndiswrapper.git
+debian/patches/update-for-linux-3.10.patch
+
+Original description header:
+
+Description: Patch for Linux 3.10
+ Based on the Ubuntu patch, with support for older kernels re-added.
+ .
+ ndiswrapper (1.58-1ubuntu1) saucy; urgency=low
+ .
+ * update-for-linux-3.10.patch: Fix build with 3.10 and later kernels
+ .
+ -- Seth Forshee <seth.forshee@canonical.com> Sun, 04 Aug 2013 11:41:02 +0100
+Origin: vendor, https://launchpadlibrarian.net/146718060/ndiswrapper_1.58-1_1.58-1ubuntu1.diff.gz
+Bug-Debian: http://bugs.debian.org/717152
+Author: Seth Forshee <seth.forshee@canonical.com>
+Author: Julian Andres Klode <jak@debian.org>
+
+Signed-off-by: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+---
+ driver/proc.c | 378 ++++++++++++++++++++++++++++--------------------------
+ driver/wrapndis.c | 2 +-
+ 2 files changed, 197 insertions(+), 183 deletions(-)
+
+diff --git a/driver/proc.c b/driver/proc.c
+index 60ed0e0..0a28e45 100644
+--- a/driver/proc.c
++++ b/driver/proc.c
+@@ -13,6 +13,7 @@
+ *
+ */
+ #include <linux/proc_fs.h>
++#include <linux/seq_file.h>
+ #include <linux/module.h>
+ #include <asm/uaccess.h>
+
+@@ -24,116 +25,127 @@
+
+ #define MAX_PROC_STR_LEN 32
+
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
++static inline void *PDE_DATA(const struct inode *inode)
++{
++ return PROC_I(inode)->pde->data;
++}
++
++void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
++{
++ de->uid = uid;
++ de->gid = gid;
++}
++#endif
++
+ static struct proc_dir_entry *wrap_procfs_entry;
+
+-static int procfs_read_ndis_stats(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int procfs_ndis_stats_show(struct seq_file *m, void *data)
+ {
+- char *p = page;
+ struct ndis_device *wnd = (struct ndis_device *)data;
+ struct ndis_wireless_stats stats;
+ NDIS_STATUS res;
+ ndis_rssi rssi;
+
+- if (off != 0) {
+- *eof = 1;
+- return 0;
+- }
+-
+ res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi));
+ if (!res)
+- p += sprintf(p, "signal_level=%d dBm\n", (s32)rssi);
++ seq_printf(m, "signal_level=%d dBm\n", (s32)rssi);
+
+ res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats));
+ if (!res) {
+
+- p += sprintf(p, "tx_frames=%llu\n", stats.tx_frag);
+- p += sprintf(p, "tx_multicast_frames=%llu\n",
+- stats.tx_multi_frag);
+- p += sprintf(p, "tx_failed=%llu\n", stats.failed);
+- p += sprintf(p, "tx_retry=%llu\n", stats.retry);
+- p += sprintf(p, "tx_multi_retry=%llu\n", stats.multi_retry);
+- p += sprintf(p, "tx_rtss_success=%llu\n", stats.rtss_succ);
+- p += sprintf(p, "tx_rtss_fail=%llu\n", stats.rtss_fail);
+- p += sprintf(p, "ack_fail=%llu\n", stats.ack_fail);
+- p += sprintf(p, "frame_duplicates=%llu\n", stats.frame_dup);
+- p += sprintf(p, "rx_frames=%llu\n", stats.rx_frag);
+- p += sprintf(p, "rx_multicast_frames=%llu\n",
+- stats.rx_multi_frag);
+- p += sprintf(p, "fcs_errors=%llu\n", stats.fcs_err);
++ seq_printf(m, "tx_frames=%llu\n", stats.tx_frag);
++ seq_printf(m, "tx_multicast_frames=%llu\n",
++ stats.tx_multi_frag);
++ seq_printf(m, "tx_failed=%llu\n", stats.failed);
++ seq_printf(m, "tx_retry=%llu\n", stats.retry);
++ seq_printf(m, "tx_multi_retry=%llu\n", stats.multi_retry);
++ seq_printf(m, "tx_rtss_success=%llu\n", stats.rtss_succ);
++ seq_printf(m, "tx_rtss_fail=%llu\n", stats.rtss_fail);
++ seq_printf(m, "ack_fail=%llu\n", stats.ack_fail);
++ seq_printf(m, "frame_duplicates=%llu\n", stats.frame_dup);
++ seq_printf(m, "rx_frames=%llu\n", stats.rx_frag);
++ seq_printf(m, "rx_multicast_frames=%llu\n",
++ stats.rx_multi_frag);
++ seq_printf(m, "fcs_errors=%llu\n", stats.fcs_err);
+ }
+
+- if (p - page > count) {
+- ERROR("wrote %td bytes (limit is %u)\n",
+- p - page, count);
+- *eof = 1;
+- }
++ return 0;
++}
+
+- return p - page;
++static int procfs_ndis_stats_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, procfs_ndis_stats_show, PDE_DATA(inode));
+ }
+
+-static int procfs_read_ndis_encr(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static const struct file_operations procfs_ndis_stats_fops = {
++ .open = procfs_ndis_stats_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int procfs_ndis_encr_show(struct seq_file *m, void *data)
+ {
+- char *p = page;
+ struct ndis_device *wnd = (struct ndis_device *)data;
+ int i, encr_status, auth_mode, infra_mode;
+ NDIS_STATUS res;
+ struct ndis_essid essid;
+ mac_address ap_address;
+
+- if (off != 0) {
+- *eof = 1;
+- return 0;
+- }
+-
+ res = mp_query(wnd, OID_802_11_BSSID,
+ &ap_address, sizeof(ap_address));
+ if (res)
+ memset(ap_address, 0, ETH_ALEN);
+- p += sprintf(p, "ap_address=%2.2X", ap_address[0]);
++ seq_printf(m, "ap_address=%2.2X", ap_address[0]);
+ for (i = 1; i < ETH_ALEN; i++)
+- p += sprintf(p, ":%2.2X", ap_address[i]);
+- p += sprintf(p, "\n");
++ seq_printf(m, ":%2.2X", ap_address[i]);
++ seq_printf(m, "\n");
+
+ res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid));
+ if (!res)
+- p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid);
++ seq_printf(m, "essid=%.*s\n", essid.length, essid.essid);
+
+ res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status);
+ if (!res) {
+ typeof(&wnd->encr_info.keys[0]) tx_key;
+- p += sprintf(p, "tx_key=%u\n", wnd->encr_info.tx_key_index);
+- p += sprintf(p, "key=");
++ seq_printf(m, "tx_key=%u\n", wnd->encr_info.tx_key_index);
++ seq_printf(m, "key=");
+ tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index];
+ if (tx_key->length > 0)
+ for (i = 0; i < tx_key->length; i++)
+- p += sprintf(p, "%2.2X", tx_key->key[i]);
++ seq_printf(m, "%2.2X", tx_key->key[i]);
+ else
+- p += sprintf(p, "off");
+- p += sprintf(p, "\n");
+- p += sprintf(p, "encr_mode=%d\n", encr_status);
++ seq_printf(m, "off");
++ seq_printf(m, "\n");
++ seq_printf(m, "encr_mode=%d\n", encr_status);
+ }
+ res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode);
+ if (!res)
+- p += sprintf(p, "auth_mode=%d\n", auth_mode);
++ seq_printf(m, "auth_mode=%d\n", auth_mode);
+ res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode);
+- p += sprintf(p, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ?
+- "adhoc" : (infra_mode == Ndis802_11Infrastructure) ?
+- "managed" : "auto");
+- if (p - page > count) {
+- WARNING("wrote %td bytes (limit is %u)",
+- p - page, count);
+- *eof = 1;
+- }
++ seq_printf(m, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ?
++ "adhoc" : (infra_mode == Ndis802_11Infrastructure) ?
++ "managed" : "auto");
+
+- return p - page;
++ return 0;
+ }
+
+-static int procfs_read_ndis_hw(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int procfs_ndis_encr_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, procfs_ndis_encr_show, PDE_DATA(inode));
++}
++
++static const struct file_operations procfs_ndis_encr_fops = {
++ .open = procfs_ndis_encr_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int procfs_hw_show(struct seq_file *m, void *data)
+ {
+- char *p = page;
+ struct ndis_device *wnd = (struct ndis_device *)data;
+ struct ndis_configuration config;
+ enum ndis_power power_mode;
+@@ -149,138 +161,134 @@ static int procfs_read_ndis_hw(char *page, char **start, off_t off,
+ char *hw_status[] = {"ready", "initializing", "resetting", "closing",
+ "not ready"};
+
+- if (off != 0) {
+- *eof = 1;
+- return 0;
+- }
+-
+ res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n);
+ if (res == NDIS_STATUS_SUCCESS && n >= 0 && n < ARRAY_SIZE(hw_status))
+- p += sprintf(p, "status=%s\n", hw_status[n]);
++ seq_printf(m, "status=%s\n", hw_status[n]);
+
+ res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac));
+ if (!res)
+- p += sprintf(p, "mac: " MACSTRSEP "\n", MAC2STR(mac));
++ seq_printf(m, "mac: " MACSTRSEP "\n", MAC2STR(mac));
+ res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config));
+ if (!res) {
+- p += sprintf(p, "beacon_period=%u msec\n",
+- config.beacon_period);
+- p += sprintf(p, "atim_window=%u msec\n", config.atim_window);
+- p += sprintf(p, "frequency=%u kHz\n", config.ds_config);
+- p += sprintf(p, "hop_pattern=%u\n",
+- config.fh_config.hop_pattern);
+- p += sprintf(p, "hop_set=%u\n",
+- config.fh_config.hop_set);
+- p += sprintf(p, "dwell_time=%u msec\n",
+- config.fh_config.dwell_time);
++ seq_printf(m, "beacon_period=%u msec\n",
++ config.beacon_period);
++ seq_printf(m, "atim_window=%u msec\n", config.atim_window);
++ seq_printf(m, "frequency=%u kHz\n", config.ds_config);
++ seq_printf(m, "hop_pattern=%u\n",
++ config.fh_config.hop_pattern);
++ seq_printf(m, "hop_set=%u\n",
++ config.fh_config.hop_set);
++ seq_printf(m, "dwell_time=%u msec\n",
++ config.fh_config.dwell_time);
+ }
+
+ res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL,
+ &tx_power, sizeof(tx_power));
+ if (!res)
+- p += sprintf(p, "tx_power=%u mW\n", tx_power);
++ seq_printf(m, "tx_power=%u mW\n", tx_power);
+
+ res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate));
+ if (!res)
+- p += sprintf(p, "bit_rate=%u kBps\n", (u32)bit_rate / 10);
++ seq_printf(m, "bit_rate=%u kBps\n", (u32)bit_rate / 10);
+
+ res = mp_query(wnd, OID_802_11_RTS_THRESHOLD,
+ &rts_threshold, sizeof(rts_threshold));
+ if (!res)
+- p += sprintf(p, "rts_threshold=%u bytes\n", rts_threshold);
++ seq_printf(m, "rts_threshold=%u bytes\n", rts_threshold);
+
+ res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,
+ &frag_threshold, sizeof(frag_threshold));
+ if (!res)
+- p += sprintf(p, "frag_threshold=%u bytes\n", frag_threshold);
++ seq_printf(m, "frag_threshold=%u bytes\n", frag_threshold);
+
+ res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode);
+ if (!res)
+- p += sprintf(p, "power_mode=%s\n",
+- (power_mode == NDIS_POWER_OFF) ? "always_on" :
+- (power_mode == NDIS_POWER_MAX) ?
+- "max_savings" : "min_savings");
++ seq_printf(m, "power_mode=%s\n",
++ (power_mode == NDIS_POWER_OFF) ? "always_on" :
++ (power_mode == NDIS_POWER_MAX) ?
++ "max_savings" : "min_savings");
+
+ res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS,
+ &antenna, sizeof(antenna));
+ if (!res)
+- p += sprintf(p, "num_antennas=%u\n", antenna);
++ seq_printf(m, "num_antennas=%u\n", antenna);
+
+ res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED,
+ &antenna, sizeof(antenna));
+ if (!res)
+- p += sprintf(p, "tx_antenna=%u\n", antenna);
++ seq_printf(m, "tx_antenna=%u\n", antenna);
+
+ res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED,
+ &antenna, sizeof(antenna));
+ if (!res)
+- p += sprintf(p, "rx_antenna=%u\n", antenna);
+-
+- p += sprintf(p, "encryption_modes=%s%s%s%s%s%s%s\n",
+- test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ?
+- "WEP" : "none",
+-
+- test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ?
+- "; TKIP with WPA" : "",
+- test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
+- ", WPA2" : "",
+- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
+- ", WPA2PSK" : "",
+-
+- test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ?
+- "; AES/CCMP with WPA" : "",
+- test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
+- ", WPA2" : "",
+- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
+- ", WPA2PSK" : "");
++ seq_printf(m, "rx_antenna=%u\n", antenna);
++
++ seq_printf(m, "encryption_modes=%s%s%s%s%s%s%s\n",
++ test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ?
++ "WEP" : "none",
++
++ test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ?
++ "; TKIP with WPA" : "",
++ test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
++ ", WPA2" : "",
++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
++ ", WPA2PSK" : "",
++
++ test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ?
++ "; AES/CCMP with WPA" : "",
++ test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
++ ", WPA2" : "",
++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
++ ", WPA2PSK" : "");
+
+ res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter);
+ if (!res) {
+ if (packet_filter != wnd->packet_filter)
+ WARNING("wrong packet_filter? 0x%08x, 0x%08x\n",
+ packet_filter, wnd->packet_filter);
+- p += sprintf(p, "packet_filter: 0x%08x\n", packet_filter);
+- }
+- if (p - page > count) {
+- WARNING("wrote %td bytes (limit is %u)",
+- p - page, count);
+- *eof = 1;
++ seq_printf(m, "packet_filter: 0x%08x\n", packet_filter);
+ }
+
+- return p - page;
++ return 0;
+ }
+
+-static int procfs_read_ndis_settings(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int procfs_hw_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, procfs_hw_show, PDE_DATA(inode));
++}
++
++static const struct file_operations procfs_hw_fops = {
++ .open = procfs_hw_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++};
++
++static int procfs_ndis_settings_show(struct seq_file *m, void *data)
+ {
+- char *p = page;
+ struct ndis_device *wnd = (struct ndis_device *)data;
+ struct wrap_device_setting *setting;
+
+- if (off != 0) {
+- *eof = 1;
+- return 0;
+- }
+-
+- p += sprintf(p, "hangcheck_interval=%d\n",
+- hangcheck_interval == 0 ?
+- (wnd->hangcheck_interval / HZ) : -1);
++ seq_printf(m, "hangcheck_interval=%d\n",
++ hangcheck_interval == 0 ?
++ (wnd->hangcheck_interval / HZ) : -1);
+
+ list_for_each_entry(setting, &wnd->wd->settings, list) {
+- p += sprintf(p, "%s=%s\n", setting->name, setting->value);
++ seq_printf(m, "%s=%s\n", setting->name, setting->value);
+ }
+
+ list_for_each_entry(setting, &wnd->wd->driver->settings, list) {
+- p += sprintf(p, "%s=%s\n", setting->name, setting->value);
++ seq_printf(m, "%s=%s\n", setting->name, setting->value);
+ }
+
+- return p - page;
++ return 0;
+ }
+
+-static int procfs_write_ndis_settings(struct file *file, const char __user *buf,
+- unsigned long count, void *data)
++static ssize_t procfs_write_ndis_settings(struct file *file,
++ const char __user *buf, size_t count,
++ loff_t *pos)
+ {
+- struct ndis_device *wnd = (struct ndis_device *)data;
++ struct ndis_device *wnd = PDE_DATA(file_inode(file));
+ char setting[MAX_PROC_STR_LEN], *p;
+ unsigned int i;
+ NDIS_STATUS res;
+@@ -380,6 +388,19 @@ static int procfs_write_ndis_settings(struct file *file, const char __user *buf,
+ return count;
+ }
+
++static int procfs_ndis_settings_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, procfs_ndis_settings_show, PDE_DATA(inode));
++}
++
++static const struct file_operations procfs_ndis_settings_fops = {
++ .open = procfs_ndis_settings_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++ .write = procfs_write_ndis_settings,
++};
++
+ int wrap_procfs_add_ndis_device(struct ndis_device *wnd)
+ {
+ struct proc_dir_entry *procfs_entry;
+@@ -388,7 +409,7 @@ int wrap_procfs_add_ndis_device(struct ndis_device *wnd)
+ return -ENOMEM;
+
+ if (wnd->procfs_iface) {
+- ERROR("%s already registered?", wnd->procfs_iface->name);
++ ERROR("%s already registered?", wnd->net_dev->name);
+ return -EINVAL;
+ }
+ wnd->procfs_iface = proc_mkdir(wnd->net_dev->name, wrap_procfs_entry);
+@@ -396,57 +417,47 @@ int wrap_procfs_add_ndis_device(struct ndis_device *wnd)
+ ERROR("couldn't create proc directory");
+ return -ENOMEM;
+ }
+- wnd->procfs_iface->uid = proc_uid;
+- wnd->procfs_iface->gid = proc_gid;
++ proc_set_user(wnd->procfs_iface, proc_uid, proc_gid);
+
+- procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP,
+- wnd->procfs_iface);
++ procfs_entry = proc_create_data("hw", S_IFREG | S_IRUSR | S_IRGRP,
++ wnd->procfs_iface, &procfs_hw_fops,
++ wnd);
+ if (procfs_entry == NULL) {
+ ERROR("couldn't create proc entry for 'hw'");
+ goto err_hw;
+ } else {
+- procfs_entry->uid = proc_uid;
+- procfs_entry->gid = proc_gid;
+- procfs_entry->data = wnd;
+- procfs_entry->read_proc = procfs_read_ndis_hw;
++ proc_set_user(procfs_entry, proc_uid, proc_gid);
+ }
+
+- procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP,
+- wnd->procfs_iface);
++ procfs_entry = proc_create_data("stats", S_IFREG | S_IRUSR | S_IRGRP,
++ wnd->procfs_iface,
++ &procfs_ndis_stats_fops, wnd);
+ if (procfs_entry == NULL) {
+ ERROR("couldn't create proc entry for 'stats'");
+ goto err_stats;
+ } else {
+- procfs_entry->uid = proc_uid;
+- procfs_entry->gid = proc_gid;
+- procfs_entry->data = wnd;
+- procfs_entry->read_proc = procfs_read_ndis_stats;
++ proc_set_user(procfs_entry, proc_uid, proc_gid);
+ }
+
+- procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP,
+- wnd->procfs_iface);
++ procfs_entry = proc_create_data("encr", S_IFREG | S_IRUSR | S_IRGRP,
++ wnd->procfs_iface,
++ &procfs_ndis_encr_fops, wnd);
+ if (procfs_entry == NULL) {
+ ERROR("couldn't create proc entry for 'encr'");
+ goto err_encr;
+ } else {
+- procfs_entry->uid = proc_uid;
+- procfs_entry->gid = proc_gid;
+- procfs_entry->data = wnd;
+- procfs_entry->read_proc = procfs_read_ndis_encr;
++ proc_set_user(procfs_entry, proc_uid, proc_gid);
+ }
+
+- procfs_entry = create_proc_entry("settings", S_IFREG |
+- S_IRUSR | S_IRGRP |
+- S_IWUSR | S_IWGRP, wnd->procfs_iface);
++ procfs_entry = proc_create_data("settings", S_IFREG |
++ S_IRUSR | S_IRGRP |
++ S_IWUSR | S_IWGRP, wnd->procfs_iface,
++ &procfs_ndis_settings_fops, wnd);
+ if (procfs_entry == NULL) {
+ ERROR("couldn't create proc entry for 'settings'");
+ goto err_settings;
+ } else {
+- procfs_entry->uid = proc_uid;
+- procfs_entry->gid = proc_gid;
+- procfs_entry->data = wnd;
+- procfs_entry->read_proc = procfs_read_ndis_settings;
+- procfs_entry->write_proc = procfs_write_ndis_settings;
++ proc_set_user(procfs_entry, proc_uid, proc_gid);
+ }
+ return 0;
+
+@@ -457,7 +468,7 @@ err_encr:
+ err_stats:
+ remove_proc_entry("hw", wnd->procfs_iface);
+ err_hw:
+- remove_proc_entry(wnd->procfs_iface->name, wrap_procfs_entry);
++ remove_proc_entry(wnd->net_dev->name, wrap_procfs_entry);
+ wnd->procfs_iface = NULL;
+ return -ENOMEM;
+ }
+@@ -473,32 +484,26 @@ void wrap_procfs_remove_ndis_device(struct ndis_device *wnd)
+ remove_proc_entry("encr", procfs_iface);
+ remove_proc_entry("settings", procfs_iface);
+ if (wrap_procfs_entry)
+- remove_proc_entry(procfs_iface->name, wrap_procfs_entry);
++ remove_proc_entry(wnd->net_dev->name, wrap_procfs_entry);
+ }
+
+-static int procfs_read_debug(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int procfs_debug_show(struct seq_file *m, void *data)
+ {
+- char *p = page;
+ #if ALLOC_DEBUG
+ enum alloc_type type;
+ #endif
+
+- if (off != 0) {
+- *eof = 1;
+- return 0;
+- }
+- p += sprintf(p, "%d\n", debug);
++ seq_printf(m, "%d\n", debug);
+ #if ALLOC_DEBUG
+ for (type = 0; type < ALLOC_TYPE_MAX; type++)
+- p += sprintf(p, "total size of allocations in %s: %d\n",
+- alloc_type_name[type], alloc_size(type));
++ seq_printf(m, "total size of allocations in %s: %d\n",
++ alloc_type_name[type], alloc_size(type));
+ #endif
+- return p - page;
++ return 0;
+ }
+
+-static int procfs_write_debug(struct file *file, const char __user *buf,
+- unsigned long count, void *data)
++static ssize_t procfs_write_debug(struct file *file, const char __user *buf,
++ size_t count, loff_t *pos)
+ {
+ int i;
+ char setting[MAX_PROC_STR_LEN], *p;
+@@ -524,6 +529,19 @@ static int procfs_write_debug(struct file *file, const char __user *buf,
+ return count;
+ }
+
++static int procfs_debug_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, procfs_debug_show, PDE_DATA(inode));
++}
++
++static const struct file_operations procfs_debug_fops = {
++ .open = procfs_debug_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
++ .write = procfs_write_debug,
++};
++
+ int wrap_procfs_init(void)
+ {
+ struct proc_dir_entry *procfs_entry;
+@@ -533,19 +551,15 @@ int wrap_procfs_init(void)
+ ERROR("couldn't create procfs directory");
+ return -ENOMEM;
+ }
+- wrap_procfs_entry->uid = proc_uid;
+- wrap_procfs_entry->gid = proc_gid;
++ proc_set_user(wrap_procfs_entry, proc_uid, proc_gid);
+
+- procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP,
+- wrap_procfs_entry);
++ procfs_entry = proc_create("debug", S_IFREG | S_IRUSR | S_IRGRP,
++ wrap_procfs_entry, &procfs_debug_fops);
+ if (procfs_entry == NULL) {
+ ERROR("couldn't create proc entry for 'debug'");
+ return -ENOMEM;
+ } else {
+- procfs_entry->uid = proc_uid;
+- procfs_entry->gid = proc_gid;
+- procfs_entry->read_proc = procfs_read_debug;
+- procfs_entry->write_proc = procfs_write_debug;
++ proc_set_user(procfs_entry, proc_uid, proc_gid);
+ }
+ return 0;
+ }
+diff --git a/driver/wrapndis.c b/driver/wrapndis.c
+index 7bb9568..98dc3a1 100644
+--- a/driver/wrapndis.c
++++ b/driver/wrapndis.c
+@@ -1771,7 +1771,7 @@ static int notifier_event(struct notifier_block *notifier, unsigned long event,
+ if (likely(wnd->procfs_iface)) {
+ printk(KERN_INFO "%s: changing interface name from "
+ "'%s' to '%s'\n", DRIVER_NAME,
+- wnd->procfs_iface->name, net_dev->name);
++ wnd->net_dev->name, net_dev->name);
+ wrap_procfs_remove_ndis_device(wnd);
+ wrap_procfs_add_ndis_device(wnd);
+ }
+--
+1.8.4
+
diff --git a/network/ndiswrapper-kernel/patches/0005-Fix-compilation-on-pre-3.9.patch b/network/ndiswrapper-kernel/patches/0005-Fix-compilation-on-pre-3.9.patch
new file mode 100644
index 000000000000..8db804b6e1ae
--- /dev/null
+++ b/network/ndiswrapper-kernel/patches/0005-Fix-compilation-on-pre-3.9.patch
@@ -0,0 +1,30 @@
+From b0d9f0c79b1dbcb42a5661e96a364519ac5faded Mon Sep 17 00:00:00 2001
+From: Andrey Utkin <andrey.krieger.utkin@gmail.com>
+Date: Tue, 8 Oct 2013 23:09:52 +0300
+Subject: [PATCH 5/5] Fix compilation on pre-3.9
+
+Provide file_inode().
+---
+ driver/proc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/driver/proc.c b/driver/proc.c
+index 0a28e45..367ff97 100644
+--- a/driver/proc.c
++++ b/driver/proc.c
+@@ -25,6 +25,12 @@
+
+ #define MAX_PROC_STR_LEN 32
+
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
++static inline struct inode *file_inode(struct file *f)
++{
++ return f->f_path.dentry->d_inode;
++}
++#endif
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+ static inline void *PDE_DATA(const struct inode *inode)
+--
+1.8.4
+