aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--driver-core.current/drivers-base-cpu.c-fix-the-output-from-sys-devices-system-cpu-offline.patch1
-rw-r--r--series5
-rw-r--r--staging.current/staging-batman-adv-don-t-have-interrupts-disabled-while-sending.patch456
-rw-r--r--staging.current/staging-batman-adv-fix-vis-output-bug-for-secondary-interfaces.patch226
-rw-r--r--staging.current/staging-batman-adv-fixing-wrap-around-bug-in-vis.patch61
5 files changed, 748 insertions, 1 deletions
diff --git a/driver-core.current/drivers-base-cpu.c-fix-the-output-from-sys-devices-system-cpu-offline.patch b/driver-core.current/drivers-base-cpu.c-fix-the-output-from-sys-devices-system-cpu-offline.patch
index c4da06554c355c..f34fcf2f9095a0 100644
--- a/driver-core.current/drivers-base-cpu.c-fix-the-output-from-sys-devices-system-cpu-offline.patch
+++ b/driver-core.current/drivers-base-cpu.c-fix-the-output-from-sys-devices-system-cpu-offline.patch
@@ -16,6 +16,7 @@ Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
diff --git a/series b/series
index 19b03e5f1c74a3..f316e2633a0040 100644
--- a/series
+++ b/series
@@ -79,6 +79,9 @@ staging.current/staging-rtl8192su-add-support-for-belkin-f5d8053-v6.patch
staging.current/staging-fix-dt3155-build.patch
staging.current/staging-rt2860-add-belkin-f5d8055-wireless-n-usb-dongle-device-id.patch
staging.current/staging-iio-fix-up-the-iio_get_new_idr_val-comment.patch
+staging.current/staging-batman-adv-don-t-have-interrupts-disabled-while-sending.patch
+staging.current/staging-batman-adv-fix-vis-output-bug-for-secondary-interfaces.patch
+staging.current/staging-batman-adv-fixing-wrap-around-bug-in-vis.patch
#####################################################################
@@ -187,5 +190,5 @@ usb/usb-gadget-add-hid-gadget-driver.patch
#######################################
-# new stuff
+# new stuff is in the staging-next git tree on git.kernel.org
diff --git a/staging.current/staging-batman-adv-don-t-have-interrupts-disabled-while-sending.patch b/staging.current/staging-batman-adv-don-t-have-interrupts-disabled-while-sending.patch
new file mode 100644
index 00000000000000..5ee5c462f09684
--- /dev/null
+++ b/staging.current/staging-batman-adv-don-t-have-interrupts-disabled-while-sending.patch
@@ -0,0 +1,456 @@
+From andrew@lunn.ch Tue Apr 27 14:51:18 2010
+From: Andrew Lunn <andrew@lunn.ch>
+Date: Mon, 22 Mar 2010 22:46:13 +0100
+Subject: Staging: batman-adv: don't have interrupts disabled while sending.
+To: gregkh@suse.de
+Cc: b.a.t.m.a.n@lists.open-mesh.net, Andrew Lunn <andrew@lunn.ch>, Marek Lindner <lindner_marek@yahoo.de>, Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Message-ID: <1269294375-11043-2-git-send-email-andrew@lunn.ch>
+
+
+send_vis_packets() would disable interrupts before calling
+dev_queue_xmit() which resulting in a backtrace in local_bh_enable().
+Fix this by using kref on the vis_info object so that we can call
+send_vis_packets() without holding vis_hash_lock. vis_hash_lock also
+used to protect recv_list, so we now need a new lock to protect that
+instead of vis_hash_lock.
+
+Also a few checkpatch cleanups.
+
+Reported-by: Linus Lüssing <linus.luessing@web.de>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
+Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/vis.c | 198 +++++++++++++++++++++++++++------------
+ drivers/staging/batman-adv/vis.h | 1
+ 2 files changed, 139 insertions(+), 60 deletions(-)
+
+--- a/drivers/staging/batman-adv/vis.c
++++ b/drivers/staging/batman-adv/vis.c
+@@ -29,22 +29,26 @@
+
+ struct hashtable_t *vis_hash;
+ DEFINE_SPINLOCK(vis_hash_lock);
++static DEFINE_SPINLOCK(recv_list_lock);
+ static struct vis_info *my_vis_info;
+ static struct list_head send_list; /* always locked with vis_hash_lock */
+
+ static void start_vis_timer(void);
+
+ /* free the info */
+-static void free_info(void *data)
++static void free_info(struct kref *ref)
+ {
+- struct vis_info *info = data;
++ struct vis_info *info = container_of(ref, struct vis_info, refcount);
+ struct recvlist_node *entry, *tmp;
++ unsigned long flags;
+
+ list_del_init(&info->send_list);
++ spin_lock_irqsave(&recv_list_lock, flags);
+ list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ kfree(info);
+ }
+
+@@ -142,36 +146,65 @@ void proc_vis_read_entry(struct seq_file
+ }
+ }
+
++/* add the info packet to the send list, if it was not
++ * already linked in. */
++static void send_list_add(struct vis_info *info)
++{
++ if (list_empty(&info->send_list)) {
++ kref_get(&info->refcount);
++ list_add_tail(&info->send_list, &send_list);
++ }
++}
++
++/* delete the info packet from the send list, if it was
++ * linked in. */
++static void send_list_del(struct vis_info *info)
++{
++ if (!list_empty(&info->send_list)) {
++ list_del_init(&info->send_list);
++ kref_put(&info->refcount, free_info);
++ }
++}
++
+ /* tries to add one entry to the receive list. */
+ static void recv_list_add(struct list_head *recv_list, char *mac)
+ {
+ struct recvlist_node *entry;
++ unsigned long flags;
++
+ entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
+ if (!entry)
+ return;
+
+ memcpy(entry->mac, mac, ETH_ALEN);
++ spin_lock_irqsave(&recv_list_lock, flags);
+ list_add_tail(&entry->list, recv_list);
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ }
+
+ /* returns 1 if this mac is in the recv_list */
+ static int recv_list_is_in(struct list_head *recv_list, char *mac)
+ {
+ struct recvlist_node *entry;
++ unsigned long flags;
+
++ spin_lock_irqsave(&recv_list_lock, flags);
+ list_for_each_entry(entry, recv_list, list) {
+- if (memcmp(entry->mac, mac, ETH_ALEN) == 0)
++ if (memcmp(entry->mac, mac, ETH_ALEN) == 0) {
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ return 1;
++ }
+ }
+-
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ return 0;
+ }
+
+ /* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
+- * broken.. ). vis hash must be locked outside. is_new is set when the packet
++ * broken.. ). vis hash must be locked outside. is_new is set when the packet
+ * is newer than old entries in the hash. */
+ static struct vis_info *add_packet(struct vis_packet *vis_packet,
+- int vis_info_len, int *is_new)
++ int vis_info_len, int *is_new,
++ int make_broadcast)
+ {
+ struct vis_info *info, *old_info;
+ struct vis_info search_elem;
+@@ -198,13 +231,15 @@ static struct vis_info *add_packet(struc
+ }
+ /* remove old entry */
+ hash_remove(vis_hash, old_info);
+- free_info(old_info);
++ send_list_del(old_info);
++ kref_put(&old_info->refcount, free_info);
+ }
+
+ info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC);
+ if (info == NULL)
+ return NULL;
+
++ kref_init(&info->refcount);
+ INIT_LIST_HEAD(&info->send_list);
+ INIT_LIST_HEAD(&info->recv_list);
+ info->first_seen = jiffies;
+@@ -214,16 +249,21 @@ static struct vis_info *add_packet(struc
+ /* initialize and add new packet. */
+ *is_new = 1;
+
++ /* Make it a broadcast packet, if required */
++ if (make_broadcast)
++ memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
++
+ /* repair if entries is longer than packet. */
+ if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
+- info->packet.entries = vis_info_len / sizeof(struct vis_info_entry);
++ info->packet.entries = vis_info_len /
++ sizeof(struct vis_info_entry);
+
+ recv_list_add(&info->recv_list, info->packet.sender_orig);
+
+ /* try to add it */
+ if (hash_add(vis_hash, info) < 0) {
+ /* did not work (for some reason) */
+- free_info(info);
++ kref_put(&old_info->refcount, free_info);
+ info = NULL;
+ }
+
+@@ -234,22 +274,21 @@ static struct vis_info *add_packet(struc
+ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
+ {
+ struct vis_info *info;
+- int is_new;
++ int is_new, make_broadcast;
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
+
++ make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
++
+ spin_lock_irqsave(&vis_hash_lock, flags);
+- info = add_packet(vis_packet, vis_info_len, &is_new);
++ info = add_packet(vis_packet, vis_info_len, &is_new, make_broadcast);
+ if (info == NULL)
+ goto end;
+
+ /* only if we are server ourselves and packet is newer than the one in
+ * hash.*/
+- if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
+- memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+- if (list_empty(&info->send_list))
+- list_add_tail(&info->send_list, &send_list);
+- }
++ if (vis_server == VIS_TYPE_SERVER_SYNC && is_new)
++ send_list_add(info);
+ end:
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+ }
+@@ -262,31 +301,32 @@ void receive_client_update_packet(struct
+ int is_new;
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
++ int are_target = 0;
+
+ /* clients shall not broadcast. */
+ if (is_bcast(vis_packet->target_orig))
+ return;
+
++ /* Are we the target for this VIS packet? */
++ if (vis_server == VIS_TYPE_SERVER_SYNC &&
++ is_my_mac(vis_packet->target_orig))
++ are_target = 1;
++
+ spin_lock_irqsave(&vis_hash_lock, flags);
+- info = add_packet(vis_packet, vis_info_len, &is_new);
++ info = add_packet(vis_packet, vis_info_len, &is_new, are_target);
+ if (info == NULL)
+ goto end;
+ /* note that outdated packets will be dropped at this point. */
+
+
+ /* send only if we're the target server or ... */
+- if (vis_server == VIS_TYPE_SERVER_SYNC &&
+- is_my_mac(info->packet.target_orig) &&
+- is_new) {
++ if (are_target && is_new) {
+ info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
+- memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+- if (list_empty(&info->send_list))
+- list_add_tail(&info->send_list, &send_list);
++ send_list_add(info);
+
+ /* ... we're not the recipient (and thus need to forward). */
+ } else if (!is_my_mac(info->packet.target_orig)) {
+- if (list_empty(&info->send_list))
+- list_add_tail(&info->send_list, &send_list);
++ send_list_add(info);
+ }
+ end:
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+@@ -361,14 +401,17 @@ static int generate_vis_packet(void)
+ while (hash_iterate(orig_hash, &hashit_global)) {
+ orig_node = hashit_global.bucket->data;
+ if (orig_node->router != NULL
+- && compare_orig(orig_node->router->addr, orig_node->orig)
++ && compare_orig(orig_node->router->addr,
++ orig_node->orig)
+ && orig_node->batman_if
+ && (orig_node->batman_if->if_active == IF_ACTIVE)
+ && orig_node->router->tq_avg > 0) {
+
+ /* fill one entry into buffer. */
+ entry = &entry_array[info->packet.entries];
+- memcpy(entry->src, orig_node->batman_if->net_dev->dev_addr, ETH_ALEN);
++ memcpy(entry->src,
++ orig_node->batman_if->net_dev->dev_addr,
++ ETH_ALEN);
+ memcpy(entry->dest, orig_node->orig, ETH_ALEN);
+ entry->quality = orig_node->router->tq_avg;
+ info->packet.entries++;
+@@ -400,6 +443,8 @@ static int generate_vis_packet(void)
+ return 0;
+ }
+
++/* free old vis packets. Must be called with this vis_hash_lock
++ * held */
+ static void purge_vis_packets(void)
+ {
+ HASHIT(hashit);
+@@ -412,7 +457,8 @@ static void purge_vis_packets(void)
+ if (time_after(jiffies,
+ info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
+ hash_remove_bucket(vis_hash, &hashit);
+- free_info(info);
++ send_list_del(info);
++ kref_put(&info->refcount, free_info);
+ }
+ }
+ }
+@@ -422,6 +468,8 @@ static void broadcast_vis_packet(struct
+ HASHIT(hashit);
+ struct orig_node *orig_node;
+ unsigned long flags;
++ struct batman_if *batman_if;
++ uint8_t dstaddr[ETH_ALEN];
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+
+@@ -430,45 +478,56 @@ static void broadcast_vis_packet(struct
+ orig_node = hashit.bucket->data;
+
+ /* if it's a vis server and reachable, send it. */
+- if (orig_node &&
+- (orig_node->flags & VIS_SERVER) &&
+- orig_node->batman_if &&
+- orig_node->router) {
++ if ((!orig_node) || (!orig_node->batman_if) ||
++ (!orig_node->router))
++ continue;
++ if (!(orig_node->flags & VIS_SERVER))
++ continue;
++ /* don't send it if we already received the packet from
++ * this node. */
++ if (recv_list_is_in(&info->recv_list, orig_node->orig))
++ continue;
++
++ memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN);
++ batman_if = orig_node->batman_if;
++ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
++ spin_unlock_irqrestore(&orig_hash_lock, flags);
++
++ send_raw_packet((unsigned char *)&info->packet,
++ packet_length, batman_if, dstaddr);
++
++ spin_lock_irqsave(&orig_hash_lock, flags);
+
+- /* don't send it if we already received the packet from
+- * this node. */
+- if (recv_list_is_in(&info->recv_list, orig_node->orig))
+- continue;
+-
+- memcpy(info->packet.target_orig,
+- orig_node->orig, ETH_ALEN);
+-
+- send_raw_packet((unsigned char *) &info->packet,
+- packet_length,
+- orig_node->batman_if,
+- orig_node->router->addr);
+- }
+ }
+- memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
++ memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+ }
+
+ static void unicast_vis_packet(struct vis_info *info, int packet_length)
+ {
+ struct orig_node *orig_node;
+ unsigned long flags;
++ struct batman_if *batman_if;
++ uint8_t dstaddr[ETH_ALEN];
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(orig_hash, info->packet.target_orig));
+
+- if ((orig_node != NULL) &&
+- (orig_node->batman_if != NULL) &&
+- (orig_node->router != NULL)) {
+- send_raw_packet((unsigned char *) &info->packet, packet_length,
+- orig_node->batman_if,
+- orig_node->router->addr);
+- }
++ if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router))
++ goto out;
++
++ /* don't lock while sending the packets ... we therefore
++ * copy the required data before sending */
++ batman_if = orig_node->batman_if;
++ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
++ spin_unlock_irqrestore(&orig_hash_lock, flags);
++
++ send_raw_packet((unsigned char *)&info->packet,
++ packet_length, batman_if, dstaddr);
++ return;
++
++out:
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+ }
+
+@@ -502,15 +561,24 @@ static void send_vis_packets(struct work
+ unsigned long flags;
+
+ spin_lock_irqsave(&vis_hash_lock, flags);
++
+ purge_vis_packets();
+
+- if (generate_vis_packet() == 0)
++ if (generate_vis_packet() == 0) {
+ /* schedule if generation was successful */
+- list_add_tail(&my_vis_info->send_list, &send_list);
++ send_list_add(my_vis_info);
++ }
+
+ list_for_each_entry_safe(info, temp, &send_list, send_list) {
+- list_del_init(&info->send_list);
++
++ kref_get(&info->refcount);
++ spin_unlock_irqrestore(&vis_hash_lock, flags);
++
+ send_vis_packet(info);
++
++ spin_lock_irqsave(&vis_hash_lock, flags);
++ send_list_del(info);
++ kref_put(&info->refcount, free_info);
+ }
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+ start_vis_timer();
+@@ -543,6 +611,7 @@ int vis_init(void)
+ my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
+ INIT_LIST_HEAD(&my_vis_info->recv_list);
+ INIT_LIST_HEAD(&my_vis_info->send_list);
++ kref_init(&my_vis_info->refcount);
+ my_vis_info->packet.version = COMPAT_VERSION;
+ my_vis_info->packet.packet_type = BAT_VIS;
+ my_vis_info->packet.ttl = TTL;
+@@ -556,9 +625,9 @@ int vis_init(void)
+
+ if (hash_add(vis_hash, my_vis_info) < 0) {
+ printk(KERN_ERR
+- "batman-adv:Can't add own vis packet into hash\n");
+- free_info(my_vis_info); /* not in hash, need to remove it
+- * manually. */
++ "batman-adv:Can't add own vis packet into hash\n");
++ /* not in hash, need to remove it manually. */
++ kref_put(&my_vis_info->refcount, free_info);
+ goto err;
+ }
+
+@@ -572,6 +641,15 @@ err:
+ return 0;
+ }
+
++/* Decrease the reference count on a hash item info */
++static void free_info_ref(void *data)
++{
++ struct vis_info *info = data;
++
++ send_list_del(info);
++ kref_put(&info->refcount, free_info);
++}
++
+ /* shutdown vis-server */
+ void vis_quit(void)
+ {
+@@ -583,7 +661,7 @@ void vis_quit(void)
+
+ spin_lock_irqsave(&vis_hash_lock, flags);
+ /* properly remove, kill timers ... */
+- hash_delete(vis_hash, free_info);
++ hash_delete(vis_hash, free_info_ref);
+ vis_hash = NULL;
+ my_vis_info = NULL;
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+--- a/drivers/staging/batman-adv/vis.h
++++ b/drivers/staging/batman-adv/vis.h
+@@ -29,6 +29,7 @@ struct vis_info {
+ /* list of server-neighbors we received a vis-packet
+ * from. we should not reply to them. */
+ struct list_head send_list;
++ struct kref refcount;
+ /* this packet might be part of the vis send queue. */
+ struct vis_packet packet;
+ /* vis_info may follow here*/
diff --git a/staging.current/staging-batman-adv-fix-vis-output-bug-for-secondary-interfaces.patch b/staging.current/staging-batman-adv-fix-vis-output-bug-for-secondary-interfaces.patch
new file mode 100644
index 00000000000000..3835e96c810c21
--- /dev/null
+++ b/staging.current/staging-batman-adv-fix-vis-output-bug-for-secondary-interfaces.patch
@@ -0,0 +1,226 @@
+From andrew@lunn.ch Tue Apr 27 14:51:34 2010
+From: Linus Lüssing <linus.luessing@web.de>
+Date: Mon, 22 Mar 2010 22:46:14 +0100
+Subject: Staging: batman-adv: Fix VIS output bug for secondary interfaces
+To: gregkh@suse.de
+Cc: b.a.t.m.a.n@lists.open-mesh.net, Linus Luessing <linus.luessing@web.de>, Andrew Lunn <andrew@lunn.ch>
+Message-ID: <1269294375-11043-3-git-send-email-andrew@lunn.ch>
+
+
+From: Linus Lüssing <linus.luessing@web.de>
+
+TQ and HNA records for originators on secondary interfaces were
+wrongly being included on the primary interface. Ensure we output a
+line for each source interface on every node, so we correctly separate
+primary and secondary interface records.
+
+Signed-off-by: Linus Lüssing <linus.luessing@web.de>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/proc.c | 51 ++++++++++++++++++++++++++------------
+ drivers/staging/batman-adv/vis.c | 25 ++++++------------
+ drivers/staging/batman-adv/vis.h | 7 +++--
+ 3 files changed, 49 insertions(+), 34 deletions(-)
+
+--- a/drivers/staging/batman-adv/proc.c
++++ b/drivers/staging/batman-adv/proc.c
+@@ -41,7 +41,7 @@ static int proc_interfaces_read(struct s
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+- seq_printf(seq, "[%8s] %s %s \n",
++ seq_printf(seq, "[%8s] %s %s\n",
+ (batman_if->if_active == IF_ACTIVE ?
+ "active" : "inactive"),
+ batman_if->dev,
+@@ -188,18 +188,18 @@ static int proc_originators_read(struct
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
++ seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
+ goto end;
+ }
+
+ if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - primary interface not active \n");
++ seq_printf(seq, "BATMAN disabled - primary interface not active\n");
+ goto end;
+ }
+
+ seq_printf(seq,
+- " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n",
++ " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s]\n",
+ "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
+ "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
+ ((struct batman_if *)if_list.next)->dev,
+@@ -240,7 +240,7 @@ static int proc_originators_read(struct
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ if (batman_count == 0)
+- seq_printf(seq, "No batman nodes in range ... \n");
++ seq_printf(seq, "No batman nodes in range ...\n");
+
+ end:
+ return 0;
+@@ -262,7 +262,7 @@ static int proc_transt_local_read(struct
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
++ seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
+ goto end;
+ }
+
+@@ -294,7 +294,7 @@ static int proc_transt_global_read(struc
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
++ seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
+ goto end;
+ }
+ rcu_read_unlock();
+@@ -350,9 +350,9 @@ static int proc_vis_srv_read(struct seq_
+ {
+ int vis_server = atomic_read(&vis_mode);
+
+- seq_printf(seq, "[%c] client mode (server disabled) \n",
++ seq_printf(seq, "[%c] client mode (server disabled)\n",
+ (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
+- seq_printf(seq, "[%c] server mode (server enabled) \n",
++ seq_printf(seq, "[%c] server mode (server enabled)\n",
+ (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
+
+ return 0;
+@@ -369,6 +369,8 @@ static int proc_vis_data_read(struct seq
+ struct vis_info *info;
+ struct vis_info_entry *entries;
+ HLIST_HEAD(vis_if_list);
++ struct if_list_entry *entry;
++ struct hlist_node *pos, *n;
+ int i;
+ char tmp_addr_str[ETH_STR_LEN];
+ unsigned long flags;
+@@ -387,17 +389,34 @@ static int proc_vis_data_read(struct seq
+ info = hashit.bucket->data;
+ entries = (struct vis_info_entry *)
+ ((char *)info + sizeof(struct vis_info));
+- addr_to_string(tmp_addr_str, info->packet.vis_orig);
+- seq_printf(seq, "%s,", tmp_addr_str);
+
+ for (i = 0; i < info->packet.entries; i++) {
+- proc_vis_read_entry(seq, &entries[i], &vis_if_list,
+- info->packet.vis_orig);
++ if (entries[i].quality == 0)
++ continue;
++ proc_vis_insert_interface(entries[i].src, &vis_if_list,
++ compare_orig(entries[i].src,
++ info->packet.vis_orig));
+ }
+
+- /* add primary/secondary records */
+- proc_vis_read_prim_sec(seq, &vis_if_list);
+- seq_printf(seq, "\n");
++ hlist_for_each_entry(entry, pos, &vis_if_list, list) {
++ addr_to_string(tmp_addr_str, entry->addr);
++ seq_printf(seq, "%s,", tmp_addr_str);
++
++ for (i = 0; i < info->packet.entries; i++)
++ proc_vis_read_entry(seq, &entries[i],
++ entry->addr, entry->primary);
++
++ /* add primary/secondary records */
++ if (compare_orig(entry->addr, info->packet.vis_orig))
++ proc_vis_read_prim_sec(seq, &vis_if_list);
++
++ seq_printf(seq, "\n");
++ }
++
++ hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
++ hlist_del(&entry->list);
++ kfree(entry);
++ }
+ }
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+
+--- a/drivers/staging/batman-adv/vis.c
++++ b/drivers/staging/batman-adv/vis.c
+@@ -86,7 +86,7 @@ static int vis_info_choose(void *data, i
+
+ /* insert interface to the list of interfaces of one originator, if it
+ * does not already exist in the list */
+-static void proc_vis_insert_interface(const uint8_t *interface,
++void proc_vis_insert_interface(const uint8_t *interface,
+ struct hlist_head *if_list,
+ bool primary)
+ {
+@@ -111,39 +111,32 @@ void proc_vis_read_prim_sec(struct seq_f
+ struct hlist_head *if_list)
+ {
+ struct if_list_entry *entry;
+- struct hlist_node *pos, *n;
++ struct hlist_node *pos;
+ char tmp_addr_str[ETH_STR_LEN];
+
+- hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
+- if (entry->primary) {
++ hlist_for_each_entry(entry, pos, if_list, list) {
++ if (entry->primary)
+ seq_printf(seq, "PRIMARY, ");
+- } else {
++ else {
+ addr_to_string(tmp_addr_str, entry->addr);
+ seq_printf(seq, "SEC %s, ", tmp_addr_str);
+ }
+-
+- hlist_del(&entry->list);
+- kfree(entry);
+ }
+ }
+
+ /* read an entry */
+ void proc_vis_read_entry(struct seq_file *seq,
+ struct vis_info_entry *entry,
+- struct hlist_head *if_list,
+- uint8_t *vis_orig)
++ uint8_t *src,
++ bool primary)
+ {
+ char to[40];
+
+ addr_to_string(to, entry->dest);
+- if (entry->quality == 0) {
+- proc_vis_insert_interface(vis_orig, if_list, true);
++ if (primary && entry->quality == 0)
+ seq_printf(seq, "HNA %s, ", to);
+- } else {
+- proc_vis_insert_interface(entry->src, if_list,
+- compare_orig(entry->src, vis_orig));
++ else if (compare_orig(entry->src, src))
+ seq_printf(seq, "TQ %s %d, ", to, entry->quality);
+- }
+ }
+
+ /* add the info packet to the send list, if it was not
+--- a/drivers/staging/batman-adv/vis.h
++++ b/drivers/staging/batman-adv/vis.h
+@@ -49,10 +49,13 @@ struct recvlist_node {
+ extern struct hashtable_t *vis_hash;
+ extern spinlock_t vis_hash_lock;
+
++void proc_vis_insert_interface(const uint8_t *interface,
++ struct hlist_head *if_list,
++ bool primary);
+ void proc_vis_read_entry(struct seq_file *seq,
+ struct vis_info_entry *entry,
+- struct hlist_head *if_list,
+- uint8_t *vis_orig);
++ uint8_t *src,
++ bool primary);
+ void proc_vis_read_prim_sec(struct seq_file *seq,
+ struct hlist_head *if_list);
+ void receive_server_sync_packet(struct vis_packet *vis_packet,
diff --git a/staging.current/staging-batman-adv-fixing-wrap-around-bug-in-vis.patch b/staging.current/staging-batman-adv-fixing-wrap-around-bug-in-vis.patch
new file mode 100644
index 00000000000000..b71ee4697fb494
--- /dev/null
+++ b/staging.current/staging-batman-adv-fixing-wrap-around-bug-in-vis.patch
@@ -0,0 +1,61 @@
+From andrew@lunn.ch Tue Apr 27 14:51:50 2010
+From: Linus L�ssing <linus.luessing@web.de>
+Date: Mon, 22 Mar 2010 22:46:15 +0100
+Subject: Staging: batman-adv: Fixing wrap-around bug in vis
+To: gregkh@suse.de
+Cc: b.a.t.m.a.n@lists.open-mesh.net, Linus L�ssing <linus.luessing@web.de>, Sven Eckelmann <sven.eckelmann@gmx.de>, Andrew Lunn <andrew@lunn.ch>
+Message-ID: <1269294375-11043-4-git-send-email-andrew@lunn.ch>
+
+
+From: Linus L�ssing <linus.luessing@web.de>
+
+When the seqno for a vis packet had a wrap around from i.e. 255 to 0,
+add_packet() would falsely claim the older packet with the seqno 255 as
+newer as the one with the seqno of 0 and would therefore ignore the new
+packet. This happens with all following vis packets until the old vis
+packet expires after 180 seconds timeout. This patch fixes this issue
+and gets rid of these highly undesired 3min. breaks for the vis-server.
+
+Signed-off-by: Linus L�ssing <linus.luessing@web.de>
+Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/vis.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/batman-adv/vis.c
++++ b/drivers/staging/batman-adv/vis.c
+@@ -27,6 +27,22 @@
+ #include "hard-interface.h"
+ #include "hash.h"
+
++/* Returns the smallest signed integer in two's complement with the sizeof x */
++#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
++
++/* Checks if a sequence number x is a predecessor/successor of y.
++ they handle overflows/underflows and can correctly check for a
++ predecessor/successor unless the variable sequence number has grown by
++ more then 2**(bitwidth(x)-1)-1.
++ This means that for a uint8_t with the maximum value 255, it would think:
++ * when adding nothing - it is neither a predecessor nor a successor
++ * before adding more than 127 to the starting value - it is a predecessor,
++ * when adding 128 - it is neither a predecessor nor a successor,
++ * after adding more than 127 to the starting value - it is a successor */
++#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
++ _dummy > smallest_signed_int(_dummy); })
++#define seq_after(x, y) seq_before(y, x)
++
+ struct hashtable_t *vis_hash;
+ DEFINE_SPINLOCK(vis_hash_lock);
+ static DEFINE_SPINLOCK(recv_list_lock);
+@@ -212,7 +228,7 @@ static struct vis_info *add_packet(struc
+ old_info = hash_find(vis_hash, &search_elem);
+
+ if (old_info != NULL) {
+- if (vis_packet->seqno - old_info->packet.seqno <= 0) {
++ if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) {
+ if (old_info->packet.seqno == vis_packet->seqno) {
+ recv_list_add(&old_info->recv_list,
+ vis_packet->sender_orig);