瀏覽代碼

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (524 commits)
  Staging: wlan-ng: Update prism2_set_tx_power() to use mBm
  Staging: ti-st: update TODO
  Staging: wlags49_h2: use common PCI_VENDOR/DEVICE_ID name format
  Staging: comedi : fix brace coding style issue in wwrap.c
  Staging: quatech_usb2: remove unused qt2_box_flush function
  Staging: slicoss: Remove net_device_stats from the driver's private
  staging: rtl8192su: check whether requests succeeded
  staging: panel: fix error path
  staging: otus: check kmalloc() return value
  staging: octeon: check request_irq() return value
  Staging: wlan-ng: remove typedef in p80211hdr.h
  Staging: wlan-ng: fix checkpatch issues in headers.
  Staging: wlan-ng: remove typedef in p80211ioctl.h
  Staging: wlan-ng: fix style issues in p80211conv.h
  Staging: wlan-ng: fix style issues for p80211hdr.h
  staging: vt6656: removed NTSTATUS definition
  staging: vt6656: simplified tests involving both multi/broad-casts
  Staging: vt6655: replace BOOL with in kernel bool
  Staging: vt6655: replace FALSE with in kernel false
  Staging: vt6655: replace TRUE with in kernel true
  ...
Linus Torvalds 15 年之前
父節點
當前提交
cc41f5cede
共有 100 個文件被更改,包括 3620 次插入1561 次删除
  1. 1 0
      arch/x86/kernel/cpu/mshyperv.c
  2. 11 3
      drivers/staging/Kconfig
  3. 6 2
      drivers/staging/Makefile
  4. 2 2
      drivers/staging/adis16255/adis16255.c
  5. 12 0
      drivers/staging/batman-adv/CHANGELOG
  6. 1 1
      drivers/staging/batman-adv/Kconfig
  7. 2 2
      drivers/staging/batman-adv/Makefile
  8. 1 1
      drivers/staging/batman-adv/README
  9. 6 3
      drivers/staging/batman-adv/TODO
  10. 6 3
      drivers/staging/batman-adv/aggregation.c
  11. 5 0
      drivers/staging/batman-adv/aggregation.h
  12. 341 0
      drivers/staging/batman-adv/bat_debugfs.c
  13. 33 0
      drivers/staging/batman-adv/bat_debugfs.h
  14. 150 150
      drivers/staging/batman-adv/bat_sysfs.c
  15. 13 0
      drivers/staging/batman-adv/bat_sysfs.h
  16. 10 7
      drivers/staging/batman-adv/bitarray.c
  17. 7 6
      drivers/staging/batman-adv/bitarray.h
  18. 0 354
      drivers/staging/batman-adv/device.c
  19. 40 31
      drivers/staging/batman-adv/hard-interface.c
  20. 5 0
      drivers/staging/batman-adv/hard-interface.h
  21. 1 1
      drivers/staging/batman-adv/hash.c
  22. 4 8
      drivers/staging/batman-adv/hash.h
  23. 334 0
      drivers/staging/batman-adv/icmp_socket.c
  24. 11 13
      drivers/staging/batman-adv/icmp_socket.h
  25. 27 35
      drivers/staging/batman-adv/main.c
  26. 62 20
      drivers/staging/batman-adv/main.h
  27. 72 84
      drivers/staging/batman-adv/originator.c
  28. 6 4
      drivers/staging/batman-adv/originator.h
  29. 28 4
      drivers/staging/batman-adv/packet.h
  30. 5 0
      drivers/staging/batman-adv/ring_buffer.h
  31. 322 84
      drivers/staging/batman-adv/routing.c
  32. 10 3
      drivers/staging/batman-adv/routing.h
  33. 52 29
      drivers/staging/batman-adv/send.c
  34. 5 2
      drivers/staging/batman-adv/send.h
  35. 80 85
      drivers/staging/batman-adv/soft-interface.c
  36. 6 7
      drivers/staging/batman-adv/soft-interface.h
  37. 14 0
      drivers/staging/batman-adv/sysfs-class-net-batman-adv
  38. 33 0
      drivers/staging/batman-adv/sysfs-class-net-mesh
  39. 82 89
      drivers/staging/batman-adv/translation-table.c
  40. 7 7
      drivers/staging/batman-adv/translation-table.h
  41. 32 11
      drivers/staging/batman-adv/types.h
  42. 98 49
      drivers/staging/batman-adv/vis.c
  43. 7 6
      drivers/staging/batman-adv/vis.h
  44. 0 1
      drivers/staging/comedi/TODO
  45. 9 2
      drivers/staging/comedi/comedi_fops.c
  46. 1 57
      drivers/staging/comedi/comedidev.h
  47. 16 1
      drivers/staging/comedi/drivers/8255.c
  48. 16 1
      drivers/staging/comedi/drivers/acl7225b.c
  49. 2 4
      drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
  50. 37 1
      drivers/staging/comedi/drivers/addi-data/addi_common.c
  51. 6 6
      drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
  52. 4 4
      drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
  53. 4 0
      drivers/staging/comedi/drivers/addi_apci_035.c
  54. 4 0
      drivers/staging/comedi/drivers/addi_apci_1032.c
  55. 4 0
      drivers/staging/comedi/drivers/addi_apci_1500.c
  56. 4 0
      drivers/staging/comedi/drivers/addi_apci_1516.c
  57. 4 0
      drivers/staging/comedi/drivers/addi_apci_1564.c
  58. 4 0
      drivers/staging/comedi/drivers/addi_apci_16xx.c
  59. 4 0
      drivers/staging/comedi/drivers/addi_apci_2016.c
  60. 4 0
      drivers/staging/comedi/drivers/addi_apci_2032.c
  61. 4 0
      drivers/staging/comedi/drivers/addi_apci_2200.c
  62. 4 0
      drivers/staging/comedi/drivers/addi_apci_3001.c
  63. 4 0
      drivers/staging/comedi/drivers/addi_apci_3120.c
  64. 4 0
      drivers/staging/comedi/drivers/addi_apci_3501.c
  65. 4 0
      drivers/staging/comedi/drivers/addi_apci_3xxx.c
  66. 43 5
      drivers/staging/comedi/drivers/adl_pci6208.c
  67. 45 6
      drivers/staging/comedi/drivers/adl_pci7230.c
  68. 45 6
      drivers/staging/comedi/drivers/adl_pci7296.c
  69. 45 6
      drivers/staging/comedi/drivers/adl_pci7432.c
  70. 45 6
      drivers/staging/comedi/drivers/adl_pci8164.c
  71. 137 76
      drivers/staging/comedi/drivers/adl_pci9111.c
  72. 41 1
      drivers/staging/comedi/drivers/adl_pci9118.c
  73. 16 1
      drivers/staging/comedi/drivers/adq12b.c
  74. 69 20
      drivers/staging/comedi/drivers/adv_pci1710.c
  75. 41 1
      drivers/staging/comedi/drivers/adv_pci1723.c
  76. 223 132
      drivers/staging/comedi/drivers/adv_pci_dio.c
  77. 16 1
      drivers/staging/comedi/drivers/aio_aio12_8.c
  78. 16 1
      drivers/staging/comedi/drivers/aio_iiro_16.c
  79. 11 11
      drivers/staging/comedi/drivers/am9513.h
  80. 55 2
      drivers/staging/comedi/drivers/amplc_dio200.c
  81. 55 2
      drivers/staging/comedi/drivers/amplc_pc236.c
  82. 55 2
      drivers/staging/comedi/drivers/amplc_pc263.c
  83. 43 1
      drivers/staging/comedi/drivers/amplc_pci224.c
  84. 45 5
      drivers/staging/comedi/drivers/amplc_pci230.c
  85. 16 1
      drivers/staging/comedi/drivers/c6xdigio.c
  86. 13 3
      drivers/staging/comedi/drivers/cb_das16_cs.c
  87. 43 5
      drivers/staging/comedi/drivers/cb_pcidas.c
  88. 43 5
      drivers/staging/comedi/drivers/cb_pcidas64.c
  89. 43 5
      drivers/staging/comedi/drivers/cb_pcidda.c
  90. 42 4
      drivers/staging/comedi/drivers/cb_pcidio.c
  91. 45 5
      drivers/staging/comedi/drivers/cb_pcimdas.c
  92. 41 5
      drivers/staging/comedi/drivers/cb_pcimdda.c
  93. 0 37
      drivers/staging/comedi/drivers/comedi_bond.c
  94. 16 1
      drivers/staging/comedi/drivers/comedi_parport.c
  95. 16 1
      drivers/staging/comedi/drivers/comedi_test.c
  96. 43 6
      drivers/staging/comedi/drivers/contec_pci_dio.c
  97. 43 1
      drivers/staging/comedi/drivers/daqboard2000.c
  98. 60 11
      drivers/staging/comedi/drivers/das08.c
  99. 1 2
      drivers/staging/comedi/drivers/das08_cs.c
  100. 16 1
      drivers/staging/comedi/drivers/das16.c

+ 1 - 0
arch/x86/kernel/cpu/mshyperv.c

@@ -18,6 +18,7 @@
 #include <asm/mshyperv.h>
 
 struct ms_hyperv_info ms_hyperv;
+EXPORT_SYMBOL_GPL(ms_hyperv);
 
 static bool __init ms_hyperv_platform(void)
 {

+ 11 - 3
drivers/staging/Kconfig

@@ -97,6 +97,8 @@ source "drivers/staging/octeon/Kconfig"
 
 source "drivers/staging/serqt_usb2/Kconfig"
 
+source "drivers/staging/spectra/Kconfig"
+
 source "drivers/staging/quatech_usb2/Kconfig"
 
 source "drivers/staging/vt6655/Kconfig"
@@ -115,7 +117,7 @@ source "drivers/staging/sep/Kconfig"
 
 source "drivers/staging/iio/Kconfig"
 
-source "drivers/staging/ramzswap/Kconfig"
+source "drivers/staging/zram/Kconfig"
 
 source "drivers/staging/wlags49_h2/Kconfig"
 
@@ -127,8 +129,6 @@ source "drivers/staging/samsung-laptop/Kconfig"
 
 source "drivers/staging/sm7xx/Kconfig"
 
-source "drivers/staging/dt3155/Kconfig"
-
 source "drivers/staging/dt3155v4l/Kconfig"
 
 source "drivers/staging/crystalhd/Kconfig"
@@ -147,5 +147,13 @@ source "drivers/staging/msm/Kconfig"
 
 source "drivers/staging/lirc/Kconfig"
 
+source "drivers/staging/easycap/Kconfig"
+
+source "drivers/staging/solo6x10/Kconfig"
+
+source "drivers/staging/tidspbridge/Kconfig"
+
+source "drivers/staging/quickstart/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING

+ 6 - 2
drivers/staging/Makefile

@@ -23,6 +23,7 @@ obj-$(CONFIG_R8187SE)		+= rtl8187se/
 obj-$(CONFIG_RTL8192SU)		+= rtl8192su/
 obj-$(CONFIG_RTL8192U)		+= rtl8192u/
 obj-$(CONFIG_RTL8192E)		+= rtl8192e/
+obj-$(CONFIG_SPECTRA)		+= spectra/
 obj-$(CONFIG_TRANZPORT)		+= frontier/
 obj-$(CONFIG_DREAM)		+= dream/
 obj-$(CONFIG_POHMELFS)		+= pohmelfs/
@@ -39,13 +40,12 @@ obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_MRST_RAR_HANDLER)	+= memrar/
 obj-$(CONFIG_DX_SEP)		+= sep/
 obj-$(CONFIG_IIO)		+= iio/
-obj-$(CONFIG_RAMZSWAP)		+= ramzswap/
+obj-$(CONFIG_ZRAM)		+= zram/
 obj-$(CONFIG_WLAGS49_H2)	+= wlags49_h2/
 obj-$(CONFIG_WLAGS49_H25)	+= wlags49_h25/
 obj-$(CONFIG_BATMAN_ADV)	+= batman-adv/
 obj-$(CONFIG_SAMSUNG_LAPTOP)	+= samsung-laptop/
 obj-$(CONFIG_FB_SM7XX)		+= sm7xx/
-obj-$(CONFIG_DT3155)		+= dt3155/
 obj-$(CONFIG_VIDEO_DT3155)	+= dt3155v4l/
 obj-$(CONFIG_CRYSTALHD)		+= crystalhd/
 obj-$(CONFIG_CXT1E1)		+= cxt1e1/
@@ -54,3 +54,7 @@ obj-$(CONFIG_ADIS16255)		+= adis16255/
 obj-$(CONFIG_FB_XGI)		+= xgifb/
 obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH)	+= mrst-touchscreen/
 obj-$(CONFIG_MSM_STAGING)	+= msm/
+obj-$(CONFIG_EASYCAP)		+= easycap/
+obj-$(CONFIG_SOLO6X10)		+= solo6x10/
+obj-$(CONFIG_TIDSPBRIDGE)	+= tidspbridge/
+obj-$(CONFIG_ACPI_QUICKSTART)	+= quickstart/

+ 2 - 2
drivers/staging/adis16255/adis16255.c

@@ -303,7 +303,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
 	if (status != 0)
 		goto err;
 	if (value != 0x0800) {
-		dev_warn(&spiadis->spi->dev, "Scale factor is none default"
+		dev_warn(&spiadis->spi->dev, "Scale factor is none default "
 				"value (%.4x)\n", value);
 	}
 
@@ -338,7 +338,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
 			status = -ENODEV;
 			goto err;
 		} else if (value & 0x3)	{
-			dev_warn(&spiadis->spi->dev, "Sensor voltage"
+			dev_warn(&spiadis->spi->dev, "Sensor voltage "
 						"out of range.\n");
 			status = -ENODEV;
 			goto err;

+ 12 - 0
drivers/staging/batman-adv/CHANGELOG

@@ -1,3 +1,15 @@
+batman-adv 2010.0.0:
+
+* support latest kernels (2.6.21 - 2.6.35)
+* further code refactoring and cleaning for coding style
+* move from procfs based configuration to sysfs
+* reorganized sequence number handling
+* limit queue lengths for batman and broadcast packets
+* many bugs (endless loop and rogue packets on shutdown, wrong tcpdump output,
+  missing frees in error situations, sleeps in atomic contexts) squashed
+
+ -- Fri, 18 Jun 2010 21:34:26 +0200
+
 batman-adv 0.2.1:
 
 * support latest kernels (2.6.20 - 2.6.33)

+ 1 - 1
drivers/staging/batman-adv/Kconfig

@@ -4,7 +4,7 @@
 
 config BATMAN_ADV
 	tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
-	depends on PROC_FS && NET
+	depends on NET
         default n
 	---help---
 

+ 2 - 2
drivers/staging/batman-adv/Makefile

@@ -18,5 +18,5 @@
 # 02110-1301, USA
 #
 
-obj-m += batman-adv.o
-batman-adv-objs := main.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o
+obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
+batman-adv-objs := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o

+ 1 - 1
drivers/staging/batman-adv/README

@@ -1,4 +1,4 @@
-[state: 03-05-2010]
+[state: 12-06-2010]
 
 BATMAN-ADV
 ----------

+ 6 - 3
drivers/staging/batman-adv/TODO

@@ -1,6 +1,9 @@
-Request a review.
-Process the comments from the review.
-Move into mainline proper.
+ * Use hweight* for hamming weight calculation
+ * Save/cache packets direktly as skb instead of using a normal memory region
+   and copying it in a skb using send_raw_packet and similar functions
+ * Request a new review
+ * Process the comments from the review
+ * Move into mainline proper
 
 Please send all patches to:
 	Marek Lindner <lindner_marek@yahoo.de>

+ 6 - 3
drivers/staging/batman-adv/aggregation.c

@@ -106,11 +106,14 @@ static void new_aggregated_packet(unsigned char *packet_buff,
 {
 	struct forw_packet *forw_packet_aggr;
 	unsigned long flags;
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 
 	/* own packet should always be scheduled */
 	if (!own_packet) {
 		if (!atomic_dec_not_zero(&batman_queue_left)) {
-			bat_dbg(DBG_BATMAN, "batman packet queue full\n");
+			bat_dbg(DBG_BATMAN, bat_priv,
+				"batman packet queue full\n");
 			return;
 		}
 	}
@@ -252,9 +255,9 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
 	while (aggregated_packet(buff_pos, packet_len,
 				 batman_packet->num_hna)) {
 
-		/* network to host order for our 16bit seqno, and the
+		/* network to host order for our 32bit seqno, and the
 		   orig_interval. */
-		batman_packet->seqno = ntohs(batman_packet->seqno);
+		batman_packet->seqno = ntohl(batman_packet->seqno);
 
 		hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
 		receive_bat_packet(ethhdr, batman_packet,

+ 5 - 0
drivers/staging/batman-adv/aggregation.h

@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_AGGREGATION_H_
+#define _NET_BATMAN_ADV_AGGREGATION_H_
+
 #include "main.h"
 
 /* is there another aggregated packet here? */
@@ -36,3 +39,5 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
 			    unsigned long send_time);
 void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
 			     int packet_len, struct batman_if *if_incoming);
+
+#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */

+ 341 - 0
drivers/staging/batman-adv/bat_debugfs.c

@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+
+#include <linux/debugfs.h>
+
+#include "bat_debugfs.h"
+#include "translation-table.h"
+#include "originator.h"
+#include "hard-interface.h"
+#include "vis.h"
+#include "icmp_socket.h"
+
+static struct dentry *bat_debugfs;
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+#define LOG_BUFF_MASK (log_buff_len-1)
+#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK])
+
+static int log_buff_len = LOG_BUF_LEN;
+
+static void emit_log_char(struct debug_log *debug_log, char c)
+{
+	LOG_BUFF(debug_log->log_end) = c;
+	debug_log->log_end++;
+
+	if (debug_log->log_end - debug_log->log_start > log_buff_len)
+		debug_log->log_start = debug_log->log_end - log_buff_len;
+}
+
+static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
+{
+	int printed_len;
+	va_list args;
+	static char debug_log_buf[256];
+	char *p;
+	unsigned long flags;
+
+	if (!debug_log)
+		return 0;
+
+	spin_lock_irqsave(&debug_log->lock, flags);
+	va_start(args, fmt);
+	printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf),
+				 fmt, args);
+	va_end(args);
+
+	for (p = debug_log_buf; *p != 0; p++)
+		emit_log_char(debug_log, *p);
+
+	spin_unlock_irqrestore(&debug_log->lock, flags);
+
+	wake_up(&debug_log->queue_wait);
+
+	return 0;
+}
+
+int debug_log(struct bat_priv *bat_priv, char *fmt, ...)
+{
+	va_list args;
+	char tmp_log_buf[256];
+
+	va_start(args, fmt);
+	vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
+	fdebug_log(bat_priv->debug_log, "[%10u] %s",
+		   (jiffies / HZ), tmp_log_buf);
+	va_end(args);
+
+	return 0;
+}
+
+static int log_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	inc_module_count();
+	return 0;
+}
+
+static int log_release(struct inode *inode, struct file *file)
+{
+	dec_module_count();
+	return 0;
+}
+
+static ssize_t log_read(struct file *file, char __user *buf,
+			size_t count, loff_t *ppos)
+{
+	struct bat_priv *bat_priv = file->private_data;
+	struct debug_log *debug_log = bat_priv->debug_log;
+	int error, i = 0;
+	char c;
+	unsigned long flags;
+
+	if ((file->f_flags & O_NONBLOCK) &&
+	    !(debug_log->log_end - debug_log->log_start))
+		return -EAGAIN;
+
+	if ((!buf) || (count < 0))
+		return -EINVAL;
+
+	if (count == 0)
+		return 0;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	error = wait_event_interruptible(debug_log->queue_wait,
+				(debug_log->log_start - debug_log->log_end));
+
+	if (error)
+		return error;
+
+	spin_lock_irqsave(&debug_log->lock, flags);
+
+	while ((!error) && (i < count) &&
+	       (debug_log->log_start != debug_log->log_end)) {
+		c = LOG_BUFF(debug_log->log_start);
+
+		debug_log->log_start++;
+
+		spin_unlock_irqrestore(&debug_log->lock, flags);
+
+		error = __put_user(c, buf);
+
+		spin_lock_irqsave(&debug_log->lock, flags);
+
+		buf++;
+		i++;
+
+	}
+
+	spin_unlock_irqrestore(&debug_log->lock, flags);
+
+	if (!error)
+		return i;
+
+	return error;
+}
+
+static unsigned int log_poll(struct file *file, poll_table *wait)
+{
+	struct bat_priv *bat_priv = file->private_data;
+	struct debug_log *debug_log = bat_priv->debug_log;
+
+	poll_wait(file, &debug_log->queue_wait, wait);
+
+	if (debug_log->log_end - debug_log->log_start)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static const struct file_operations log_fops = {
+	.open           = log_open,
+	.release        = log_release,
+	.read           = log_read,
+	.poll           = log_poll,
+};
+
+static int debug_log_setup(struct bat_priv *bat_priv)
+{
+	struct dentry *d;
+
+	if (!bat_priv->debug_dir)
+		goto err;
+
+	bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC);
+	if (!bat_priv->debug_log)
+		goto err;
+
+	spin_lock_init(&bat_priv->debug_log->lock);
+	init_waitqueue_head(&bat_priv->debug_log->queue_wait);
+
+	d = debugfs_create_file("log", S_IFREG | S_IRUSR,
+				bat_priv->debug_dir, bat_priv, &log_fops);
+	if (d)
+		goto err;
+
+	return 0;
+
+err:
+	return 1;
+}
+
+static void debug_log_cleanup(struct bat_priv *bat_priv)
+{
+	kfree(bat_priv->debug_log);
+	bat_priv->debug_log = NULL;
+}
+#else /* CONFIG_BATMAN_ADV_DEBUG */
+static int debug_log_setup(struct bat_priv *bat_priv)
+{
+	bat_priv->debug_log = NULL;
+	return 0;
+}
+
+static void debug_log_cleanup(struct bat_priv *bat_priv)
+{
+	return;
+}
+#endif
+
+static int originators_open(struct inode *inode, struct file *file)
+{
+	struct net_device *net_dev = (struct net_device *)inode->i_private;
+	return single_open(file, orig_seq_print_text, net_dev);
+}
+
+static int transtable_global_open(struct inode *inode, struct file *file)
+{
+	struct net_device *net_dev = (struct net_device *)inode->i_private;
+	return single_open(file, hna_global_seq_print_text, net_dev);
+}
+
+static int transtable_local_open(struct inode *inode, struct file *file)
+{
+	struct net_device *net_dev = (struct net_device *)inode->i_private;
+	return single_open(file, hna_local_seq_print_text, net_dev);
+}
+
+static int vis_data_open(struct inode *inode, struct file *file)
+{
+	struct net_device *net_dev = (struct net_device *)inode->i_private;
+	return single_open(file, vis_seq_print_text, net_dev);
+}
+
+struct bat_debuginfo {
+	struct attribute attr;
+	const struct file_operations fops;
+};
+
+#define BAT_DEBUGINFO(_name, _mode, _open)	\
+struct bat_debuginfo bat_debuginfo_##_name = {	\
+	.attr = { .name = __stringify(_name),	\
+		  .mode = _mode, },		\
+	.fops = { .owner = THIS_MODULE,		\
+		  .open = _open,		\
+		  .read	= seq_read,		\
+		  .llseek = seq_lseek,		\
+		  .release = single_release,	\
+		}				\
+};
+
+static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
+static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
+static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
+static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
+
+static struct bat_debuginfo *mesh_debuginfos[] = {
+	&bat_debuginfo_originators,
+	&bat_debuginfo_transtable_global,
+	&bat_debuginfo_transtable_local,
+	&bat_debuginfo_vis_data,
+	NULL,
+};
+
+void debugfs_init(void)
+{
+	bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
+	if (bat_debugfs == ERR_PTR(-ENODEV))
+		bat_debugfs = NULL;
+}
+
+void debugfs_destroy(void)
+{
+	if (bat_debugfs) {
+		debugfs_remove_recursive(bat_debugfs);
+		bat_debugfs = NULL;
+	}
+}
+
+int debugfs_add_meshif(struct net_device *dev)
+{
+	struct bat_priv *bat_priv = netdev_priv(dev);
+	struct bat_debuginfo **bat_debug;
+	struct dentry *file;
+
+	if (!bat_debugfs)
+		goto out;
+
+	bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs);
+	if (!bat_priv->debug_dir)
+		goto out;
+
+	bat_socket_setup(bat_priv);
+	debug_log_setup(bat_priv);
+
+	for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
+		file = debugfs_create_file(((*bat_debug)->attr).name,
+					  S_IFREG | ((*bat_debug)->attr).mode,
+					  bat_priv->debug_dir,
+					  dev, &(*bat_debug)->fops);
+		if (!file) {
+			bat_err(dev, "Can't add debugfs file: %s/%s\n",
+				dev->name, ((*bat_debug)->attr).name);
+			goto rem_attr;
+		}
+	}
+
+	return 0;
+rem_attr:
+	debugfs_remove_recursive(bat_priv->debug_dir);
+	bat_priv->debug_dir = NULL;
+out:
+#ifdef CONFIG_DEBUG_FS
+	return -ENOMEM;
+#else
+	return 0;
+#endif /* CONFIG_DEBUG_FS */
+}
+
+void debugfs_del_meshif(struct net_device *dev)
+{
+	struct bat_priv *bat_priv = netdev_priv(dev);
+
+	debug_log_cleanup(bat_priv);
+
+	if (bat_debugfs) {
+		debugfs_remove_recursive(bat_priv->debug_dir);
+		bat_priv->debug_dir = NULL;
+	}
+}

+ 33 - 0
drivers/staging/batman-adv/bat_debugfs.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+
+#ifndef _NET_BATMAN_ADV_DEBUGFS_H_
+#define _NET_BATMAN_ADV_DEBUGFS_H_
+
+#define DEBUGFS_BAT_SUBDIR "batman_adv"
+
+void debugfs_init(void);
+void debugfs_destroy(void);
+int debugfs_add_meshif(struct net_device *dev);
+void debugfs_del_meshif(struct net_device *dev);
+
+#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */

+ 150 - 150
drivers/staging/batman-adv/bat_sysfs.c

@@ -28,22 +28,6 @@
 
 #define to_dev(obj)     container_of(obj, struct device, kobj)
 
-struct bat_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
-			char *buf);
-	ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
-			 char *buf, size_t count);
-};
-
-struct hardif_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
-			char *buf);
-	ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
-			 char *buf, size_t count);
-};
-
 #define BAT_ATTR(_name, _mode, _show, _store)	\
 struct bat_attribute bat_attr_##_name = {	\
 	.attr = {.name = __stringify(_name),	\
@@ -52,34 +36,18 @@ struct bat_attribute bat_attr_##_name = {	\
 	.store  = _store,			\
 };
 
-#define BAT_BIN_ATTR(_name, _mode, _read, _write)	\
-struct bin_attribute bat_attr_##_name = {		\
-	.attr = { .name = __stringify(_name),		\
-		  .mode = _mode, },			\
-	.read = _read,					\
-	.write = _write,				\
-};
-
-#define HARDIF_ATTR(_name, _mode, _show, _store)	\
-struct hardif_attribute hardif_attr_##_name = {		\
-	.attr = {.name = __stringify(_name),		\
-		 .mode = _mode },			\
-	.show   = _show,				\
-	.store  = _store,				\
-};
-
-static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr,
+static ssize_t show_aggr_ogms(struct kobject *kobj, struct attribute *attr,
 			     char *buff)
 {
 	struct device *dev = to_dev(kobj->parent);
 	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
 	int aggr_status = atomic_read(&bat_priv->aggregation_enabled);
 
-	return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1\n",
+	return sprintf(buff, "%s\n",
 		       aggr_status == 0 ? "disabled" : "enabled");
 }
 
-static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
+static ssize_t store_aggr_ogms(struct kobject *kobj, struct attribute *attr,
 			      char *buff, size_t count)
 {
 	struct device *dev = to_dev(kobj->parent);
@@ -99,23 +67,73 @@ static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr,
 		if (buff[count - 1] == '\n')
 			buff[count - 1] = '\0';
 
-		printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n",
-		       net_dev->name, buff);
+		bat_info(net_dev,
+			 "Invalid parameter for 'aggregate OGM' setting"
+			 "received: %s\n", buff);
 		return -EINVAL;
 	}
 
 	if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp)
 		return count;
 
-	printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n",
-	       atomic_read(&bat_priv->aggregation_enabled) == 1 ?
-	       "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled",
-	       net_dev->name);
+	bat_info(net_dev, "Changing aggregation from: %s to: %s\n",
+		 atomic_read(&bat_priv->aggregation_enabled) == 1 ?
+		 "enabled" : "disabled", aggr_tmp == 1 ? "enabled" :
+		 "disabled");
 
 	atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp);
 	return count;
 }
 
+static ssize_t show_bond(struct kobject *kobj, struct attribute *attr,
+			     char *buff)
+{
+	struct device *dev = to_dev(kobj->parent);
+	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+	int bond_status = atomic_read(&bat_priv->bonding_enabled);
+
+	return sprintf(buff, "%s\n",
+		       bond_status == 0 ? "disabled" : "enabled");
+}
+
+static ssize_t store_bond(struct kobject *kobj, struct attribute *attr,
+			  char *buff, size_t count)
+{
+	struct device *dev = to_dev(kobj->parent);
+	struct net_device *net_dev = to_net_dev(dev);
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
+	int bonding_enabled_tmp = -1;
+
+	if (((count == 2) && (buff[0] == '1')) ||
+	    (strncmp(buff, "enable", 6) == 0))
+		bonding_enabled_tmp = 1;
+
+	if (((count == 2) && (buff[0] == '0')) ||
+	    (strncmp(buff, "disable", 7) == 0))
+		bonding_enabled_tmp = 0;
+
+	if (bonding_enabled_tmp < 0) {
+		if (buff[count - 1] == '\n')
+			buff[count - 1] = '\0';
+
+		bat_err(net_dev,
+			"Invalid parameter for 'bonding' setting received: "
+			"%s\n", buff);
+		return -EINVAL;
+	}
+
+	if (atomic_read(&bat_priv->bonding_enabled) == bonding_enabled_tmp)
+		return count;
+
+	bat_info(net_dev, "Changing bonding from: %s to: %s\n",
+		 atomic_read(&bat_priv->bonding_enabled) == 1 ?
+		 "enabled" : "disabled",
+		 bonding_enabled_tmp == 1 ? "enabled" : "disabled");
+
+	atomic_set(&bat_priv->bonding_enabled, (unsigned)bonding_enabled_tmp);
+	return count;
+}
+
 static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
 			     char *buff)
 {
@@ -123,10 +141,9 @@ static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
 	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
 	int vis_mode = atomic_read(&bat_priv->vis_mode);
 
-	return sprintf(buff, "status: %s\ncommands: client, server, %d, %d\n",
+	return sprintf(buff, "%s\n",
 		       vis_mode == VIS_TYPE_CLIENT_UPDATE ?
-							"client" : "server",
-		       VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE);
+							"client" : "server");
 }
 
 static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
@@ -141,7 +158,8 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
 	ret = strict_strtoul(buff, 10, &val);
 
 	if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
-	    (strncmp(buff, "client", 6) == 0))
+	    (strncmp(buff, "client", 6) == 0) ||
+	    (strncmp(buff, "off", 3) == 0))
 		vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
 
 	if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
@@ -152,18 +170,19 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
 		if (buff[count - 1] == '\n')
 			buff[count - 1] = '\0';
 
-		printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n",
-		       net_dev->name, buff);
+		bat_info(net_dev,
+			 "Invalid parameter for 'vis mode' setting received: "
+			 "%s\n", buff);
 		return -EINVAL;
 	}
 
 	if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
 		return count;
 
-	printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n",
-	       atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
-	       "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
-	       "client" : "server", net_dev->name);
+	bat_info(net_dev, "Changing vis mode from: %s to: %s\n",
+		 atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
+		 "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
+		 "client" : "server");
 
 	atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
 	return count;
@@ -175,7 +194,7 @@ static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr,
 	struct device *dev = to_dev(kobj->parent);
 	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
 
-	return sprintf(buff, "status: %i\n",
+	return sprintf(buff, "%i\n",
 		       atomic_read(&bat_priv->orig_interval));
 }
 
@@ -190,91 +209,87 @@ static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,
 
 	ret = strict_strtoul(buff, 10, &orig_interval_tmp);
 	if (ret) {
-		printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n",
-		       net_dev->name, buff);
+		bat_info(net_dev, "Invalid parameter for 'orig_interval' "
+			 "setting received: %s\n", buff);
 		return -EINVAL;
 	}
 
-	if (orig_interval_tmp <= JITTER * 2) {
-		printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n",
-		       orig_interval_tmp, JITTER * 2);
+	if (orig_interval_tmp < JITTER * 2) {
+		bat_info(net_dev, "New originator interval too small: %li "
+			 "(min: %i)\n", orig_interval_tmp, JITTER * 2);
 		return -EINVAL;
 	}
 
 	if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp)
 		return count;
 
-	printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n",
-	       atomic_read(&bat_priv->orig_interval),
-	       orig_interval_tmp, net_dev->name);
+	bat_info(net_dev, "Changing originator interval from: %i to: %li\n",
+		 atomic_read(&bat_priv->orig_interval),
+		 orig_interval_tmp);
 
 	atomic_set(&bat_priv->orig_interval, orig_interval_tmp);
 	return count;
 }
 
-static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR,
-		show_aggr_ogm, store_aggr_ogm);
-static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
-static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
-		show_orig_interval, store_orig_interval);
-
-static struct bat_attribute *mesh_attrs[] = {
-	&bat_attr_aggregate_ogm,
-	&bat_attr_vis_mode,
-	&bat_attr_orig_interval,
-	NULL,
-};
-
-static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj,
-				  struct bin_attribute *bin_attr,
-				  char *buff, loff_t off, size_t count)
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+static ssize_t show_log_level(struct kobject *kobj, struct attribute *attr,
+			     char *buff)
 {
 	struct device *dev = to_dev(kobj->parent);
-	struct net_device *net_dev = to_net_dev(dev);
+	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+	int log_level = atomic_read(&bat_priv->log_level);
 
-	return hna_local_fill_buffer_text(net_dev, buff, count, off);
+	return sprintf(buff, "%d\n", log_level);
 }
 
-static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj,
-				  struct bin_attribute *bin_attr,
-				  char *buff, loff_t off, size_t count)
+static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
+			      char *buff, size_t count)
 {
 	struct device *dev = to_dev(kobj->parent);
 	struct net_device *net_dev = to_net_dev(dev);
+	struct bat_priv *bat_priv = netdev_priv(net_dev);
+	unsigned long log_level_tmp;
+	int ret;
 
-	return hna_global_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static ssize_t originators_read(struct file *filp, struct kobject *kobj,
-				  struct bin_attribute *bin_attr,
-				  char *buff, loff_t off, size_t count)
-{
-	struct device *dev = to_dev(kobj->parent);
-	struct net_device *net_dev = to_net_dev(dev);
+	ret = strict_strtoul(buff, 10, &log_level_tmp);
+	if (ret) {
+		bat_info(net_dev, "Invalid parameter for 'log_level' "
+			 "setting received: %s\n", buff);
+		return -EINVAL;
+	}
 
-	return orig_fill_buffer_text(net_dev, buff, count, off);
-}
+	if (log_level_tmp > 3) {
+		bat_info(net_dev, "New log level too big: %li "
+			 "(max: %i)\n", log_level_tmp, 3);
+		return -EINVAL;
+	}
 
-static ssize_t vis_data_read(struct file *filp, struct kobject *kobj,
-				  struct bin_attribute *bin_attr,
-				  char *buff, loff_t off, size_t count)
-{
-	struct device *dev = to_dev(kobj->parent);
-	struct net_device *net_dev = to_net_dev(dev);
+	if (atomic_read(&bat_priv->log_level) == log_level_tmp)
+		return count;
 
-	return vis_fill_buffer_text(net_dev, buff, count, off);
+	atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
+	return count;
 }
+#endif
 
-static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
-static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
-static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
-static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
+static BAT_ATTR(aggregated_ogms, S_IRUGO | S_IWUSR,
+		show_aggr_ogms, store_aggr_ogms);
+static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond);
+static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
+static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
+		show_orig_interval, store_orig_interval);
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+static BAT_ATTR(log_level, S_IRUGO | S_IWUSR, show_log_level, store_log_level);
+#endif
 
-static struct bin_attribute *mesh_bin_attrs[] = {
-	&bat_attr_transtable_local,
-	&bat_attr_transtable_global,
-	&bat_attr_originators,
-	&bat_attr_vis_data,
+static struct bat_attribute *mesh_attrs[] = {
+	&bat_attr_aggregated_ogms,
+	&bat_attr_bonding,
+	&bat_attr_vis_mode,
+	&bat_attr_orig_interval,
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+	&bat_attr_log_level,
+#endif
 	NULL,
 };
 
@@ -283,22 +298,24 @@ int sysfs_add_meshif(struct net_device *dev)
 	struct kobject *batif_kobject = &dev->dev.kobj;
 	struct bat_priv *bat_priv = netdev_priv(dev);
 	struct bat_attribute **bat_attr;
-	struct bin_attribute **bin_attr;
 	int err;
 
 	/* FIXME: should be done in the general mesh setup
 		  routine as soon as we have it */
 	atomic_set(&bat_priv->aggregation_enabled, 1);
+	atomic_set(&bat_priv->bonding_enabled, 0);
 	atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
 	atomic_set(&bat_priv->orig_interval, 1000);
+	atomic_set(&bat_priv->log_level, 0);
+
 	bat_priv->primary_if = NULL;
 	bat_priv->num_ifaces = 0;
 
 	bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
 						    batif_kobject);
 	if (!bat_priv->mesh_obj) {
-		printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
-		       dev->name, SYSFS_IF_MESH_SUBDIR);
+		bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
+			SYSFS_IF_MESH_SUBDIR);
 		goto out;
 	}
 
@@ -306,28 +323,15 @@ int sysfs_add_meshif(struct net_device *dev)
 		err = sysfs_create_file(bat_priv->mesh_obj,
 					&((*bat_attr)->attr));
 		if (err) {
-			printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
-			       dev->name, SYSFS_IF_MESH_SUBDIR,
-			       ((*bat_attr)->attr).name);
+			bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+				dev->name, SYSFS_IF_MESH_SUBDIR,
+				((*bat_attr)->attr).name);
 			goto rem_attr;
 		}
 	}
 
-	for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) {
-		err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr));
-		if (err) {
-			printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
-			       dev->name, SYSFS_IF_MESH_SUBDIR,
-			       ((*bin_attr)->attr).name);
-			goto rem_bin_attr;
-		}
-	}
-
 	return 0;
 
-rem_bin_attr:
-	for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
-		sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
 rem_attr:
 	for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
 		sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
@@ -342,10 +346,6 @@ void sysfs_del_meshif(struct net_device *dev)
 {
 	struct bat_priv *bat_priv = netdev_priv(dev);
 	struct bat_attribute **bat_attr;
-	struct bin_attribute **bin_attr;
-
-	for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
-		sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
 
 	for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
 		sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
@@ -364,7 +364,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
 	if (!batman_if)
 		return 0;
 
-	return sprintf(buff, "status: %s\ncommands: none, bat0\n",
+	return sprintf(buff, "%s\n",
 		       batman_if->if_status == IF_NOT_IN_USE ?
 							"none" : "bat0");
 }
@@ -390,8 +390,8 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
 		if (buff[count - 1] == '\n')
 			buff[count - 1] = '\0';
 
-		printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n",
-		       buff);
+		pr_err("Invalid parameter for 'mesh_iface' setting received: "
+		       "%s\n", buff);
 		return -EINVAL;
 	}
 
@@ -433,37 +433,37 @@ static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
 	}
 }
 
-static HARDIF_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
-		   show_mesh_iface, store_mesh_iface);
-static HARDIF_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
+static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
+		show_mesh_iface, store_mesh_iface);
+static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
 
-static struct hardif_attribute *batman_attrs[] = {
-	&hardif_attr_mesh_iface,
-	&hardif_attr_iface_status,
+static struct bat_attribute *batman_attrs[] = {
+	&bat_attr_mesh_iface,
+	&bat_attr_iface_status,
 	NULL,
 };
 
 int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
 {
 	struct kobject *hardif_kobject = &dev->dev.kobj;
-	struct hardif_attribute **hardif_attr;
+	struct bat_attribute **bat_attr;
 	int err;
 
 	*hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR,
 						    hardif_kobject);
 
 	if (!*hardif_obj) {
-		printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n",
-		       dev->name, SYSFS_IF_BAT_SUBDIR);
+		bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
+			SYSFS_IF_BAT_SUBDIR);
 		goto out;
 	}
 
-	for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) {
-		err = sysfs_create_file(*hardif_obj, &((*hardif_attr)->attr));
+	for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) {
+		err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
 		if (err) {
-			printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
-			       dev->name, SYSFS_IF_BAT_SUBDIR,
-			       ((*hardif_attr)->attr).name);
+			bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+				dev->name, SYSFS_IF_BAT_SUBDIR,
+				((*bat_attr)->attr).name);
 			goto rem_attr;
 		}
 	}
@@ -471,8 +471,8 @@ int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
 	return 0;
 
 rem_attr:
-	for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr)
-		sysfs_remove_file(*hardif_obj, &((*hardif_attr)->attr));
+	for (bat_attr = batman_attrs; *bat_attr; ++bat_attr)
+		sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
 out:
 	return -ENOMEM;
 }

+ 13 - 0
drivers/staging/batman-adv/bat_sysfs.h

@@ -20,10 +20,23 @@
  */
 
 
+#ifndef _NET_BATMAN_ADV_SYSFS_H_
+#define _NET_BATMAN_ADV_SYSFS_H_
+
 #define SYSFS_IF_MESH_SUBDIR "mesh"
 #define SYSFS_IF_BAT_SUBDIR "batman_adv"
 
+struct bat_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
+			 char *buf, size_t count);
+};
+
 int sysfs_add_meshif(struct net_device *dev);
 void sysfs_del_meshif(struct net_device *dev);
 int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
 void sysfs_del_hardif(struct kobject **hardif_obj);
+
+#endif /* _NET_BATMAN_ADV_SYSFS_H_ */

+ 10 - 7
drivers/staging/batman-adv/bitarray.c

@@ -24,10 +24,10 @@
 
 /* returns true if the corresponding bit in the given seq_bits indicates true
  * and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
-		       uint16_t curr_seqno)
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
+		       uint32_t curr_seqno)
 {
-	int16_t diff, word_offset, word_num;
+	int32_t diff, word_offset, word_num;
 
 	diff = last_seqno - curr_seqno;
 	if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
@@ -63,7 +63,7 @@ void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n)
 }
 
 /* shift the packet array by n places. */
-void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
+static void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
 {
 	int32_t word_offset, word_num;
 	int32_t i;
@@ -125,9 +125,12 @@ static void bit_reset_window(TYPE_OF_WORD *seq_bits)
  *  1 if the window was moved (either new or very old)
  *  0 if the window was not moved/shifted.
  */
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
 		    int8_t set_mark)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+
 	/* sequence number is slightly older. We already got a sequence number
 	 * higher than this one, so we just mark it. */
 
@@ -152,7 +155,7 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
 
 	if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
 		|| (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"We missed a lot of packets (%i) !\n",
 			seq_num_diff - 1);
 		bit_reset_window(seq_bits);
@@ -169,7 +172,7 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
 	if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
 		|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
 
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Other host probably restarted!\n");
 
 		bit_reset_window(seq_bits);

+ 7 - 6
drivers/staging/batman-adv/bitarray.h

@@ -19,6 +19,8 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_BITARRAY_H_
+#define _NET_BATMAN_ADV_BITARRAY_H_
 
 /* you should choose something big, if you don't want to waste cpu */
 #define TYPE_OF_WORD unsigned long
@@ -26,20 +28,19 @@
 
 /* returns true if the corresponding bit in the given seq_bits indicates true
  * and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
-					   uint16_t curr_seqno);
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
+					   uint32_t curr_seqno);
 
 /* turn corresponding bit on, so we can remember that we got the packet */
 void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
 
-/* shift the packet array by n places. */
-void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n);
-
 
 /* receive and process one packet, returns 1 if received seq_num is considered
  * new, 0 if old  */
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
 					int8_t set_mark);
 
 /* count the hamming weight, how many good packets did we receive? */
 int  bit_packet_count(TYPE_OF_WORD *seq_bits);
+
+#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */

+ 0 - 354
drivers/staging/batman-adv/device.c

@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#include <linux/device.h>
-#include <linux/slab.h>
-#include "main.h"
-#include "device.h"
-#include "send.h"
-#include "types.h"
-#include "hash.h"
-#include "hard-interface.h"
-
-static struct class *batman_class;
-
-static int Major;	/* Major number assigned to our device driver */
-
-static const struct file_operations fops = {
-	.open = bat_device_open,
-	.release = bat_device_release,
-	.read = bat_device_read,
-	.write = bat_device_write,
-	.poll = bat_device_poll,
-};
-
-static struct device_client *device_client_hash[256];
-
-void bat_device_init(void)
-{
-	memset(device_client_hash, 0, sizeof(device_client_hash));
-}
-
-int bat_device_setup(void)
-{
-	int tmp_major;
-
-	if (Major)
-		return 1;
-
-	/* register our device - kernel assigns a free major number */
-	tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
-	if (tmp_major < 0) {
-		printk(KERN_ERR "batman-adv:"
-		       "Registering the character device failed with %d\n",
-			  tmp_major);
-		return 0;
-	}
-
-	batman_class = class_create(THIS_MODULE, "batman-adv");
-
-	if (IS_ERR(batman_class)) {
-		printk(KERN_ERR "batman-adv:"
-		       "Could not register class 'batman-adv'\n");
-		return 0;
-	}
-
-	device_create(batman_class, NULL, MKDEV(tmp_major, 0), NULL,
-		      "batman-adv");
-
-	Major = tmp_major;
-	return 1;
-}
-
-void bat_device_destroy(void)
-{
-	if (!Major)
-		return;
-
-	device_destroy(batman_class, MKDEV(Major, 0));
-	class_destroy(batman_class);
-
-	/* Unregister the device */
-	unregister_chrdev(Major, DRIVER_DEVICE);
-
-	Major = 0;
-}
-
-int bat_device_open(struct inode *inode, struct file *file)
-{
-	unsigned int i;
-	struct device_client *device_client;
-
-	device_client = kmalloc(sizeof(struct device_client), GFP_KERNEL);
-
-	if (!device_client)
-		return -ENOMEM;
-
-	for (i = 0; i < ARRAY_SIZE(device_client_hash); i++) {
-		if (!device_client_hash[i]) {
-			device_client_hash[i] = device_client;
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(device_client_hash)) {
-		printk(KERN_ERR "batman-adv:"
-		       "Error - can't add another packet client: "
-		       "maximum number of clients reached\n");
-		kfree(device_client);
-		return -EXFULL;
-	}
-
-	INIT_LIST_HEAD(&device_client->queue_list);
-	device_client->queue_len = 0;
-	device_client->index = i;
-	spin_lock_init(&device_client->lock);
-	init_waitqueue_head(&device_client->queue_wait);
-
-	file->private_data = device_client;
-
-	inc_module_count();
-	return 0;
-}
-
-int bat_device_release(struct inode *inode, struct file *file)
-{
-	struct device_client *device_client =
-		(struct device_client *)file->private_data;
-	struct device_packet *device_packet;
-	struct list_head *list_pos, *list_pos_tmp;
-	unsigned long flags;
-
-	spin_lock_irqsave(&device_client->lock, flags);
-
-	/* for all packets in the queue ... */
-	list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) {
-		device_packet = list_entry(list_pos,
-					   struct device_packet, list);
-
-		list_del(list_pos);
-		kfree(device_packet);
-	}
-
-	device_client_hash[device_client->index] = NULL;
-	spin_unlock_irqrestore(&device_client->lock, flags);
-
-	kfree(device_client);
-	dec_module_count();
-
-	return 0;
-}
-
-ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
-			loff_t *ppos)
-{
-	struct device_client *device_client =
-		(struct device_client *)file->private_data;
-	struct device_packet *device_packet;
-	int error;
-	unsigned long flags;
-
-	if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
-		return -EAGAIN;
-
-	if ((!buf) || (count < sizeof(struct icmp_packet)))
-		return -EINVAL;
-
-	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT;
-
-	error = wait_event_interruptible(device_client->queue_wait,
-					 device_client->queue_len);
-
-	if (error)
-		return error;
-
-	spin_lock_irqsave(&device_client->lock, flags);
-
-	device_packet = list_first_entry(&device_client->queue_list,
-					 struct device_packet, list);
-	list_del(&device_packet->list);
-	device_client->queue_len--;
-
-	spin_unlock_irqrestore(&device_client->lock, flags);
-
-	error = __copy_to_user(buf, &device_packet->icmp_packet,
-			       sizeof(struct icmp_packet));
-
-	kfree(device_packet);
-
-	if (error)
-		return -EFAULT;
-
-	return sizeof(struct icmp_packet);
-}
-
-ssize_t bat_device_write(struct file *file, const char __user *buff,
-			 size_t len, loff_t *off)
-{
-	struct device_client *device_client =
-		(struct device_client *)file->private_data;
-	struct icmp_packet icmp_packet;
-	struct orig_node *orig_node;
-	struct batman_if *batman_if;
-	uint8_t dstaddr[ETH_ALEN];
-	unsigned long flags;
-
-	if (len < sizeof(struct icmp_packet)) {
-		bat_dbg(DBG_BATMAN, "batman-adv:"
-			"Error - can't send packet from char device: "
-			"invalid packet size\n");
-		return -EINVAL;
-	}
-
-	if (!access_ok(VERIFY_READ, buff, sizeof(struct icmp_packet)))
-		return -EFAULT;
-
-	if (__copy_from_user(&icmp_packet, buff, sizeof(icmp_packet)))
-		return -EFAULT;
-
-	if (icmp_packet.packet_type != BAT_ICMP) {
-		bat_dbg(DBG_BATMAN, "batman-adv:"
-			"Error - can't send packet from char device: "
-			"got bogus packet type (expected: BAT_ICMP)\n");
-		return -EINVAL;
-	}
-
-	if (icmp_packet.msg_type != ECHO_REQUEST) {
-		bat_dbg(DBG_BATMAN, "batman-adv:"
-			"Error - can't send packet from char device: "
-			"got bogus message type (expected: ECHO_REQUEST)\n");
-		return -EINVAL;
-	}
-
-	icmp_packet.uid = device_client->index;
-
-	if (icmp_packet.version != COMPAT_VERSION) {
-		icmp_packet.msg_type = PARAMETER_PROBLEM;
-		icmp_packet.ttl = COMPAT_VERSION;
-		bat_device_add_packet(device_client, &icmp_packet);
-		goto out;
-	}
-
-	if (atomic_read(&module_state) != MODULE_ACTIVE)
-		goto dst_unreach;
-
-	spin_lock_irqsave(&orig_hash_lock, flags);
-	orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
-
-	if (!orig_node)
-		goto unlock;
-
-	if (!orig_node->router)
-		goto unlock;
-
-	batman_if = orig_node->router->if_incoming;
-	memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
-
-	spin_unlock_irqrestore(&orig_hash_lock, flags);
-
-	if (!batman_if)
-		goto dst_unreach;
-
-	if (batman_if->if_status != IF_ACTIVE)
-		goto dst_unreach;
-
-	memcpy(icmp_packet.orig,
-	       batman_if->net_dev->dev_addr,
-	       ETH_ALEN);
-
-	send_raw_packet((unsigned char *)&icmp_packet,
-			sizeof(struct icmp_packet),
-			batman_if, dstaddr);
-
-	goto out;
-
-unlock:
-	spin_unlock_irqrestore(&orig_hash_lock, flags);
-dst_unreach:
-	icmp_packet.msg_type = DESTINATION_UNREACHABLE;
-	bat_device_add_packet(device_client, &icmp_packet);
-out:
-	return len;
-}
-
-unsigned int bat_device_poll(struct file *file, poll_table *wait)
-{
-	struct device_client *device_client =
-		(struct device_client *)file->private_data;
-
-	poll_wait(file, &device_client->queue_wait, wait);
-
-	if (device_client->queue_len > 0)
-		return POLLIN | POLLRDNORM;
-
-	return 0;
-}
-
-void bat_device_add_packet(struct device_client *device_client,
-			   struct icmp_packet *icmp_packet)
-{
-	struct device_packet *device_packet;
-	unsigned long flags;
-
-	device_packet = kmalloc(sizeof(struct device_packet), GFP_ATOMIC);
-
-	if (!device_packet)
-		return;
-
-	INIT_LIST_HEAD(&device_packet->list);
-	memcpy(&device_packet->icmp_packet, icmp_packet,
-	       sizeof(struct icmp_packet));
-
-	spin_lock_irqsave(&device_client->lock, flags);
-
-	/* while waiting for the lock the device_client could have been
-	 * deleted */
-	if (!device_client_hash[icmp_packet->uid]) {
-		spin_unlock_irqrestore(&device_client->lock, flags);
-		kfree(device_packet);
-		return;
-	}
-
-	list_add_tail(&device_packet->list, &device_client->queue_list);
-	device_client->queue_len++;
-
-	if (device_client->queue_len > 100) {
-		device_packet = list_first_entry(&device_client->queue_list,
-						 struct device_packet, list);
-
-		list_del(&device_packet->list);
-		kfree(device_packet);
-		device_client->queue_len--;
-	}
-
-	spin_unlock_irqrestore(&device_client->lock, flags);
-
-	wake_up(&device_client->queue_wait);
-}
-
-void bat_device_receive_packet(struct icmp_packet *icmp_packet)
-{
-	struct device_client *hash = device_client_hash[icmp_packet->uid];
-
-	if (hash)
-		bat_device_add_packet(hash, icmp_packet);
-}

+ 40 - 31
drivers/staging/batman-adv/hard-interface.c

@@ -30,6 +30,7 @@
 #include "hash.h"
 
 #include <linux/if_arp.h>
+#include <linux/netfilter_bridge.h>
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
@@ -108,7 +109,7 @@ static void set_primary_if(struct bat_priv *bat_priv,
 	set_main_if_addr(batman_if->net_dev->dev_addr);
 
 	batman_packet = (struct batman_packet *)(batman_if->packet_buff);
-	batman_packet->flags = 0;
+	batman_packet->flags = PRIMARIES_FIRST_HOP;
 	batman_packet->ttl = TTL;
 
 	/***
@@ -149,12 +150,10 @@ static void check_known_mac_addr(uint8_t *addr)
 		if (!compare_orig(batman_if->net_dev->dev_addr, addr))
 			continue;
 
-		printk(KERN_WARNING "batman-adv:"
-		    "The newly added mac address (%pM) already exists on: %s\n",
-		    addr, batman_if->dev);
-		printk(KERN_WARNING "batman-adv:"
-		    "It is strongly recommended to keep mac addresses unique"
-		    "to avoid problems!\n");
+		pr_warning("The newly added mac address (%pM) already exists "
+			   "on: %s\n", addr, batman_if->dev);
+		pr_warning("It is strongly recommended to keep mac addresses "
+			   "unique to avoid problems!\n");
 	}
 	rcu_read_unlock();
 }
@@ -188,7 +187,8 @@ void update_min_mtu(void)
 		soft_device->mtu = min_mtu;
 }
 
-static void hardif_activate_interface(struct bat_priv *bat_priv,
+static void hardif_activate_interface(struct net_device *net_dev,
+				      struct bat_priv *bat_priv,
 				      struct batman_if *batman_if)
 {
 	if (batman_if->if_status != IF_INACTIVE)
@@ -206,8 +206,7 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
 	if (!bat_priv->primary_if)
 		set_primary_if(bat_priv, batman_if);
 
-	printk(KERN_INFO "batman-adv:Interface activated: %s\n",
-	       batman_if->dev);
+	bat_info(net_dev, "Interface activated: %s\n", batman_if->dev);
 
 	if (atomic_read(&module_state) == MODULE_INACTIVE)
 		activate_module();
@@ -216,7 +215,8 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
 	return;
 }
 
-static void hardif_deactivate_interface(struct batman_if *batman_if)
+static void hardif_deactivate_interface(struct net_device *net_dev,
+					struct batman_if *batman_if)
 {
 	if ((batman_if->if_status != IF_ACTIVE) &&
 	   (batman_if->if_status != IF_TO_BE_ACTIVATED))
@@ -226,8 +226,7 @@ static void hardif_deactivate_interface(struct batman_if *batman_if)
 
 	batman_if->if_status = IF_INACTIVE;
 
-	printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
-	       batman_if->dev);
+	bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
 
 	update_min_mtu();
 }
@@ -245,9 +244,8 @@ int hardif_enable_interface(struct batman_if *batman_if)
 	batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
 
 	if (!batman_if->packet_buff) {
-		printk(KERN_ERR "batman-adv:"
-		       "Can't add interface packet (%s): out of memory\n",
-		       batman_if->dev);
+		bat_err(soft_device, "Can't add interface packet (%s): "
+			"out of memory\n", batman_if->dev);
 		goto err;
 	}
 
@@ -265,15 +263,14 @@ int hardif_enable_interface(struct batman_if *batman_if)
 	orig_hash_add_if(batman_if, bat_priv->num_ifaces);
 
 	atomic_set(&batman_if->seqno, 1);
-	printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev);
+	bat_info(soft_device, "Adding interface: %s\n", batman_if->dev);
 
 	if (hardif_is_iface_up(batman_if))
-		hardif_activate_interface(bat_priv, batman_if);
+		hardif_activate_interface(soft_device, bat_priv, batman_if);
 	else
-		printk(KERN_ERR "batman-adv:"
-		       "Not using interface %s "
-		       "(retrying later): interface not active\n",
-		       batman_if->dev);
+		bat_err(soft_device, "Not using interface %s "
+			"(retrying later): interface not active\n",
+			batman_if->dev);
 
 	/* begin scheduling originator messages on that interface */
 	schedule_own_packet(batman_if);
@@ -291,12 +288,12 @@ void hardif_disable_interface(struct batman_if *batman_if)
 	struct bat_priv *bat_priv = netdev_priv(soft_device);
 
 	if (batman_if->if_status == IF_ACTIVE)
-		hardif_deactivate_interface(batman_if);
+		hardif_deactivate_interface(soft_device, batman_if);
 
 	if (batman_if->if_status != IF_INACTIVE)
 		return;
 
-	printk(KERN_INFO "batman-adv:Removing interface: %s\n", batman_if->dev);
+	bat_info(soft_device, "Removing interface: %s\n", batman_if->dev);
 	bat_priv->num_ifaces--;
 	orig_hash_del_if(batman_if, bat_priv->num_ifaces);
 
@@ -323,8 +320,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
 
 	batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
 	if (!batman_if) {
-		printk(KERN_ERR "batman-adv:"
-		       "Can't add interface (%s): out of memory\n",
+		pr_err("Can't add interface (%s): out of memory\n",
 		       net_dev->name);
 		goto out;
 	}
@@ -407,11 +403,11 @@ static int hard_if_event(struct notifier_block *this,
 	case NETDEV_REGISTER:
 		break;
 	case NETDEV_UP:
-		hardif_activate_interface(bat_priv, batman_if);
+		hardif_activate_interface(soft_device, bat_priv, batman_if);
 		break;
 	case NETDEV_GOING_DOWN:
 	case NETDEV_DOWN:
-		hardif_deactivate_interface(batman_if);
+		hardif_deactivate_interface(soft_device, batman_if);
 		break;
 	case NETDEV_UNREGISTER:
 		hardif_remove_interface(batman_if);
@@ -432,11 +428,18 @@ out:
 	return NOTIFY_DONE;
 }
 
+static int batman_skb_recv_finish(struct sk_buff *skb)
+{
+	return NF_ACCEPT;
+}
+
 /* receive a packet with the batman ethertype coming on a hard
  * interface */
 int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	struct packet_type *ptype, struct net_device *orig_dev)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct batman_packet *batman_packet;
 	struct batman_if *batman_if;
 	struct net_device_stats *stats;
@@ -452,6 +455,13 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	if (atomic_read(&module_state) != MODULE_ACTIVE)
 		goto err_free;
 
+	/* if netfilter/ebtables wants to block incoming batman
+	 * packets then give them a chance to do so here */
+	ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
+		      batman_skb_recv_finish);
+	if (ret != 1)
+		goto err_out;
+
 	/* packet should hold at least type and version */
 	if (unlikely(skb_headlen(skb) < 2))
 		goto err_free;
@@ -478,7 +488,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	batman_packet = (struct batman_packet *)skb->data;
 
 	if (batman_packet->version != COMPAT_VERSION) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: incompatible batman version (%i)\n",
 			batman_packet->version);
 		goto err_free;
@@ -500,7 +510,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 
 		/* unicast packet */
 	case BAT_UNICAST:
-		ret = recv_unicast_packet(skb);
+		ret = recv_unicast_packet(skb, batman_if);
 		break;
 
 		/* broadcast packet */
@@ -531,7 +541,6 @@ err_out:
 	return NET_RX_DROP;
 }
 
-
 struct notifier_block hard_if_notifier = {
 	.notifier_call = hard_if_event,
 };

+ 5 - 0
drivers/staging/batman-adv/hard-interface.h

@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
+#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
+
 #define IF_NOT_IN_USE 0
 #define IF_TO_BE_REMOVED 1
 #define IF_INACTIVE 2
@@ -38,3 +41,5 @@ int batman_skb_recv(struct sk_buff *skb,
 				struct net_device *orig_dev);
 int hardif_min_mtu(void);
 void update_min_mtu(void);
+
+#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */

+ 1 - 1
drivers/staging/batman-adv/hash.c

@@ -23,7 +23,7 @@
 #include "hash.h"
 
 /* clears the hash */
-void hash_init(struct hashtable_t *hash)
+static void hash_init(struct hashtable_t *hash)
 {
 	int i;
 

+ 4 - 8
drivers/staging/batman-adv/hash.h

@@ -19,8 +19,9 @@
  *
  */
 
-#ifndef _BATMAN_HASH_H
-#define _BATMAN_HASH_H
+#ifndef _NET_BATMAN_ADV_HASH_H_
+#define _NET_BATMAN_ADV_HASH_H_
+
 #define HASHIT(name) struct hash_it_t name = { \
 		.index = -1, .bucket = NULL, \
 		.prev_bucket = NULL, \
@@ -56,9 +57,6 @@ struct hashtable_t {
 				     * argument and the size the second */
 };
 
-/* clears the hash */
-void hash_init(struct hashtable_t *hash);
-
 /* allocates and clears the hash */
 struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
 			     hashdata_choose_cb choose);
@@ -99,6 +97,4 @@ struct hashtable_t *hash_resize(struct hashtable_t *hash, int size);
 struct hash_it_t *hash_iterate(struct hashtable_t *hash,
 			       struct hash_it_t *iter_in);
 
-/* print the hash table for debugging */
-void hash_debug(struct hashtable_t *hash);
-#endif
+#endif /* _NET_BATMAN_ADV_HASH_H_ */

+ 334 - 0
drivers/staging/batman-adv/icmp_socket.c

@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include "main.h"
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include "icmp_socket.h"
+#include "send.h"
+#include "types.h"
+#include "hash.h"
+#include "hard-interface.h"
+
+
+static struct socket_client *socket_client_hash[256];
+
+static void bat_socket_add_packet(struct socket_client *socket_client,
+				  struct icmp_packet_rr *icmp_packet,
+				  size_t icmp_len);
+
+void bat_socket_init(void)
+{
+	memset(socket_client_hash, 0, sizeof(socket_client_hash));
+}
+
+static int bat_socket_open(struct inode *inode, struct file *file)
+{
+	unsigned int i;
+	struct socket_client *socket_client;
+
+	socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL);
+
+	if (!socket_client)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) {
+		if (!socket_client_hash[i]) {
+			socket_client_hash[i] = socket_client;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(socket_client_hash)) {
+		pr_err("Error - can't add another packet client: "
+		       "maximum number of clients reached\n");
+		kfree(socket_client);
+		return -EXFULL;
+	}
+
+	INIT_LIST_HEAD(&socket_client->queue_list);
+	socket_client->queue_len = 0;
+	socket_client->index = i;
+	spin_lock_init(&socket_client->lock);
+	init_waitqueue_head(&socket_client->queue_wait);
+
+	file->private_data = socket_client;
+
+	inc_module_count();
+	return 0;
+}
+
+static int bat_socket_release(struct inode *inode, struct file *file)
+{
+	struct socket_client *socket_client = file->private_data;
+	struct socket_packet *socket_packet;
+	struct list_head *list_pos, *list_pos_tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&socket_client->lock, flags);
+
+	/* for all packets in the queue ... */
+	list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) {
+		socket_packet = list_entry(list_pos,
+					   struct socket_packet, list);
+
+		list_del(list_pos);
+		kfree(socket_packet);
+	}
+
+	socket_client_hash[socket_client->index] = NULL;
+	spin_unlock_irqrestore(&socket_client->lock, flags);
+
+	kfree(socket_client);
+	dec_module_count();
+
+	return 0;
+}
+
+static ssize_t bat_socket_read(struct file *file, char __user *buf,
+			       size_t count, loff_t *ppos)
+{
+	struct socket_client *socket_client = file->private_data;
+	struct socket_packet *socket_packet;
+	size_t packet_len;
+	int error;
+	unsigned long flags;
+
+	if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0))
+		return -EAGAIN;
+
+	if ((!buf) || (count < sizeof(struct icmp_packet)))
+		return -EINVAL;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	error = wait_event_interruptible(socket_client->queue_wait,
+					 socket_client->queue_len);
+
+	if (error)
+		return error;
+
+	spin_lock_irqsave(&socket_client->lock, flags);
+
+	socket_packet = list_first_entry(&socket_client->queue_list,
+					 struct socket_packet, list);
+	list_del(&socket_packet->list);
+	socket_client->queue_len--;
+
+	spin_unlock_irqrestore(&socket_client->lock, flags);
+
+	error = __copy_to_user(buf, &socket_packet->icmp_packet,
+			       socket_packet->icmp_len);
+
+	packet_len = socket_packet->icmp_len;
+	kfree(socket_packet);
+
+	if (error)
+		return -EFAULT;
+
+	return packet_len;
+}
+
+static ssize_t bat_socket_write(struct file *file, const char __user *buff,
+				size_t len, loff_t *off)
+{
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+	struct socket_client *socket_client = file->private_data;
+	struct icmp_packet_rr icmp_packet;
+	struct orig_node *orig_node;
+	struct batman_if *batman_if;
+	size_t packet_len = sizeof(struct icmp_packet);
+	uint8_t dstaddr[ETH_ALEN];
+	unsigned long flags;
+
+	if (len < sizeof(struct icmp_packet)) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Error - can't send packet from char device: "
+			"invalid packet size\n");
+		return -EINVAL;
+	}
+
+	if (len >= sizeof(struct icmp_packet_rr))
+		packet_len = sizeof(struct icmp_packet_rr);
+
+	if (!access_ok(VERIFY_READ, buff, packet_len))
+		return -EFAULT;
+
+	if (__copy_from_user(&icmp_packet, buff, packet_len))
+		return -EFAULT;
+
+	if (icmp_packet.packet_type != BAT_ICMP) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Error - can't send packet from char device: "
+			"got bogus packet type (expected: BAT_ICMP)\n");
+		return -EINVAL;
+	}
+
+	if (icmp_packet.msg_type != ECHO_REQUEST) {
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Error - can't send packet from char device: "
+			"got bogus message type (expected: ECHO_REQUEST)\n");
+		return -EINVAL;
+	}
+
+	icmp_packet.uid = socket_client->index;
+
+	if (icmp_packet.version != COMPAT_VERSION) {
+		icmp_packet.msg_type = PARAMETER_PROBLEM;
+		icmp_packet.ttl = COMPAT_VERSION;
+		bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
+		goto out;
+	}
+
+	if (atomic_read(&module_state) != MODULE_ACTIVE)
+		goto dst_unreach;
+
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
+
+	if (!orig_node)
+		goto unlock;
+
+	if (!orig_node->router)
+		goto unlock;
+
+	batman_if = orig_node->router->if_incoming;
+	memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+	if (!batman_if)
+		goto dst_unreach;
+
+	if (batman_if->if_status != IF_ACTIVE)
+		goto dst_unreach;
+
+	memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN);
+
+	if (packet_len == sizeof(struct icmp_packet_rr))
+		memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+
+	send_raw_packet((unsigned char *)&icmp_packet,
+			packet_len, batman_if, dstaddr);
+
+	goto out;
+
+unlock:
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+dst_unreach:
+	icmp_packet.msg_type = DESTINATION_UNREACHABLE;
+	bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
+out:
+	return len;
+}
+
+static unsigned int bat_socket_poll(struct file *file, poll_table *wait)
+{
+	struct socket_client *socket_client = file->private_data;
+
+	poll_wait(file, &socket_client->queue_wait, wait);
+
+	if (socket_client->queue_len > 0)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static const struct file_operations fops = {
+	.owner = THIS_MODULE,
+	.open = bat_socket_open,
+	.release = bat_socket_release,
+	.read = bat_socket_read,
+	.write = bat_socket_write,
+	.poll = bat_socket_poll,
+};
+
+int bat_socket_setup(struct bat_priv *bat_priv)
+{
+	struct dentry *d;
+
+	if (!bat_priv->debug_dir)
+		goto err;
+
+	d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
+				bat_priv->debug_dir, NULL, &fops);
+	if (d)
+		goto err;
+
+	return 0;
+
+err:
+	return 1;
+}
+
+static void bat_socket_add_packet(struct socket_client *socket_client,
+				  struct icmp_packet_rr *icmp_packet,
+				  size_t icmp_len)
+{
+	struct socket_packet *socket_packet;
+	unsigned long flags;
+
+	socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC);
+
+	if (!socket_packet)
+		return;
+
+	INIT_LIST_HEAD(&socket_packet->list);
+	memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len);
+	socket_packet->icmp_len = icmp_len;
+
+	spin_lock_irqsave(&socket_client->lock, flags);
+
+	/* while waiting for the lock the socket_client could have been
+	 * deleted */
+	if (!socket_client_hash[icmp_packet->uid]) {
+		spin_unlock_irqrestore(&socket_client->lock, flags);
+		kfree(socket_packet);
+		return;
+	}
+
+	list_add_tail(&socket_packet->list, &socket_client->queue_list);
+	socket_client->queue_len++;
+
+	if (socket_client->queue_len > 100) {
+		socket_packet = list_first_entry(&socket_client->queue_list,
+						 struct socket_packet, list);
+
+		list_del(&socket_packet->list);
+		kfree(socket_packet);
+		socket_client->queue_len--;
+	}
+
+	spin_unlock_irqrestore(&socket_client->lock, flags);
+
+	wake_up(&socket_client->queue_wait);
+}
+
+void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
+			       size_t icmp_len)
+{
+	struct socket_client *hash = socket_client_hash[icmp_packet->uid];
+
+	if (hash)
+		bat_socket_add_packet(hash, icmp_packet, icmp_len);
+}

+ 11 - 13
drivers/staging/batman-adv/device.h → drivers/staging/batman-adv/icmp_socket.h

@@ -19,18 +19,16 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_
+#define _NET_BATMAN_ADV_ICMP_SOCKET_H_
+
 #include "types.h"
 
-void bat_device_init(void);
-int bat_device_setup(void);
-void bat_device_destroy(void);
-int bat_device_open(struct inode *inode, struct file *file);
-int bat_device_release(struct inode *inode, struct file *file);
-ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
-			loff_t *ppos);
-ssize_t bat_device_write(struct file *file, const char __user *buff,
-			 size_t len, loff_t *off);
-unsigned int bat_device_poll(struct file *file, poll_table *wait);
-void bat_device_add_packet(struct device_client *device_client,
-			   struct icmp_packet *icmp_packet);
-void bat_device_receive_packet(struct icmp_packet *icmp_packet);
+#define ICMP_SOCKET "socket"
+
+void bat_socket_init(void);
+int bat_socket_setup(struct bat_priv *bat_priv);
+void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
+			       size_t icmp_len);
+
+#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */

+ 27 - 35
drivers/staging/batman-adv/main.c

@@ -21,11 +21,12 @@
 
 #include "main.h"
 #include "bat_sysfs.h"
+#include "bat_debugfs.h"
 #include "routing.h"
 #include "send.h"
 #include "originator.h"
 #include "soft-interface.h"
-#include "device.h"
+#include "icmp_socket.h"
 #include "translation-table.h"
 #include "hard-interface.h"
 #include "types.h"
@@ -41,7 +42,6 @@ DEFINE_SPINLOCK(orig_hash_lock);
 DEFINE_SPINLOCK(forw_bat_list_lock);
 DEFINE_SPINLOCK(forw_bcast_list_lock);
 
-atomic_t vis_interval;
 atomic_t bcast_queue_left;
 atomic_t batman_queue_left;
 
@@ -49,7 +49,7 @@ int16_t num_hna;
 
 struct net_device *soft_device;
 
-unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 atomic_t module_state;
 
 static struct packet_type batman_adv_packet_type __read_mostly = {
@@ -59,18 +59,7 @@ static struct packet_type batman_adv_packet_type __read_mostly = {
 
 struct workqueue_struct *bat_event_workqueue;
 
-#ifdef CONFIG_BATMAN_ADV_DEBUG
-int debug;
-
-module_param(debug, int, 0644);
-
-int bat_debug_type(int type)
-{
-	return debug & type;
-}
-#endif
-
-int init_module(void)
+static int __init batman_init(void)
 {
 	int retval;
 
@@ -80,8 +69,6 @@ int init_module(void)
 
 	atomic_set(&module_state, MODULE_INACTIVE);
 
-	atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
-					 * for debugging now. */
 	atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN);
 	atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
 
@@ -92,23 +79,22 @@ int init_module(void)
 	if (!bat_event_workqueue)
 		return -ENOMEM;
 
-	bat_device_init();
+	bat_socket_init();
+	debugfs_init();
 
 	/* initialize layer 2 interface */
 	soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d",
 				   interface_setup);
 
 	if (!soft_device) {
-		printk(KERN_ERR "batman-adv:"
-		       "Unable to allocate the batman interface\n");
+		pr_err("Unable to allocate the batman interface\n");
 		goto end;
 	}
 
 	retval = register_netdev(soft_device);
 
 	if (retval < 0) {
-		printk(KERN_ERR "batman-adv:"
-		       "Unable to register the batman interface: %i\n", retval);
+		pr_err("Unable to register the batman interface: %i\n", retval);
 		goto free_soft_device;
 	}
 
@@ -117,15 +103,22 @@ int init_module(void)
 	if (retval < 0)
 		goto unreg_soft_device;
 
+	retval = debugfs_add_meshif(soft_device);
+
+	if (retval < 0)
+		goto unreg_sysfs;
+
 	register_netdevice_notifier(&hard_if_notifier);
 	dev_add_pack(&batman_adv_packet_type);
 
-	printk(KERN_INFO "batman-adv:"
-	       "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n",
-	       SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
+	pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
+		"loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
+		COMPAT_VERSION);
 
 	return 0;
 
+unreg_sysfs:
+	sysfs_del_meshif(soft_device);
 unreg_soft_device:
 	unregister_netdev(soft_device);
 	soft_device = NULL;
@@ -138,14 +131,16 @@ end:
 	return -ENOMEM;
 }
 
-void cleanup_module(void)
+static void __exit batman_exit(void)
 {
 	deactivate_module();
 
+	debugfs_destroy();
 	unregister_netdevice_notifier(&hard_if_notifier);
 	hardif_remove_interfaces();
 
 	if (soft_device) {
+		debugfs_del_meshif(soft_device);
 		sysfs_del_meshif(soft_device);
 		unregister_netdev(soft_device);
 		soft_device = NULL;
@@ -157,7 +152,7 @@ void cleanup_module(void)
 	bat_event_workqueue = NULL;
 }
 
-/* activates the module, creates bat device, starts timer ... */
+/* activates the module, starts timer ... */
 void activate_module(void)
 {
 	if (originator_init() < 1)
@@ -171,9 +166,6 @@ void activate_module(void)
 
 	hna_local_add(soft_device->dev_addr);
 
-	if (bat_device_setup() < 1)
-		goto end;
-
 	if (vis_init() < 1)
 		goto err;
 
@@ -182,8 +174,7 @@ void activate_module(void)
 	goto end;
 
 err:
-	printk(KERN_ERR "batman-adv:"
-	       "Unable to allocate memory for mesh information structures: "
+	pr_err("Unable to allocate memory for mesh information structures: "
 	       "out of mem ?\n");
 	deactivate_module();
 end:
@@ -208,7 +199,6 @@ void deactivate_module(void)
 	hna_global_free();
 
 	synchronize_net();
-	bat_device_destroy();
 
 	synchronize_rcu();
 	atomic_set(&module_state, MODULE_INACTIVE);
@@ -226,8 +216,7 @@ void dec_module_count(void)
 
 int addr_to_string(char *buff, uint8_t *addr)
 {
-	return sprintf(buff, MAC_FMT,
-		       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+	return sprintf(buff, "%pM", addr);
 }
 
 /* returns 1 if they are the same originator */
@@ -284,6 +273,9 @@ int is_mcast(uint8_t *addr)
 	return *addr & 0x01;
 }
 
+module_init(batman_init);
+module_exit(batman_exit);
+
 MODULE_LICENSE("GPL");
 
 MODULE_AUTHOR(DRIVER_AUTHOR);

+ 62 - 20
drivers/staging/batman-adv/main.h

@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_MAIN_H_
+#define _NET_BATMAN_ADV_MAIN_H_
+
 /* Kernel Programming */
 #define LINUX
 
@@ -27,7 +30,7 @@
 #define DRIVER_DESC   "B.A.T.M.A.N. advanced"
 #define DRIVER_DEVICE "batman-adv"
 
-#define SOURCE_VERSION "0.2.2-beta"
+#define SOURCE_VERSION "maint"
 
 
 /* B.A.T.M.A.N. parameters */
@@ -36,10 +39,10 @@
 #define JITTER 20
 #define TTL 50			  /* Time To Live of broadcast messages */
 
-#define PURGE_TIMEOUT 200000	  /* purge originators after time in ms if no
+#define PURGE_TIMEOUT 200	/* purge originators after time in seconds if no
 				   * valid packet comes in -> TODO: check
 				   * influence on TQ_LOCAL_WINDOW_SIZE */
-#define LOCAL_HNA_TIMEOUT 3600000
+#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
 
 #define TQ_LOCAL_WINDOW_SIZE 64	  /* sliding packet range of received originator
 				   * messages in squence numbers (should be a
@@ -57,44 +60,42 @@
 #define LOG_BUF_LEN 8192	  /* has to be a power of 2 */
 #define ETH_STR_LEN 20
 
+#define VIS_INTERVAL 5000	/* 5 seconds */
+
+/* how much worse secondary interfaces may be to
+ * to be considered as bonding candidates */
+
+#define BONDING_TQ_THRESHOLD	50
+
 #define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
 				   * change the size of
 				   * forw_packet->direct_link_flags */
 #define MAX_AGGREGATION_MS 100
 
 #define RESET_PROTECTION_MS 30000
-#define EXPECTED_SEQNO_RANGE	4096
+#define EXPECTED_SEQNO_RANGE	65536
 /* don't reset again within 30 seconds */
 
 #define MODULE_INACTIVE 0
 #define MODULE_ACTIVE 1
 #define MODULE_DEACTIVATING 2
 
-#define BCAST_QUEUE_LEN 256
+#define BCAST_QUEUE_LEN		256
 #define BATMAN_QUEUE_LEN	256
 
 /*
  * Debug Messages
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
+					     * kernel messages */
 
 #define DBG_BATMAN 1	/* all messages related to routing / flooding /
 			 * broadcasting / etc */
 #define DBG_ROUTES 2	/* route or hna added / changed / deleted */
+#define DBG_ALL 3
 
-#ifdef CONFIG_BATMAN_ADV_DEBUG
-extern int debug;
+#define LOG_BUF_LEN 8192          /* has to be a power of 2 */
 
-extern int bat_debug_type(int type);
-#define bat_dbg(type, fmt, arg...) do {					\
-		if (bat_debug_type(type))				\
-			printk(KERN_DEBUG "batman-adv:" fmt, ## arg);	\
-	}								\
-	while (0)
-#else /* !CONFIG_BATMAN_ADV_DEBUG */
-#define bat_dbg(type, fmt, arg...) do {		\
-	}					\
-	while (0)
-#endif
 
 /*
  *  Vis
@@ -117,6 +118,7 @@ extern int bat_debug_type(int type);
 #include <linux/slab.h>
 #include <net/sock.h>		/* struct sock */
 #include <linux/jiffies.h>
+#include <linux/seq_file.h>
 #include "types.h"
 
 #ifndef REVISION_VERSION
@@ -134,14 +136,13 @@ extern spinlock_t orig_hash_lock;
 extern spinlock_t forw_bat_list_lock;
 extern spinlock_t forw_bcast_list_lock;
 
-extern atomic_t vis_interval;
 extern atomic_t bcast_queue_left;
 extern atomic_t batman_queue_left;
 extern int16_t num_hna;
 
 extern struct net_device *soft_device;
 
-extern unsigned char broadcastAddr[];
+extern unsigned char broadcast_addr[];
 extern atomic_t module_state;
 extern struct workqueue_struct *bat_event_workqueue;
 
@@ -155,3 +156,44 @@ int choose_orig(void *data, int32_t size);
 int is_my_mac(uint8_t *addr);
 int is_bcast(uint8_t *addr);
 int is_mcast(uint8_t *addr);
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+extern int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
+
+#define bat_dbg(type, bat_priv, fmt, arg...)			\
+	do {							\
+		if (atomic_read(&bat_priv->log_level) & type)	\
+			debug_log(bat_priv, fmt, ## arg);	\
+	}							\
+	while (0)
+#else /* !CONFIG_BATMAN_ADV_DEBUG */
+static inline void bat_dbg(char type __attribute__((unused)),
+			   struct bat_priv *bat_priv __attribute__((unused)),
+			   char *fmt __attribute__((unused)), ...)
+{
+}
+#endif
+
+#define bat_warning(net_dev, fmt, arg...)				\
+	do {								\
+		struct net_device *_netdev = (net_dev);                 \
+		struct bat_priv *_batpriv = netdev_priv(_netdev);       \
+		bat_dbg(DBG_ALL, _batpriv, fmt, ## arg);		\
+		pr_warning("%s: " fmt, _netdev->name, ## arg);		\
+	} while (0)
+#define bat_info(net_dev, fmt, arg...)					\
+	do {								\
+		struct net_device *_netdev = (net_dev);                 \
+		struct bat_priv *_batpriv = netdev_priv(_netdev);       \
+		bat_dbg(DBG_ALL, _batpriv, fmt, ## arg);		\
+		pr_info("%s: " fmt, _netdev->name, ## arg);		\
+	} while (0)
+#define bat_err(net_dev, fmt, arg...)					\
+	do {								\
+		struct net_device *_netdev = (net_dev);                 \
+		struct bat_priv *_batpriv = netdev_priv(_netdev);       \
+		bat_dbg(DBG_ALL, _batpriv, fmt, ## arg);		\
+		pr_err("%s: " fmt, _netdev->name, ## arg);		\
+	} while (0)
+
+#endif /* _NET_BATMAN_ADV_MAIN_H_ */

+ 72 - 84
drivers/staging/batman-adv/originator.c

@@ -56,28 +56,16 @@ err:
 	return 0;
 }
 
-void originator_free(void)
-{
-	unsigned long flags;
-
-	if (!orig_hash)
-		return;
-
-	cancel_delayed_work_sync(&purge_orig_wq);
-
-	spin_lock_irqsave(&orig_hash_lock, flags);
-	hash_delete(orig_hash, free_orig_node);
-	orig_hash = NULL;
-	spin_unlock_irqrestore(&orig_hash_lock, flags);
-}
-
 struct neigh_node *
 create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
 		uint8_t *neigh, struct batman_if *if_incoming)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct neigh_node *neigh_node;
 
-	bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Creating new last-hop neighbor of originator\n");
 
 	neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
 	if (!neigh_node)
@@ -93,7 +81,7 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
 	return neigh_node;
 }
 
-void free_orig_node(void *data)
+static void free_orig_node(void *data)
 {
 	struct list_head *list_pos, *list_pos_tmp;
 	struct neigh_node *neigh_node;
@@ -114,6 +102,21 @@ void free_orig_node(void *data)
 	kfree(orig_node);
 }
 
+void originator_free(void)
+{
+	unsigned long flags;
+
+	if (!orig_hash)
+		return;
+
+	cancel_delayed_work_sync(&purge_orig_wq);
+
+	spin_lock_irqsave(&orig_hash_lock, flags);
+	hash_delete(orig_hash, free_orig_node);
+	orig_hash = NULL;
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
+}
+
 /* this function finds or creates an originator entry for the given
  * address if it does not exits */
 struct orig_node *get_orig_node(uint8_t *addr)
@@ -129,7 +132,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
 	if (orig_node != NULL)
 		return orig_node;
 
-	bat_dbg(DBG_BATMAN, "Creating new originator: %pM\n", addr);
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Creating new originator: %pM\n", addr);
 
 	orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
 	if (!orig_node)
@@ -163,8 +167,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
 		swaphash = hash_resize(orig_hash, orig_hash->size * 2);
 
 		if (swaphash == NULL)
-			printk(KERN_ERR
-			       "batman-adv:Couldn't resize orig hash table\n");
+			bat_err(soft_device,
+				"Couldn't resize orig hash table\n");
 		else
 			orig_hash = swaphash;
 	}
@@ -182,6 +186,8 @@ free_orig_node:
 static bool purge_orig_neighbors(struct orig_node *orig_node,
 				 struct neigh_node **best_neigh_node)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct list_head *list_pos, *list_pos_tmp;
 	struct neigh_node *neigh_node;
 	bool neigh_purged = false;
@@ -193,20 +199,19 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
 		neigh_node = list_entry(list_pos, struct neigh_node, list);
 
 		if ((time_after(jiffies,
-			       (neigh_node->last_valid +
-				((PURGE_TIMEOUT * HZ) / 1000)))) ||
+			neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
 		    (neigh_node->if_incoming->if_status ==
 						IF_TO_BE_REMOVED)) {
 
 			if (neigh_node->if_incoming->if_status ==
 							IF_TO_BE_REMOVED)
-				bat_dbg(DBG_BATMAN,
+				bat_dbg(DBG_BATMAN, bat_priv,
 					"neighbor purge: originator %pM, "
 					"neighbor: %pM, iface: %s\n",
 					orig_node->orig, neigh_node->addr,
 					neigh_node->if_incoming->dev);
 			else
-				bat_dbg(DBG_BATMAN,
+				bat_dbg(DBG_BATMAN, bat_priv,
 					"neighbor timeout: originator %pM, "
 					"neighbor: %pM, last_valid: %lu\n",
 					orig_node->orig, neigh_node->addr,
@@ -226,21 +231,26 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
 
 static bool purge_orig_node(struct orig_node *orig_node)
 {
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct neigh_node *best_neigh_node;
 
 	if (time_after(jiffies,
-		       (orig_node->last_valid +
-			((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
+		orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) {
 
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Originator timeout: originator %pM, last_valid %lu\n",
 			orig_node->orig, (orig_node->last_valid / HZ));
 		return true;
 	} else {
-		if (purge_orig_neighbors(orig_node, &best_neigh_node))
+		if (purge_orig_neighbors(orig_node, &best_neigh_node)) {
 			update_routes(orig_node, best_neigh_node,
 				      orig_node->hna_buff,
 				      orig_node->hna_buff_len);
+			/* update bonding candidates, we could have lost
+			 * some candidates. */
+			update_bonding_candidates(bat_priv, orig_node);
+		}
 	}
 
 	return false;
@@ -271,49 +281,41 @@ void purge_orig(struct work_struct *work)
 		start_purge_timer();
 }
 
-ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
-			      size_t count, loff_t off)
+int orig_seq_print_text(struct seq_file *seq, void *offset)
 {
 	HASHIT(hashit);
+	struct net_device *net_dev = (struct net_device *)seq->private;
 	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct orig_node *orig_node;
 	struct neigh_node *neigh_node;
-	size_t hdr_len, tmp_len;
-	int batman_count = 0, bytes_written = 0;
+	int batman_count = 0;
+	int last_seen_secs;
+	int last_seen_msecs;
 	unsigned long flags;
 	char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
 
-	if (!bat_priv->primary_if) {
-		if (off == 0)
-			return sprintf(buff,
-				     "BATMAN mesh %s disabled - "
+	if ((!bat_priv->primary_if) ||
+	    (bat_priv->primary_if->if_status != IF_ACTIVE)) {
+		if (!bat_priv->primary_if)
+			return seq_printf(seq, "BATMAN mesh %s disabled - "
 				     "please specify interfaces to enable it\n",
 				     net_dev->name);
 
-		return 0;
+		return seq_printf(seq, "BATMAN mesh %s "
+				  "disabled - primary interface not active\n",
+				  net_dev->name);
 	}
 
-	if (bat_priv->primary_if->if_status != IF_ACTIVE && off == 0)
-		return sprintf(buff,
-			       "BATMAN mesh %s "
-			       "disabled - primary interface not active\n",
-			       net_dev->name);
-	else if (bat_priv->primary_if->if_status != IF_ACTIVE)
-		return 0;
-
 	rcu_read_lock();
-	hdr_len = sprintf(buff,
-		   "  %-14s (%s/%i) %17s [%10s]: %20s "
-		   "... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
-		   "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
-		   "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
+	seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
+		   SOURCE_VERSION, REVISION_VERSION_STR,
 		   bat_priv->primary_if->dev, bat_priv->primary_if->addr_str,
 		   net_dev->name);
+	seq_printf(seq, "  %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
+		   "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
+		   "outgoingIF", "Potential nexthops");
 	rcu_read_unlock();
 
-	if (off < hdr_len)
-		bytes_written = hdr_len;
-
 	spin_lock_irqsave(&orig_hash_lock, flags);
 
 	while (hash_iterate(orig_hash, &hashit)) {
@@ -326,44 +328,34 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
 		if (orig_node->router->tq_avg == 0)
 			continue;
 
-		/* estimated line length */
-		if (count < bytes_written + 200)
-			break;
-
 		addr_to_string(orig_str, orig_node->orig);
 		addr_to_string(router_str, orig_node->router->addr);
+		last_seen_secs = jiffies_to_msecs(jiffies -
+						orig_node->last_valid) / 1000;
+		last_seen_msecs = jiffies_to_msecs(jiffies -
+						orig_node->last_valid) % 1000;
 
-		tmp_len = sprintf(buff + bytes_written,
-				  "%-17s  (%3i) %17s [%10s]:",
-				   orig_str, orig_node->router->tq_avg,
-				   router_str,
-				   orig_node->router->if_incoming->dev);
+		seq_printf(seq, "%-17s %4i.%03is   (%3i) %17s [%10s]:",
+			   orig_str, last_seen_secs, last_seen_msecs,
+			   orig_node->router->tq_avg, router_str,
+			   orig_node->router->if_incoming->dev);
 
 		list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
 			addr_to_string(orig_str, neigh_node->addr);
-			tmp_len += sprintf(buff + bytes_written + tmp_len,
-					   " %17s (%3i)", orig_str,
+			seq_printf(seq, " %17s (%3i)", orig_str,
 					   neigh_node->tq_avg);
 		}
 
-		tmp_len += sprintf(buff + bytes_written + tmp_len, "\n");
-
+		seq_printf(seq, "\n");
 		batman_count++;
-		hdr_len += tmp_len;
-
-		if (off >= hdr_len)
-			continue;
-
-		bytes_written += tmp_len;
 	}
 
 	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-	if ((batman_count == 0) && (off == 0))
-		bytes_written += sprintf(buff + bytes_written,
-					"No batman nodes in range ...\n");
+	if ((batman_count == 0))
+		seq_printf(seq, "No batman nodes in range ...\n");
 
-	return bytes_written;
+	return 0;
 }
 
 static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
@@ -373,8 +365,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
 	data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS,
 			   GFP_ATOMIC);
 	if (!data_ptr) {
-		printk(KERN_ERR
-		       "batman-adv:Can't resize orig: out of memory\n");
+		pr_err("Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -385,8 +376,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
 
 	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
 	if (!data_ptr) {
-		printk(KERN_ERR
-		       "batman-adv:Can't resize orig: out of memory\n");
+		pr_err("Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -435,8 +425,7 @@ static int orig_node_del_if(struct orig_node *orig_node,
 	chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS;
 	data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
 	if (!data_ptr) {
-		printk(KERN_ERR
-		       "batman-adv:Can't resize orig: out of memory\n");
+		pr_err("Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -457,8 +446,7 @@ free_bcast_own:
 
 	data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
 	if (!data_ptr) {
-		printk(KERN_ERR
-		       "batman-adv:Can't resize orig: out of memory\n");
+		pr_err("Can't resize orig: out of memory\n");
 		return -1;
 	}
 

+ 6 - 4
drivers/staging/batman-adv/originator.h

@@ -19,16 +19,18 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
+#define _NET_BATMAN_ADV_ORIGINATOR_H_
+
 int originator_init(void);
-void free_orig_node(void *data);
 void originator_free(void);
 void purge_orig(struct work_struct *work);
-struct orig_node *orig_find(char *mac);
 struct orig_node *get_orig_node(uint8_t *addr);
 struct neigh_node *
 create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
 		uint8_t *neigh, struct batman_if *if_incoming);
-ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
-			      size_t count, loff_t off);
+int orig_seq_print_text(struct seq_file *seq, void *offset);
 int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
 int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
+
+#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */

+ 28 - 4
drivers/staging/batman-adv/packet.h

@@ -19,6 +19,9 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_PACKET_H_
+#define _NET_BATMAN_ADV_PACKET_H_
+
 #define ETH_P_BATMAN  0x4305	/* unofficial/not registered Ethertype */
 
 #define BAT_PACKET    0x01
@@ -28,9 +31,10 @@
 #define BAT_VIS       0x05
 
 /* this file is included by batctl which needs these defines */
-#define COMPAT_VERSION 8
+#define COMPAT_VERSION 11
 #define DIRECTLINK 0x40
 #define VIS_SERVER 0x20
+#define PRIMARIES_FIRST_HOP 0x10
 
 /* ICMP message types */
 #define ECHO_REPLY 0
@@ -48,7 +52,7 @@ struct batman_packet {
 	uint8_t  version;  /* batman version field */
 	uint8_t  flags;    /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
 	uint8_t  tq;
-	uint16_t seqno;
+	uint32_t seqno;
 	uint8_t  orig[6];
 	uint8_t  prev_sender[6];
 	uint8_t  ttl;
@@ -68,6 +72,23 @@ struct icmp_packet {
 	uint8_t  uid;
 } __attribute__((packed));
 
+#define BAT_RR_LEN 16
+
+/* icmp_packet_rr must start with all fields from imcp_packet
+   as this is assumed by code that handles ICMP packets */
+struct icmp_packet_rr {
+	uint8_t  packet_type;
+	uint8_t  version;  /* batman version field */
+	uint8_t  msg_type; /* see ICMP message types above */
+	uint8_t  ttl;
+	uint8_t  dst[6];
+	uint8_t  orig[6];
+	uint16_t seqno;
+	uint8_t  uid;
+	uint8_t  rr_cur;
+	uint8_t  rr[BAT_RR_LEN][ETH_ALEN];
+} __attribute__((packed));
+
 struct unicast_packet {
 	uint8_t  packet_type;
 	uint8_t  version;  /* batman version field */
@@ -79,18 +100,21 @@ struct bcast_packet {
 	uint8_t  packet_type;
 	uint8_t  version;  /* batman version field */
 	uint8_t  orig[6];
-	uint16_t seqno;
+	uint8_t  ttl;
+	uint32_t seqno;
 } __attribute__((packed));
 
 struct vis_packet {
 	uint8_t  packet_type;
 	uint8_t  version;        /* batman version field */
 	uint8_t  vis_type;	 /* which type of vis-participant sent this? */
-	uint8_t  seqno;		 /* sequence number */
 	uint8_t  entries;	 /* number of entries behind this struct */
+	uint32_t seqno;		 /* sequence number */
 	uint8_t  ttl;		 /* TTL */
 	uint8_t  vis_orig[6];	 /* originator that informs about its
 				  * neighbors */
 	uint8_t  target_orig[6]; /* who should receive this packet */
 	uint8_t  sender_orig[6]; /* who sent or rebroadcasted this packet */
 } __attribute__((packed));
+
+#endif /* _NET_BATMAN_ADV_PACKET_H_ */

+ 5 - 0
drivers/staging/batman-adv/ring_buffer.h

@@ -19,5 +19,10 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_
+#define _NET_BATMAN_ADV_RING_BUFFER_H_
+
 void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
 uint8_t ring_buffer_avg(uint8_t lq_recv[]);
+
+#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */

+ 322 - 84
drivers/staging/batman-adv/routing.c

@@ -25,7 +25,7 @@
 #include "hash.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
-#include "device.h"
+#include "icmp_socket.h"
 #include "translation-table.h"
 #include "originator.h"
 #include "types.h"
@@ -33,7 +33,7 @@
 #include "vis.h"
 #include "aggregation.h"
 
-DECLARE_WAIT_QUEUE_HEAD(thread_wait);
+static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
 
 void slide_own_bcast_window(struct batman_if *batman_if)
 {
@@ -77,24 +77,27 @@ static void update_route(struct orig_node *orig_node,
 			 struct neigh_node *neigh_node,
 			 unsigned char *hna_buff, int hna_buff_len)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+
 	/* route deleted */
 	if ((orig_node->router != NULL) && (neigh_node == NULL)) {
 
-		bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
+		bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
 			orig_node->orig);
 		hna_global_del_orig(orig_node, "originator timed out");
 
 		/* route added */
 	} else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
 
-		bat_dbg(DBG_ROUTES,
+		bat_dbg(DBG_ROUTES, bat_priv,
 			"Adding route towards: %pM (via %pM)\n",
 			orig_node->orig, neigh_node->addr);
 		hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
 
 		/* route changed */
 	} else {
-		bat_dbg(DBG_ROUTES,
+		bat_dbg(DBG_ROUTES, bat_priv,
 			"Changing route towards: %pM "
 			"(now via %pM - was via %pM)\n",
 			orig_node->orig, neigh_node->addr,
@@ -120,11 +123,13 @@ void update_routes(struct orig_node *orig_node,
 		update_HNA(orig_node, hna_buff, hna_buff_len);
 }
 
-static int isBidirectionalNeigh(struct orig_node *orig_node,
+static int is_bidirectional_neigh(struct orig_node *orig_node,
 				struct orig_node *orig_neigh_node,
 				struct batman_packet *batman_packet,
 				struct batman_if *if_incoming)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
 	unsigned char total_count;
 
@@ -211,7 +216,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node,
 			      orig_neigh_node->tq_asym_penalty) /
 			     (TQ_MAX_VALUE * TQ_MAX_VALUE));
 
-	bat_dbg(DBG_BATMAN,
+	bat_dbg(DBG_BATMAN, bat_priv,
 		"bidirectional: "
 		"orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
 		"real recv = %2i, local tq: %3i, asym_penalty: %3i, "
@@ -234,10 +239,12 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
 			unsigned char *hna_buff, int hna_buff_len,
 			char is_duplicate)
 {
+	/* FIXME: get bat_priv */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
 	int tmp_hna_buff_len;
 
-	bat_dbg(DBG_BATMAN, "update_originator(): "
+	bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
 		"Searching and updating originator entry of received packet\n");
 
 	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
@@ -269,7 +276,7 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
 		if (!neigh_node)
 			return;
 	} else
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Updating existing last-hop neighbor of originator\n");
 
 	orig_node->flags = batman_packet->flags;
@@ -318,16 +325,19 @@ update_hna:
  *  0 if the packet is to be accepted
  *  1 if the packet is to be ignored.
  */
-static int window_protected(int16_t seq_num_diff,
+static int window_protected(int32_t seq_num_diff,
 				unsigned long *last_reset)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+
 	if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
 		|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
 		if (time_after(jiffies, *last_reset +
 			msecs_to_jiffies(RESET_PROTECTION_MS))) {
 
 			*last_reset = jiffies;
-			bat_dbg(DBG_BATMAN,
+			bat_dbg(DBG_BATMAN, bat_priv,
 				"old packet received, start protection\n");
 
 			return 0;
@@ -349,10 +359,12 @@ static char count_real_packets(struct ethhdr *ethhdr,
 			       struct batman_packet *batman_packet,
 			       struct batman_if *if_incoming)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct orig_node *orig_node;
 	struct neigh_node *tmp_neigh_node;
 	char is_duplicate = 0;
-	int16_t seq_diff;
+	int32_t seq_diff;
 	int need_update = 0;
 	int set_mark;
 
@@ -387,7 +399,8 @@ static char count_real_packets(struct ethhdr *ethhdr,
 	}
 
 	if (need_update) {
-		bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n",
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"updating last_seqno: old %d, new %d\n",
 			orig_node->last_real_seqno, batman_packet->seqno);
 		orig_node->last_real_seqno = batman_packet->seqno;
 	}
@@ -395,18 +408,127 @@ static char count_real_packets(struct ethhdr *ethhdr,
 	return is_duplicate;
 }
 
+/* copy primary address for bonding */
+static void mark_bonding_address(struct bat_priv *bat_priv,
+				 struct orig_node *orig_node,
+				 struct orig_node *orig_neigh_node,
+				 struct batman_packet *batman_packet)
+
+{
+	if (batman_packet->flags & PRIMARIES_FIRST_HOP)
+		memcpy(orig_neigh_node->primary_addr,
+		       orig_node->orig, ETH_ALEN);
+
+	return;
+}
+
+/* mark possible bond.candidates in the neighbor list */
+void update_bonding_candidates(struct bat_priv *bat_priv,
+			       struct orig_node *orig_node)
+{
+	int candidates;
+	int interference_candidate;
+	int best_tq;
+	struct neigh_node *tmp_neigh_node, *tmp_neigh_node2;
+	struct neigh_node *first_candidate, *last_candidate;
+
+	/* update the candidates for this originator */
+	if (!orig_node->router) {
+		orig_node->bond.candidates = 0;
+		return;
+	}
+
+	best_tq = orig_node->router->tq_avg;
+
+	/* update bond.candidates */
+
+	candidates = 0;
+
+	/* mark other nodes which also received "PRIMARIES FIRST HOP" packets
+	 * as "bonding partner" */
+
+	/* first, zero the list */
+	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+		tmp_neigh_node->next_bond_candidate = NULL;
+	}
+
+	first_candidate = NULL;
+	last_candidate = NULL;
+	list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+
+		/* only consider if it has the same primary address ...  */
+		if (memcmp(orig_node->orig,
+				tmp_neigh_node->orig_node->primary_addr,
+				ETH_ALEN) != 0)
+			continue;
+
+		/* ... and is good enough to be considered */
+		if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
+			continue;
+
+		/* check if we have another candidate with the same
+		 * mac address or interface. If we do, we won't
+		 * select this candidate because of possible interference. */
+
+		interference_candidate = 0;
+		list_for_each_entry(tmp_neigh_node2,
+				&orig_node->neigh_list, list) {
+
+			if (tmp_neigh_node2 == tmp_neigh_node)
+				continue;
+
+			/* we only care if the other candidate is even
+			 * considered as candidate. */
+			if (tmp_neigh_node2->next_bond_candidate == NULL)
+				continue;
+
+
+			if ((tmp_neigh_node->if_incoming ==
+				tmp_neigh_node2->if_incoming)
+				|| (memcmp(tmp_neigh_node->addr,
+				tmp_neigh_node2->addr, ETH_ALEN) == 0)) {
+
+				interference_candidate = 1;
+				break;
+			}
+		}
+		/* don't care further if it is an interference candidate */
+		if (interference_candidate)
+			continue;
+
+		if (first_candidate == NULL) {
+			first_candidate = tmp_neigh_node;
+			tmp_neigh_node->next_bond_candidate = first_candidate;
+		} else
+			tmp_neigh_node->next_bond_candidate = last_candidate;
+
+		last_candidate = tmp_neigh_node;
+
+		candidates++;
+	}
+
+	if (candidates > 0) {
+		first_candidate->next_bond_candidate = last_candidate;
+		orig_node->bond.selected = first_candidate;
+	}
+
+	orig_node->bond.candidates = candidates;
+}
+
 void receive_bat_packet(struct ethhdr *ethhdr,
 				struct batman_packet *batman_packet,
 				unsigned char *hna_buff, int hna_buff_len,
 				struct batman_if *if_incoming)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct batman_if *batman_if;
 	struct orig_node *orig_neigh_node, *orig_node;
 	char has_directlink_flag;
 	char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
 	char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
 	char is_duplicate;
-	unsigned short if_incoming_seqno;
+	uint32_t if_incoming_seqno;
 
 	/* Silently drop when the batman packet is actually not a
 	 * correct packet.
@@ -431,7 +553,8 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 	is_single_hop_neigh = (compare_orig(ethhdr->h_source,
 					    batman_packet->orig) ? 1 : 0);
 
-	bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] "
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Received BATMAN packet via NB: %pM, IF: %s [%s] "
 		"(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, "
 		"TTL %d, V %d, IDF %d)\n",
 		ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
@@ -455,19 +578,19 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 				 batman_if->net_dev->dev_addr))
 			is_my_oldorig = 1;
 
-		if (compare_orig(ethhdr->h_source, broadcastAddr))
+		if (compare_orig(ethhdr->h_source, broadcast_addr))
 			is_broadcast = 1;
 	}
 
 	if (batman_packet->version != COMPAT_VERSION) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: incompatible batman version (%i)\n",
 			batman_packet->version);
 		return;
 	}
 
 	if (is_my_addr) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: received my own broadcast (sender: %pM"
 			")\n",
 			ethhdr->h_source);
@@ -475,7 +598,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 	}
 
 	if (is_broadcast) {
-		bat_dbg(DBG_BATMAN, "Drop packet: "
+		bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
 		"ignoring all packets with broadcast source addr (sender: %pM"
 		")\n", ethhdr->h_source);
 		return;
@@ -505,13 +628,13 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 				bit_packet_count(word);
 		}
 
-		bat_dbg(DBG_BATMAN, "Drop packet: "
+		bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
 			"originator packet from myself (via neighbor)\n");
 		return;
 	}
 
 	if (is_my_oldorig) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: ignoring all rebroadcast echos (sender: "
 			"%pM)\n", ethhdr->h_source);
 		return;
@@ -524,14 +647,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 	is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
 
 	if (is_duplicate == -1) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: packet within seqno protection time "
 			"(sender: %pM)\n", ethhdr->h_source);
 		return;
 	}
 
 	if (batman_packet->tq == 0) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: originator packet with tq equal 0\n");
 		return;
 	}
@@ -544,7 +667,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 	    !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
 	    (compare_orig(orig_node->router->addr,
 			  orig_node->router->orig_node->router->addr))) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: ignoring all rebroadcast packets that "
 			"may make me loop (sender: %pM)\n", ethhdr->h_source);
 		return;
@@ -561,11 +684,12 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 	 * don't route towards it */
 	if (!is_single_hop_neigh &&
 	    (orig_neigh_node->router == NULL)) {
-		bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n");
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: OGM via unknown neighbor!\n");
 		return;
 	}
 
-	is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
+	is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node,
 						batman_packet, if_incoming);
 
 	/* update ranking if it is not a duplicate or has the same
@@ -577,6 +701,10 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 		update_orig(orig_node, ethhdr, batman_packet,
 			    if_incoming, hna_buff, hna_buff_len, is_duplicate);
 
+	mark_bonding_address(bat_priv, orig_node,
+			     orig_neigh_node, batman_packet);
+	update_bonding_candidates(bat_priv, orig_node);
+
 	/* is single hop (direct) neighbor */
 	if (is_single_hop_neigh) {
 
@@ -584,24 +712,25 @@ void receive_bat_packet(struct ethhdr *ethhdr,
 		schedule_forward_packet(orig_node, ethhdr, batman_packet,
 					1, hna_buff_len, if_incoming);
 
-		bat_dbg(DBG_BATMAN, "Forwarding packet: "
+		bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
 			"rebroadcast neighbor packet with direct link flag\n");
 		return;
 	}
 
 	/* multihop originator */
 	if (!is_bidirectional) {
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: not received via bidirectional link\n");
 		return;
 	}
 
 	if (is_duplicate) {
-		bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"Drop packet: duplicate packet received\n");
 		return;
 	}
 
-	bat_dbg(DBG_BATMAN,
+	bat_dbg(DBG_BATMAN, bat_priv,
 		"Forwarding packet: rebroadcast originator packet\n");
 	schedule_forward_packet(orig_node, ethhdr, batman_packet,
 				0, hna_buff_len, if_incoming);
@@ -652,10 +781,10 @@ int recv_bat_packet(struct sk_buff *skb,
 	return NET_RX_SUCCESS;
 }
 
-static int recv_my_icmp_packet(struct sk_buff *skb)
+static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
 {
 	struct orig_node *orig_node;
-	struct icmp_packet *icmp_packet;
+	struct icmp_packet_rr *icmp_packet;
 	struct ethhdr *ethhdr;
 	struct sk_buff *skb_old;
 	struct batman_if *batman_if;
@@ -663,12 +792,12 @@ static int recv_my_icmp_packet(struct sk_buff *skb)
 	unsigned long flags;
 	uint8_t dstaddr[ETH_ALEN];
 
-	icmp_packet = (struct icmp_packet *)skb->data;
+	icmp_packet = (struct icmp_packet_rr *)skb->data;
 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
 
 	/* add data to device queue */
 	if (icmp_packet->msg_type != ECHO_REQUEST) {
-		bat_device_receive_packet(icmp_packet);
+		bat_socket_receive_packet(icmp_packet, icmp_len);
 		return NET_RX_DROP;
 	}
 
@@ -690,13 +819,12 @@ static int recv_my_icmp_packet(struct sk_buff *skb)
 
 		/* create a copy of the skb, if needed, to modify it. */
 		skb_old = NULL;
-		if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+		if (!skb_clone_writable(skb, icmp_len)) {
 			skb_old = skb;
 			skb = skb_copy(skb, GFP_ATOMIC);
 			if (!skb)
 				return NET_RX_DROP;
-
-			icmp_packet = (struct icmp_packet *)skb->data;
+			icmp_packet = (struct icmp_packet_rr *)skb->data;
 			ethhdr = (struct ethhdr *)skb_mac_header(skb);
 			kfree_skb(skb_old);
 		}
@@ -715,7 +843,7 @@ static int recv_my_icmp_packet(struct sk_buff *skb)
 	return ret;
 }
 
-static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
+static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
 {
 	struct orig_node *orig_node;
 	struct icmp_packet *icmp_packet;
@@ -731,10 +859,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
 
 	/* send TTL exceeded if packet is an echo request (traceroute) */
 	if (icmp_packet->msg_type != ECHO_REQUEST) {
-		printk(KERN_WARNING "batman-adv:"
-		       "Warning - can't forward icmp packet from %pM to %pM: "
-		       "ttl exceeded\n",
-		       icmp_packet->orig, icmp_packet->dst);
+		pr_warning("Warning - can't forward icmp packet from %pM to "
+			   "%pM: ttl exceeded\n", icmp_packet->orig,
+			   icmp_packet->dst);
 		return NET_RX_DROP;
 	}
 
@@ -754,7 +881,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
 		/* create a copy of the skb, if needed, to modify it. */
-		if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+		if (!skb_clone_writable(skb, icmp_len)) {
 			skb_old = skb;
 			skb = skb_copy(skb, GFP_ATOMIC);
 			if (!skb)
@@ -781,7 +908,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
 
 int recv_icmp_packet(struct sk_buff *skb)
 {
-	struct icmp_packet *icmp_packet;
+	struct icmp_packet_rr *icmp_packet;
 	struct ethhdr *ethhdr;
 	struct orig_node *orig_node;
 	struct sk_buff *skb_old;
@@ -791,6 +918,12 @@ int recv_icmp_packet(struct sk_buff *skb)
 	unsigned long flags;
 	uint8_t dstaddr[ETH_ALEN];
 
+	/**
+	 * we truncate all incoming icmp packets if they don't match our size
+	 */
+	if (skb_headlen(skb) >= sizeof(struct icmp_packet_rr))
+		hdr_size = sizeof(struct icmp_packet_rr);
+
 	/* drop packet if it has not necessary minimum size */
 	if (skb_headlen(skb) < hdr_size)
 		return NET_RX_DROP;
@@ -809,15 +942,23 @@ int recv_icmp_packet(struct sk_buff *skb)
 	if (!is_my_mac(ethhdr->h_dest))
 		return NET_RX_DROP;
 
-	icmp_packet = (struct icmp_packet *)skb->data;
+	icmp_packet = (struct icmp_packet_rr *)skb->data;
+
+	/* add record route information if not full */
+	if ((hdr_size == sizeof(struct icmp_packet_rr)) &&
+	    (icmp_packet->rr_cur < BAT_RR_LEN)) {
+		memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
+			ethhdr->h_dest, ETH_ALEN);
+		icmp_packet->rr_cur++;
+	}
 
 	/* packet for me */
 	if (is_my_mac(icmp_packet->dst))
-		return recv_my_icmp_packet(skb);
+		return recv_my_icmp_packet(skb, hdr_size);
 
 	/* TTL exceeded */
 	if (icmp_packet->ttl < 2)
-		return recv_icmp_ttl_exceeded(skb);
+		return recv_icmp_ttl_exceeded(skb, hdr_size);
 
 	ret = NET_RX_DROP;
 
@@ -836,12 +977,12 @@ int recv_icmp_packet(struct sk_buff *skb)
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
 		/* create a copy of the skb, if needed, to modify it. */
-		if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+		if (!skb_clone_writable(skb, hdr_size)) {
 			skb_old = skb;
 			skb = skb_copy(skb, GFP_ATOMIC);
 			if (!skb)
 				return NET_RX_DROP;
-			icmp_packet = (struct icmp_packet *)skb->data;
+			icmp_packet = (struct icmp_packet_rr *)skb->data;
 			ethhdr = (struct ethhdr *)skb_mac_header(skb);
 			kfree_skb(skb_old);
 		}
@@ -859,16 +1000,109 @@ int recv_icmp_packet(struct sk_buff *skb)
 	return ret;
 }
 
-int recv_unicast_packet(struct sk_buff *skb)
+/* find a suitable router for this originator, and use
+ * bonding if possible. */
+struct neigh_node *find_router(struct orig_node *orig_node,
+		struct batman_if *recv_if)
+{
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+	struct orig_node *primary_orig_node;
+	struct orig_node *router_orig;
+	struct neigh_node *router, *first_candidate, *best_router;
+	static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+	int bonding_enabled;
+
+	if (!orig_node)
+		return NULL;
+
+	if (!orig_node->router)
+		return NULL;
+
+	/* without bonding, the first node should
+	 * always choose the default router. */
+
+	bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
+	if (!bonding_enabled && (recv_if == NULL))
+			return orig_node->router;
+
+	router_orig = orig_node->router->orig_node;
+
+	/* if we have something in the primary_addr, we can search
+	 * for a potential bonding candidate. */
+	if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0)
+		return orig_node->router;
+
+	/* find the orig_node which has the primary interface. might
+	 * even be the same as our router_orig in many cases */
+
+	if (memcmp(router_orig->primary_addr,
+				router_orig->orig, ETH_ALEN) == 0) {
+		primary_orig_node = router_orig;
+	} else {
+		primary_orig_node = hash_find(orig_hash,
+						router_orig->primary_addr);
+		if (!primary_orig_node)
+			return orig_node->router;
+	}
+
+	/* with less than 2 candidates, we can't do any
+	 * bonding and prefer the original router. */
+
+	if (primary_orig_node->bond.candidates < 2)
+		return orig_node->router;
+
+
+	/* all nodes between should choose a candidate which
+	 * is is not on the interface where the packet came
+	 * in. */
+	first_candidate = primary_orig_node->bond.selected;
+	router = first_candidate;
+
+	if (bonding_enabled) {
+		/* in the bonding case, send the packets in a round
+		 * robin fashion over the remaining interfaces. */
+		do {
+			/* recv_if == NULL on the first node. */
+			if (router->if_incoming != recv_if)
+				break;
+
+			router = router->next_bond_candidate;
+		} while (router != first_candidate);
+
+		primary_orig_node->bond.selected = router->next_bond_candidate;
+
+	} else {
+		/* if bonding is disabled, use the best of the
+		 * remaining candidates which are not using
+		 * this interface. */
+		best_router = first_candidate;
+
+		do {
+			/* recv_if == NULL on the first node. */
+			if ((router->if_incoming != recv_if) &&
+				(router->tq_avg > best_router->tq_avg))
+					best_router = router;
+
+			router = router->next_bond_candidate;
+		} while (router != first_candidate);
+
+		router = best_router;
+	}
+
+	return router;
+}
+
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
 {
 	struct unicast_packet *unicast_packet;
 	struct orig_node *orig_node;
+	struct neigh_node *router;
 	struct ethhdr *ethhdr;
 	struct batman_if *batman_if;
 	struct sk_buff *skb_old;
 	uint8_t dstaddr[ETH_ALEN];
 	int hdr_size = sizeof(struct unicast_packet);
-	int ret;
 	unsigned long flags;
 
 	/* drop packet if it has not necessary minimum size */
@@ -899,49 +1133,50 @@ int recv_unicast_packet(struct sk_buff *skb)
 
 	/* TTL exceeded */
 	if (unicast_packet->ttl < 2) {
-		printk(KERN_WARNING "batman-adv:Warning - "
-		       "can't forward unicast packet from %pM to %pM: "
-		       "ttl exceeded\n",
-		       ethhdr->h_source, unicast_packet->dest);
+		pr_warning("Warning - can't forward unicast packet from %pM to "
+			   "%pM: ttl exceeded\n", ethhdr->h_source,
+			   unicast_packet->dest);
 		return NET_RX_DROP;
 	}
 
-	ret = NET_RX_DROP;
 	/* get routing information */
 	spin_lock_irqsave(&orig_hash_lock, flags);
 	orig_node = ((struct orig_node *)
 		     hash_find(orig_hash, unicast_packet->dest));
 
-	if ((orig_node != NULL) &&
-	    (orig_node->router != NULL)) {
+	router = find_router(orig_node, recv_if);
 
-		/* don't lock while sending the packets ... we therefore
-		 * copy the required data before sending */
-		batman_if = orig_node->router->if_incoming;
-		memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+	if (!router) {
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
+		return NET_RX_DROP;
+	}
 
-		/* create a copy of the skb, if needed, to modify it. */
-		if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
-			skb_old = skb;
-			skb = skb_copy(skb, GFP_ATOMIC);
-			if (!skb)
-				return NET_RX_DROP;
-			unicast_packet = (struct unicast_packet *)skb->data;
-			ethhdr = (struct ethhdr *)skb_mac_header(skb);
-			kfree_skb(skb_old);
-		}
-		/* decrement ttl */
-		unicast_packet->ttl--;
+	/* don't lock while sending the packets ... we therefore
+	 * copy the required data before sending */
 
-		/* route it */
-		send_skb_packet(skb, batman_if, dstaddr);
-		ret = NET_RX_SUCCESS;
+	batman_if = router->if_incoming;
+	memcpy(dstaddr, router->addr, ETH_ALEN);
 
-	} else
-		spin_unlock_irqrestore(&orig_hash_lock, flags);
+	spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-	return ret;
+	/* create a copy of the skb, if needed, to modify it. */
+	if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
+		skb_old = skb;
+		skb = skb_copy(skb, GFP_ATOMIC);
+		if (!skb)
+			return NET_RX_DROP;
+		unicast_packet = (struct unicast_packet *) skb->data;
+		ethhdr = (struct ethhdr *)skb_mac_header(skb);
+		kfree_skb(skb_old);
+	}
+
+	/* decrement ttl */
+	unicast_packet->ttl--;
+
+	/* route it */
+	send_skb_packet(skb, batman_if, dstaddr);
+
+	return NET_RX_SUCCESS;
 }
 
 int recv_bcast_packet(struct sk_buff *skb)
@@ -950,7 +1185,7 @@ int recv_bcast_packet(struct sk_buff *skb)
 	struct bcast_packet *bcast_packet;
 	struct ethhdr *ethhdr;
 	int hdr_size = sizeof(struct bcast_packet);
-	int16_t seq_diff;
+	int32_t seq_diff;
 	unsigned long flags;
 
 	/* drop packet if it has not necessary minimum size */
@@ -977,6 +1212,9 @@ int recv_bcast_packet(struct sk_buff *skb)
 	if (is_my_mac(bcast_packet->orig))
 		return NET_RX_DROP;
 
+	if (bcast_packet->ttl < 2)
+		return NET_RX_DROP;
+
 	spin_lock_irqsave(&orig_hash_lock, flags);
 	orig_node = ((struct orig_node *)
 		     hash_find(orig_hash, bcast_packet->orig));
@@ -989,12 +1227,12 @@ int recv_bcast_packet(struct sk_buff *skb)
 	/* check whether the packet is a duplicate */
 	if (get_bit_status(orig_node->bcast_bits,
 			   orig_node->last_bcast_seqno,
-			   ntohs(bcast_packet->seqno))) {
+			   ntohl(bcast_packet->seqno))) {
 		spin_unlock_irqrestore(&orig_hash_lock, flags);
 		return NET_RX_DROP;
 	}
 
-	seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno;
+	seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
 
 	/* check whether the packet is old and the host just restarted. */
 	if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) {
@@ -1005,7 +1243,7 @@ int recv_bcast_packet(struct sk_buff *skb)
 	/* mark broadcast in flood history, update window position
 	 * if required. */
 	if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1))
-		orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
+		orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
 
 	spin_unlock_irqrestore(&orig_hash_lock, flags);
 	/* rebroadcast packet */

+ 10 - 3
drivers/staging/batman-adv/routing.h

@@ -19,9 +19,10 @@
  *
  */
 
-#include "types.h"
+#ifndef _NET_BATMAN_ADV_ROUTING_H_
+#define _NET_BATMAN_ADV_ROUTING_H_
 
-extern wait_queue_head_t thread_wait;
+#include "types.h"
 
 void slide_own_bcast_window(struct batman_if *batman_if);
 void receive_bat_packet(struct ethhdr *ethhdr,
@@ -32,8 +33,14 @@ void update_routes(struct orig_node *orig_node,
 				struct neigh_node *neigh_node,
 				unsigned char *hna_buff, int hna_buff_len);
 int recv_icmp_packet(struct sk_buff *skb);
-int recv_unicast_packet(struct sk_buff *skb);
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
 int recv_bcast_packet(struct sk_buff *skb);
 int recv_vis_packet(struct sk_buff *skb);
 int recv_bat_packet(struct sk_buff *skb,
 				struct batman_if *batman_if);
+struct neigh_node *find_router(struct orig_node *orig_node,
+		struct batman_if *recv_if);
+void update_bonding_candidates(struct bat_priv *bat_priv,
+			       struct orig_node *orig_node);
+
+#endif /* _NET_BATMAN_ADV_ROUTING_H_ */

+ 52 - 29
drivers/staging/batman-adv/send.c

@@ -29,6 +29,10 @@
 #include "vis.h"
 #include "aggregation.h"
 
+#include <linux/netfilter_bridge.h>
+
+static void send_outstanding_bcast_packet(struct work_struct *work);
+
 /* apply hop penalty for a normal link */
 static uint8_t hop_penalty(const uint8_t tq)
 {
@@ -38,15 +42,15 @@ static uint8_t hop_penalty(const uint8_t tq)
 /* when do we schedule our own packet to be sent */
 static unsigned long own_send_time(struct bat_priv *bat_priv)
 {
-	return jiffies +
-		(((atomic_read(&bat_priv->orig_interval) - JITTER +
-		   (random32() % 2*JITTER)) * HZ) / 1000);
+	return jiffies + msecs_to_jiffies(
+		   atomic_read(&bat_priv->orig_interval) -
+		   JITTER + (random32() % 2*JITTER));
 }
 
 /* when do we schedule a forwarded packet to be sent */
 static unsigned long forward_send_time(struct bat_priv *bat_priv)
 {
-	return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000);
+	return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
 }
 
 /* send out an already prepared packet to the given address via the
@@ -64,10 +68,8 @@ int send_skb_packet(struct sk_buff *skb,
 		goto send_skb_err;
 
 	if (!(batman_if->net_dev->flags & IFF_UP)) {
-		printk(KERN_WARNING
-		       "batman-adv:Interface %s "
-		       "is not up - can't send packet via that interface!\n",
-		       batman_if->dev);
+		pr_warning("Interface %s is not up - can't send packet via "
+			   "that interface!\n", batman_if->dev);
 		goto send_skb_err;
 	}
 
@@ -90,9 +92,12 @@ int send_skb_packet(struct sk_buff *skb,
 
 	/* dev_queue_xmit() returns a negative result on error.	 However on
 	 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
-	 * (which is > 0). This will not be treated as an error. */
+	 * (which is > 0). This will not be treated as an error.
+	 * Also, if netfilter/ebtables wants to block outgoing batman
+	 * packets then giving them a chance to do so here */
 
-	return dev_queue_xmit(skb);
+	return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+		       dev_queue_xmit);
 send_skb_err:
 	kfree_skb(skb);
 	return NET_XMIT_DROP;
@@ -119,6 +124,8 @@ void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
 static void send_packet_to_if(struct forw_packet *forw_packet,
 			      struct batman_if *batman_if)
 {
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	char *fwd_str;
 	uint8_t packet_num;
 	int16_t buff_pos;
@@ -148,11 +155,11 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 		fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
 							    "Sending own" :
 							    "Forwarding"));
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
 			" IDF %s) on interface %s [%s]\n",
 			fwd_str, (packet_num > 0 ? "aggregated " : ""),
-			batman_packet->orig, ntohs(batman_packet->seqno),
+			batman_packet->orig, ntohl(batman_packet->seqno),
 			batman_packet->tq, batman_packet->ttl,
 			(batman_packet->flags & DIRECTLINK ?
 			 "on" : "off"),
@@ -167,20 +174,22 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
 
 	send_raw_packet(forw_packet->packet_buff,
 			forw_packet->packet_len,
-			batman_if, broadcastAddr);
+			batman_if, broadcast_addr);
 }
 
 /* send a batman packet */
 static void send_packet(struct forw_packet *forw_packet)
 {
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct batman_if *batman_if;
 	struct batman_packet *batman_packet =
 		(struct batman_packet *)(forw_packet->packet_buff);
 	unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
 
 	if (!forw_packet->if_incoming) {
-		printk(KERN_ERR "batman-adv: Error - can't forward packet: "
-		       "incoming iface not specified\n");
+		pr_err("Error - can't forward packet: incoming iface not "
+		       "specified\n");
 		return;
 	}
 
@@ -193,18 +202,18 @@ static void send_packet(struct forw_packet *forw_packet)
 	    (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
 
 		/* FIXME: what about aggregated packets ? */
-		bat_dbg(DBG_BATMAN,
+		bat_dbg(DBG_BATMAN, bat_priv,
 			"%s packet (originator %pM, seqno %d, TTL %d) "
 			"on interface %s [%s]\n",
 			(forw_packet->own ? "Sending own" : "Forwarding"),
-			batman_packet->orig, ntohs(batman_packet->seqno),
+			batman_packet->orig, ntohl(batman_packet->seqno),
 			batman_packet->ttl, forw_packet->if_incoming->dev,
 			forw_packet->if_incoming->addr_str);
 
 		send_raw_packet(forw_packet->packet_buff,
 				forw_packet->packet_len,
 				forw_packet->if_incoming,
-				broadcastAddr);
+				broadcast_addr);
 		return;
 	}
 
@@ -276,14 +285,14 @@ void schedule_own_packet(struct batman_if *batman_if)
 	batman_packet = (struct batman_packet *)batman_if->packet_buff;
 
 	/* change sequence number to network order */
-	batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
+	batman_packet->seqno =
+		htonl((uint32_t)atomic_read(&batman_if->seqno));
 
 	if (vis_server == VIS_TYPE_SERVER_SYNC)
-		batman_packet->flags = VIS_SERVER;
+		batman_packet->flags |= VIS_SERVER;
 	else
 		batman_packet->flags &= ~VIS_SERVER;
 
-	/* could be read by receive_bat_packet() */
 	atomic_inc(&batman_if->seqno);
 
 	slide_own_bcast_window(batman_if);
@@ -306,7 +315,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
 	unsigned long send_time;
 
 	if (batman_packet->ttl <= 1) {
-		bat_dbg(DBG_BATMAN, "ttl exceeded\n");
+		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
 		return;
 	}
 
@@ -335,13 +344,16 @@ void schedule_forward_packet(struct orig_node *orig_node,
 	/* apply hop penalty */
 	batman_packet->tq = hop_penalty(batman_packet->tq);
 
-	bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, "
+	bat_dbg(DBG_BATMAN, bat_priv,
+		"Forwarding packet: tq_orig: %i, tq_avg: %i, "
 		"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
 		in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
 		batman_packet->ttl);
 
-	batman_packet->seqno = htons(batman_packet->seqno);
+	batman_packet->seqno = htonl(batman_packet->seqno);
 
+	/* switch of primaries first hop flag when forwarding */
+	batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
 	if (directlink)
 		batman_packet->flags |= DIRECTLINK;
 	else
@@ -392,9 +404,12 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
 int add_bcast_packet_to_list(struct sk_buff *skb)
 {
 	struct forw_packet *forw_packet;
+	struct bcast_packet *bcast_packet;
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 
 	if (!atomic_dec_not_zero(&bcast_queue_left)) {
-		bat_dbg(DBG_BATMAN, "bcast packet queue full\n");
+		bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
 		goto out;
 	}
 
@@ -407,6 +422,10 @@ int add_bcast_packet_to_list(struct sk_buff *skb)
 	if (!skb)
 		goto packet_free;
 
+	/* as we have a copy now, it is safe to decrease the TTL */
+	bcast_packet = (struct bcast_packet *)skb->data;
+	bcast_packet->ttl--;
+
 	skb_reset_mac_header(skb);
 
 	forw_packet->skb = skb;
@@ -426,7 +445,7 @@ out:
 	return NETDEV_TX_BUSY;
 }
 
-void send_outstanding_bcast_packet(struct work_struct *work)
+static void send_outstanding_bcast_packet(struct work_struct *work)
 {
 	struct batman_if *batman_if;
 	struct delayed_work *delayed_work =
@@ -450,7 +469,7 @@ void send_outstanding_bcast_packet(struct work_struct *work)
 		skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
 		if (skb1)
 			send_skb_packet(skb1,
-				batman_if, broadcastAddr);
+				batman_if, broadcast_addr);
 	}
 	rcu_read_unlock();
 
@@ -502,15 +521,19 @@ out:
 
 void purge_outstanding_packets(struct batman_if *batman_if)
 {
+	/* FIXME: each batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct forw_packet *forw_packet;
 	struct hlist_node *tmp_node, *safe_tmp_node;
 	unsigned long flags;
 
 	if (batman_if)
-		bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n",
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"purge_outstanding_packets(): %s\n",
 			batman_if->dev);
 	else
-		bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
+		bat_dbg(DBG_BATMAN, bat_priv,
+			"purge_outstanding_packets()\n");
 
 	/* free bcast list */
 	spin_lock_irqsave(&forw_bcast_list_lock, flags);

+ 5 - 2
drivers/staging/batman-adv/send.h

@@ -19,9 +19,11 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_SEND_H_
+#define _NET_BATMAN_ADV_SEND_H_
+
 #include "types.h"
 
-void send_own_packet_work(struct work_struct *work);
 int send_skb_packet(struct sk_buff *skb,
 				struct batman_if *batman_if,
 				uint8_t *dst_addr);
@@ -34,6 +36,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
 			     uint8_t directlink, int hna_buff_len,
 			     struct batman_if *if_outgoing);
 int  add_bcast_packet_to_list(struct sk_buff *skb);
-void send_outstanding_bcast_packet(struct work_struct *work);
 void send_outstanding_bat_packet(struct work_struct *work);
 void purge_outstanding_packets(struct batman_if *batman_if);
+
+#endif /* _NET_BATMAN_ADV_SEND_H_ */

+ 80 - 85
drivers/staging/batman-adv/soft-interface.c

@@ -22,6 +22,7 @@
 #include "main.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
+#include "routing.h"
 #include "send.h"
 #include "translation-table.h"
 #include "types.h"
@@ -30,13 +31,12 @@
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 
-static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
+static uint32_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
 				  * broadcast storms */
 static int32_t skb_packets;
 static int32_t skb_bad_packets;
 
-unsigned char mainIfAddr[ETH_ALEN];
-static unsigned char mainIfAddr_default[ETH_ALEN];
+unsigned char main_if_addr[ETH_ALEN];
 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
 static void bat_get_drvinfo(struct net_device *dev,
 			    struct ethtool_drvinfo *info);
@@ -58,12 +58,7 @@ static const struct ethtool_ops bat_ethtool_ops = {
 
 void set_main_if_addr(uint8_t *addr)
 {
-	memcpy(mainIfAddr, addr, ETH_ALEN);
-}
-
-int main_if_was_up(void)
-{
-	return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
+	memcpy(main_if_addr, addr, ETH_ALEN);
 }
 
 int my_skb_push(struct sk_buff *skb, unsigned int len)
@@ -83,69 +78,25 @@ int my_skb_push(struct sk_buff *skb, unsigned int len)
 	return 0;
 }
 
-#ifdef HAVE_NET_DEVICE_OPS
-static const struct net_device_ops bat_netdev_ops = {
-	.ndo_open = interface_open,
-	.ndo_stop = interface_release,
-	.ndo_get_stats = interface_stats,
-	.ndo_set_mac_address = interface_set_mac_addr,
-	.ndo_change_mtu = interface_change_mtu,
-	.ndo_start_xmit = interface_tx,
-	.ndo_validate_addr = eth_validate_addr
-};
-#endif
-
-void interface_setup(struct net_device *dev)
-{
-	struct bat_priv *priv = netdev_priv(dev);
-	char dev_addr[ETH_ALEN];
-
-	ether_setup(dev);
-
-#ifdef HAVE_NET_DEVICE_OPS
-	dev->netdev_ops = &bat_netdev_ops;
-#else
-	dev->open = interface_open;
-	dev->stop = interface_release;
-	dev->get_stats = interface_stats;
-	dev->set_mac_address = interface_set_mac_addr;
-	dev->change_mtu = interface_change_mtu;
-	dev->hard_start_xmit = interface_tx;
-#endif
-	dev->destructor = free_netdev;
-
-	dev->mtu = hardif_min_mtu();
-	dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
-						* skbuff for our header */
-
-	/* generate random address */
-	random_ether_addr(dev_addr);
-	memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
-
-	SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
-
-	memset(priv, 0, sizeof(struct bat_priv));
-}
-
-int interface_open(struct net_device *dev)
+static int interface_open(struct net_device *dev)
 {
 	netif_start_queue(dev);
 	return 0;
 }
 
-int interface_release(struct net_device *dev)
+static int interface_release(struct net_device *dev)
 {
 	netif_stop_queue(dev);
 	return 0;
 }
 
-struct net_device_stats *interface_stats(struct net_device *dev)
+static struct net_device_stats *interface_stats(struct net_device *dev)
 {
 	struct bat_priv *priv = netdev_priv(dev);
 	return &priv->stats;
 }
 
-int interface_set_mac_addr(struct net_device *dev, void *p)
+static int interface_set_mac_addr(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
 
@@ -163,7 +114,7 @@ int interface_set_mac_addr(struct net_device *dev, void *p)
 	return 0;
 }
 
-int interface_change_mtu(struct net_device *dev, int new_mtu)
+static int interface_change_mtu(struct net_device *dev, int new_mtu)
 {
 	/* check ranges */
 	if ((new_mtu < 68) || (new_mtu > hardif_min_mtu()))
@@ -179,6 +130,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 	struct unicast_packet *unicast_packet;
 	struct bcast_packet *bcast_packet;
 	struct orig_node *orig_node;
+	struct neigh_node *router;
 	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
 	struct bat_priv *priv = netdev_priv(dev);
 	struct batman_if *batman_if;
@@ -205,16 +157,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 
 		bcast_packet = (struct bcast_packet *)skb->data;
 		bcast_packet->version = COMPAT_VERSION;
+		bcast_packet->ttl = TTL;
 
 		/* batman packet type: broadcast */
 		bcast_packet->packet_type = BAT_BCAST;
 
 		/* hw address of first interface is the orig mac because only
 		 * this mac is known throughout the mesh */
-		memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
+		memcpy(bcast_packet->orig, main_if_addr, ETH_ALEN);
 
 		/* set broadcast sequence number */
-		bcast_packet->seqno = htons(bcast_seqno);
+		bcast_packet->seqno = htonl(bcast_seqno);
 
 		/* broadcast packet. on success, increase seqno. */
 		if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
@@ -235,38 +188,36 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
 		if (!orig_node)
 			orig_node = transtable_search(ethhdr->h_dest);
 
-		if ((orig_node) &&
-		    (orig_node->router)) {
-			struct neigh_node *router = orig_node->router;
+		router = find_router(orig_node, NULL);
 
-			if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
-				goto unlock;
+		if (!router)
+			goto unlock;
 
-			unicast_packet = (struct unicast_packet *)skb->data;
+		/* don't lock while sending the packets ... we therefore
+		 * copy the required data before sending */
 
-			unicast_packet->version = COMPAT_VERSION;
-			/* batman packet type: unicast */
-			unicast_packet->packet_type = BAT_UNICAST;
-			/* set unicast ttl */
-			unicast_packet->ttl = TTL;
-			/* copy the destination for faster routing */
-			memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+		batman_if = router->if_incoming;
+		memcpy(dstaddr, router->addr, ETH_ALEN);
 
-			/* net_dev won't be available when not active */
-			if (router->if_incoming->if_status != IF_ACTIVE)
-				goto unlock;
+		spin_unlock_irqrestore(&orig_hash_lock, flags);
 
-			/* don't lock while sending the packets ... we therefore
-			 * copy the required data before sending */
+		if (batman_if->if_status != IF_ACTIVE)
+			goto dropped;
 
-			batman_if = router->if_incoming;
-			memcpy(dstaddr, router->addr, ETH_ALEN);
-			spin_unlock_irqrestore(&orig_hash_lock, flags);
+		if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
+			goto dropped;
 
-			send_skb_packet(skb, batman_if, dstaddr);
-		} else {
-			goto unlock;
-		}
+		unicast_packet = (struct unicast_packet *)skb->data;
+
+		unicast_packet->version = COMPAT_VERSION;
+		/* batman packet type: unicast */
+		unicast_packet->packet_type = BAT_UNICAST;
+		/* set unicast ttl */
+		unicast_packet->ttl = TTL;
+		/* copy the destination for faster routing */
+		memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+
+		send_skb_packet(skb, batman_if, dstaddr);
 	}
 
 	priv->stats.tx_packets++;
@@ -315,6 +266,50 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
 	netif_rx(skb);
 }
 
+#ifdef HAVE_NET_DEVICE_OPS
+static const struct net_device_ops bat_netdev_ops = {
+	.ndo_open = interface_open,
+	.ndo_stop = interface_release,
+	.ndo_get_stats = interface_stats,
+	.ndo_set_mac_address = interface_set_mac_addr,
+	.ndo_change_mtu = interface_change_mtu,
+	.ndo_start_xmit = interface_tx,
+	.ndo_validate_addr = eth_validate_addr
+};
+#endif
+
+void interface_setup(struct net_device *dev)
+{
+	struct bat_priv *priv = netdev_priv(dev);
+	char dev_addr[ETH_ALEN];
+
+	ether_setup(dev);
+
+#ifdef HAVE_NET_DEVICE_OPS
+	dev->netdev_ops = &bat_netdev_ops;
+#else
+	dev->open = interface_open;
+	dev->stop = interface_release;
+	dev->get_stats = interface_stats;
+	dev->set_mac_address = interface_set_mac_addr;
+	dev->change_mtu = interface_change_mtu;
+	dev->hard_start_xmit = interface_tx;
+#endif
+	dev->destructor = free_netdev;
+
+	dev->mtu = hardif_min_mtu();
+	dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
+						* skbuff for our header */
+
+	/* generate random address */
+	random_ether_addr(dev_addr);
+	memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
+
+	SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
+
+	memset(priv, 0, sizeof(struct bat_priv));
+}
+
 /* ethtool */
 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {

+ 6 - 7
drivers/staging/batman-adv/soft-interface.h

@@ -19,16 +19,15 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_
+#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
+
 void set_main_if_addr(uint8_t *addr);
-int main_if_was_up(void);
 void interface_setup(struct net_device *dev);
-int interface_open(struct net_device *dev);
-int interface_release(struct net_device *dev);
-struct net_device_stats *interface_stats(struct net_device *dev);
-int interface_set_mac_addr(struct net_device *dev, void *addr);
-int interface_change_mtu(struct net_device *dev, int new_mtu);
 int interface_tx(struct sk_buff *skb, struct net_device *dev);
 void interface_rx(struct sk_buff *skb, int hdr_size);
 int my_skb_push(struct sk_buff *skb, unsigned int len);
 
-extern unsigned char mainIfAddr[];
+extern unsigned char main_if_addr[];
+
+#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */

+ 14 - 0
drivers/staging/batman-adv/sysfs-class-net-batman-adv

@@ -0,0 +1,14 @@
+
+What:           /sys/class/net/<iface>/batman-adv/mesh_iface
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                The /sys/class/net/<iface>/batman-adv/mesh_iface file
+                displays the batman mesh interface this <iface>
+                currently is associated with.
+
+What:           /sys/class/net/<iface>/batman-adv/iface_status
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Indicates the status of <iface> as it is seen by batman.

+ 33 - 0
drivers/staging/batman-adv/sysfs-class-net-mesh

@@ -0,0 +1,33 @@
+
+What:           /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Indicates whether the batman protocol messages of the
+                mesh <mesh_iface> shall be aggregated or not.
+
+What:           /sys/class/net/<mesh_iface>/mesh/bonding
+Date:           June 2010
+Contact:        Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Description:
+                Indicates whether the data traffic going through the
+                mesh will be sent using multiple interfaces at the
+                same time (if available).
+
+What:           /sys/class/net/<mesh_iface>/mesh/orig_interval
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Defines the interval in milliseconds in which batman
+                sends its protocol messages.
+
+What:           /sys/class/net/<mesh_iface>/mesh/vis_mode
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Each batman node only maintains information about its
+                own local neighborhood, therefore generating graphs
+                showing the topology of the entire mesh is not easily
+                feasible without having a central instance to collect
+                the local topologies from all nodes. This file allows
+                to activate the collecting (server) mode.

+ 82 - 89
drivers/staging/batman-adv/translation-table.c

@@ -32,7 +32,10 @@ atomic_t hna_local_changed;
 DEFINE_SPINLOCK(hna_local_hash_lock);
 static DEFINE_SPINLOCK(hna_global_hash_lock);
 
+static void hna_local_purge(struct work_struct *work);
 static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge);
+static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+				 char *message);
 
 static void hna_local_start_timer(void)
 {
@@ -57,6 +60,8 @@ int hna_local_init(void)
 
 void hna_local_add(uint8_t *addr)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct hna_local_entry *hna_local_entry;
 	struct hna_global_entry *hna_global_entry;
 	struct hashtable_t *swaphash;
@@ -77,15 +82,15 @@ void hna_local_add(uint8_t *addr)
 	   MAC-flooding. */
 	if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
 	    (num_hna + 1 > 255)) {
-		bat_dbg(DBG_ROUTES,
+		bat_dbg(DBG_ROUTES, bat_priv,
 			"Can't add new local hna entry (%pM): "
 			"number of local hna entries exceeds packet size\n",
 			addr);
 		return;
 	}
 
-	bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM\n",
-		addr);
+	bat_dbg(DBG_ROUTES, bat_priv,
+		"Creating new local hna entry: %pM\n", addr);
 
 	hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
 	if (!hna_local_entry)
@@ -111,8 +116,7 @@ void hna_local_add(uint8_t *addr)
 				       hna_local_hash->size * 2);
 
 		if (swaphash == NULL)
-			printk(KERN_ERR "batman-adv:"
-			       "Couldn't resize local hna hash table\n");
+			pr_err("Couldn't resize local hna hash table\n");
 		else
 			hna_local_hash = swaphash;
 	}
@@ -160,59 +164,54 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
 	return i;
 }
 
-int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
-			       size_t count, loff_t off)
+int hna_local_seq_print_text(struct seq_file *seq, void *offset)
 {
+	struct net_device *net_dev = (struct net_device *)seq->private;
 	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct hna_local_entry *hna_local_entry;
 	HASHIT(hashit);
-	int bytes_written = 0;
+	HASHIT(hashit_count);
 	unsigned long flags;
-	size_t hdr_len;
+	size_t buf_size, pos;
+	char *buff;
 
 	if (!bat_priv->primary_if) {
-		if (off == 0)
-			return sprintf(buff,
-				     "BATMAN mesh %s disabled - "
-				     "please specify interfaces to enable it\n",
-				     net_dev->name);
-
-		return 0;
+		return seq_printf(seq, "BATMAN mesh %s disabled - "
+			       "please specify interfaces to enable it\n",
+			       net_dev->name);
 	}
 
-	hdr_len = sprintf(buff,
-			  "Locally retrieved addresses (from %s) "
-			  "announced via HNA:\n",
-			  net_dev->name);
-
-	if (off < hdr_len)
-		bytes_written = hdr_len;
+	seq_printf(seq, "Locally retrieved addresses (from %s) "
+		   "announced via HNA:\n",
+		   net_dev->name);
 
 	spin_lock_irqsave(&hna_local_hash_lock, flags);
 
-	while (hash_iterate(hna_local_hash, &hashit)) {
-		hdr_len += 21;
-
-		if (count < bytes_written + 22)
-			break;
+	buf_size = 1;
+	/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
+	while (hash_iterate(hna_local_hash, &hashit_count))
+		buf_size += 21;
 
-		if (off >= hdr_len)
-			continue;
+	buff = kmalloc(buf_size, GFP_ATOMIC);
+	if (!buff) {
+		spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+		return -ENOMEM;
+	}
+	buff[0] = '\0';
+	pos = 0;
 
+	while (hash_iterate(hna_local_hash, &hashit)) {
 		hna_local_entry = hashit.bucket->data;
 
-		bytes_written += snprintf(buff + bytes_written, 22,
-					  " * " MAC_FMT "\n",
-					  hna_local_entry->addr[0],
-					  hna_local_entry->addr[1],
-					  hna_local_entry->addr[2],
-					  hna_local_entry->addr[3],
-					  hna_local_entry->addr[4],
-					  hna_local_entry->addr[5]);
+		pos += snprintf(buff + pos, 22, " * %pM\n",
+				hna_local_entry->addr);
 	}
 
 	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
-	return bytes_written;
+
+	seq_printf(seq, "%s", buff);
+	kfree(buff);
+	return 0;
 }
 
 static void _hna_local_del(void *data)
@@ -225,7 +224,9 @@ static void _hna_local_del(void *data)
 static void hna_local_del(struct hna_local_entry *hna_local_entry,
 			  char *message)
 {
-	bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s\n",
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+	bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
 		hna_local_entry->addr, message);
 
 	hash_remove(hna_local_hash, hna_local_entry->addr);
@@ -247,7 +248,7 @@ void hna_local_remove(uint8_t *addr, char *message)
 	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
 }
 
-void hna_local_purge(struct work_struct *work)
+static void hna_local_purge(struct work_struct *work)
 {
 	struct hna_local_entry *hna_local_entry;
 	HASHIT(hashit);
@@ -259,8 +260,7 @@ void hna_local_purge(struct work_struct *work)
 	while (hash_iterate(hna_local_hash, &hashit)) {
 		hna_local_entry = hashit.bucket->data;
 
-		timeout = hna_local_entry->last_seen +
-			((LOCAL_HNA_TIMEOUT / 1000) * HZ);
+		timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ;
 		if ((!hna_local_entry->never_purge) &&
 		    time_after(jiffies, timeout))
 			hna_local_del(hna_local_entry, "address timed out");
@@ -296,6 +296,8 @@ int hna_global_init(void)
 void hna_global_add_orig(struct orig_node *orig_node,
 			 unsigned char *hna_buff, int hna_buff_len)
 {
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
 	struct hna_global_entry *hna_global_entry;
 	struct hna_local_entry *hna_local_entry;
 	struct hashtable_t *swaphash;
@@ -322,7 +324,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
 
 			memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
 
-			bat_dbg(DBG_ROUTES,
+			bat_dbg(DBG_ROUTES, bat_priv,
 				"Creating new global hna entry: "
 				"%pM (via %pM)\n",
 				hna_global_entry->addr, orig_node->orig);
@@ -369,8 +371,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
 				       hna_global_hash->size * 2);
 
 		if (swaphash == NULL)
-			printk(KERN_ERR "batman-adv:"
-			       "Couldn't resize global hna hash table\n");
+			pr_err("Couldn't resize global hna hash table\n");
 		else
 			hna_global_hash = swaphash;
 	}
@@ -378,71 +379,63 @@ void hna_global_add_orig(struct orig_node *orig_node,
 	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
 }
 
-int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
-				size_t count, loff_t off)
+int hna_global_seq_print_text(struct seq_file *seq, void *offset)
 {
+	struct net_device *net_dev = (struct net_device *)seq->private;
 	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	struct hna_global_entry *hna_global_entry;
 	HASHIT(hashit);
-	int bytes_written = 0;
+	HASHIT(hashit_count);
 	unsigned long flags;
-	size_t hdr_len;
+	size_t buf_size, pos;
+	char *buff;
 
 	if (!bat_priv->primary_if) {
-		if (off == 0)
-			return sprintf(buff,
-				     "BATMAN mesh %s disabled - "
-				     "please specify interfaces to enable it\n",
-				     net_dev->name);
-
-		return 0;
+		return seq_printf(seq, "BATMAN mesh %s disabled - "
+				  "please specify interfaces to enable it\n",
+				  net_dev->name);
 	}
 
-	hdr_len = sprintf(buff,
-			  "Globally announced HNAs received via the mesh %s "
-			  "(translation table):\n",
-			  net_dev->name);
-
-	if (off < hdr_len)
-		bytes_written = hdr_len;
+	seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
+		   net_dev->name);
 
 	spin_lock_irqsave(&hna_global_hash_lock, flags);
 
-	while (hash_iterate(hna_global_hash, &hashit)) {
-		hdr_len += 43;
-
-		if (count < bytes_written + 44)
-			break;
+	buf_size = 1;
+	/* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
+	while (hash_iterate(hna_global_hash, &hashit_count))
+		buf_size += 43;
 
-		if (off >= hdr_len)
-			continue;
+	buff = kmalloc(buf_size, GFP_ATOMIC);
+	if (!buff) {
+		spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+		return -ENOMEM;
+	}
+	buff[0] = '\0';
+	pos = 0;
 
+	while (hash_iterate(hna_global_hash, &hashit)) {
 		hna_global_entry = hashit.bucket->data;
 
-		bytes_written += snprintf(buff + bytes_written, 44,
-					  " * " MAC_FMT " via " MAC_FMT "\n",
-					  hna_global_entry->addr[0],
-					  hna_global_entry->addr[1],
-					  hna_global_entry->addr[2],
-					  hna_global_entry->addr[3],
-					  hna_global_entry->addr[4],
-					  hna_global_entry->addr[5],
-					  hna_global_entry->orig_node->orig[0],
-					  hna_global_entry->orig_node->orig[1],
-					  hna_global_entry->orig_node->orig[2],
-					  hna_global_entry->orig_node->orig[3],
-					  hna_global_entry->orig_node->orig[4],
-					  hna_global_entry->orig_node->orig[5]);
+		pos += snprintf(buff + pos, 44,
+				" * %pM via %pM\n", hna_global_entry->addr,
+				hna_global_entry->orig_node->orig);
 	}
 
 	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
-	return bytes_written;
+
+	seq_printf(seq, "%s", buff);
+	kfree(buff);
+	return 0;
 }
 
-void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
-			  char *message)
+static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+				 char *message)
 {
-	bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s\n",
+	/* FIXME: each orig_node->batman_if will be attached to a softif */
+	struct bat_priv *bat_priv = netdev_priv(soft_device);
+	bat_dbg(DBG_ROUTES, bat_priv,
+		"Deleting global hna entry %pM (via %pM): %s\n",
 		hna_global_entry->addr, hna_global_entry->orig_node->orig,
 		message);
 

+ 7 - 7
drivers/staging/batman-adv/translation-table.h

@@ -19,23 +19,21 @@
  *
  */
 
+#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
+#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
+
 #include "types.h"
 
 int hna_local_init(void);
 void hna_local_add(uint8_t *addr);
 void hna_local_remove(uint8_t *addr, char *message);
 int hna_local_fill_buffer(unsigned char *buff, int buff_len);
-int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
-			       size_t count, loff_t off);
-void hna_local_purge(struct work_struct *work);
+int hna_local_seq_print_text(struct seq_file *seq, void *offset);
 void hna_local_free(void);
 int hna_global_init(void);
 void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff,
 			 int hna_buff_len);
-int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
-				size_t count, loff_t off);
-void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
-			  char *orig_str);
+int hna_global_seq_print_text(struct seq_file *seq, void *offset);
 void hna_global_del_orig(struct orig_node *orig_node, char *message);
 void hna_global_free(void);
 struct orig_node *transtable_search(uint8_t *addr);
@@ -43,3 +41,5 @@ struct orig_node *transtable_search(uint8_t *addr);
 extern spinlock_t hna_local_hash_lock;
 extern struct hashtable_t *hna_local_hash;
 extern atomic_t hna_local_changed;
+
+#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */

+ 32 - 11
drivers/staging/batman-adv/types.h

@@ -21,10 +21,8 @@
 
 
 
-
-
-#ifndef TYPES_H
-#define TYPES_H
+#ifndef _NET_BATMAN_ADV_TYPES_H_
+#define _NET_BATMAN_ADV_TYPES_H_
 
 #include "packet.h"
 #include "bitarray.h"
@@ -52,6 +50,7 @@ struct batman_if {
 
 /**
   *	orig_node - structure for orig_list maintaining nodes of mesh
+  *	@primary_addr: hosts primary interface address
   *	@last_valid: when last packet from this node was received
   *	@bcast_seqno_reset: time when the broadcast seqno window was reset
   *	@batman_seqno_reset: time when the batman seqno window was reset
@@ -59,9 +58,13 @@ struct batman_if {
   *	@last_real_seqno: last and best known squence number
   *	@last_ttl: ttl of last received packet
   *	@last_bcast_seqno: last broadcast sequence number received by this host
+  *
+  *	@candidates: how many candidates are available
+  *	@selected: next bonding candidate
  */
 struct orig_node {
 	uint8_t orig[ETH_ALEN];
+	uint8_t primary_addr[ETH_ALEN];
 	struct neigh_node *router;
 	TYPE_OF_WORD *bcast_own;
 	uint8_t *bcast_own_sum;
@@ -72,12 +75,16 @@ struct orig_node {
 	unsigned long batman_seqno_reset;
 	uint8_t  flags;
 	unsigned char *hna_buff;
-	int16_t  hna_buff_len;
-	uint16_t last_real_seqno;
+	int16_t hna_buff_len;
+	uint32_t last_real_seqno;
 	uint8_t last_ttl;
 	TYPE_OF_WORD bcast_bits[NUM_WORDS];
-	uint16_t last_bcast_seqno;
+	uint32_t last_bcast_seqno;
 	struct list_head neigh_list;
+	struct {
+		uint8_t candidates;
+		struct neigh_node *selected;
+	} bond;
 };
 
 /**
@@ -92,6 +99,7 @@ struct neigh_node {
 	uint8_t tq_index;
 	uint8_t tq_avg;
 	uint8_t last_ttl;
+	struct neigh_node *next_bond_candidate;
 	unsigned long last_valid;
 	TYPE_OF_WORD real_bits[NUM_WORDS];
 	struct orig_node *orig_node;
@@ -101,14 +109,18 @@ struct neigh_node {
 struct bat_priv {
 	struct net_device_stats stats;
 	atomic_t aggregation_enabled;
+	atomic_t bonding_enabled;
 	atomic_t vis_mode;
 	atomic_t orig_interval;
+	atomic_t log_level;
 	char num_ifaces;
+	struct debug_log *debug_log;
 	struct batman_if *primary_if;
 	struct kobject *mesh_obj;
+	struct dentry *debug_dir;
 };
 
-struct device_client {
+struct socket_client {
 	struct list_head queue_list;
 	unsigned int queue_len;
 	unsigned char index;
@@ -116,9 +128,10 @@ struct device_client {
 	wait_queue_head_t queue_wait;
 };
 
-struct device_packet {
+struct socket_packet {
 	struct list_head list;
-	struct icmp_packet icmp_packet;
+	size_t icmp_len;
+	struct icmp_packet_rr icmp_packet;
 };
 
 struct hna_local_entry {
@@ -159,4 +172,12 @@ struct if_list_entry {
 	struct hlist_node list;
 };
 
-#endif
+struct debug_log {
+	char log_buff[LOG_BUF_LEN];
+	unsigned long log_start;
+	unsigned long log_end;
+	spinlock_t lock;
+	wait_queue_head_t queue_wait;
+};
+
+#endif /* _NET_BATMAN_ADV_TYPES_H_ */

+ 98 - 49
drivers/staging/batman-adv/vis.c

@@ -43,8 +43,8 @@
 			_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 struct hashtable_t *vis_hash;
+static 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 */
@@ -115,7 +115,7 @@ static void vis_data_insert_interface(const uint8_t *interface,
 	}
 
 	/* its a new address, add it to the list */
-	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
 	if (!entry)
 		return;
 	memcpy(entry->addr, interface, ETH_ALEN);
@@ -142,12 +142,29 @@ static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
 	return len;
 }
 
+static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
+{
+	struct if_list_entry *entry;
+	struct hlist_node *pos;
+	size_t count = 0;
+
+	hlist_for_each_entry(entry, pos, if_list, list) {
+		if (entry->primary)
+			count += 9;
+		else
+			count += 23;
+	}
+
+	return count;
+}
+
 /* read an entry  */
 static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
 				   uint8_t *src, bool primary)
 {
-	char to[40];
+	char to[18];
 
+	/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
 	addr_to_string(to, entry->dest);
 	if (primary && entry->quality == 0)
 		return sprintf(buff, "HNA %s, ", to);
@@ -157,38 +174,74 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
 	return 0;
 }
 
-ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
-			      size_t count, loff_t off)
+int vis_seq_print_text(struct seq_file *seq, void *offset)
 {
 	HASHIT(hashit);
+	HASHIT(hashit_count);
 	struct vis_info *info;
 	struct vis_info_entry *entries;
+	struct net_device *net_dev = (struct net_device *)seq->private;
 	struct bat_priv *bat_priv = netdev_priv(net_dev);
 	HLIST_HEAD(vis_if_list);
 	struct if_list_entry *entry;
 	struct hlist_node *pos, *n;
-	size_t hdr_len, tmp_len;
-	int i, bytes_written = 0;
+	int i;
 	char tmp_addr_str[ETH_STR_LEN];
 	unsigned long flags;
 	int vis_server = atomic_read(&bat_priv->vis_mode);
+	size_t buff_pos, buf_size;
+	char *buff;
 
 	if ((!bat_priv->primary_if) ||
 	    (vis_server == VIS_TYPE_CLIENT_UPDATE))
 		return 0;
 
-	hdr_len = 0;
-
+	buf_size = 1;
+	/* Estimate length */
 	spin_lock_irqsave(&vis_hash_lock, flags);
+	while (hash_iterate(vis_hash, &hashit_count)) {
+		info = hashit_count.bucket->data;
+		entries = (struct vis_info_entry *)
+			((char *)info + sizeof(struct vis_info));
+
+		for (i = 0; i < info->packet.entries; i++) {
+			if (entries[i].quality == 0)
+				continue;
+			vis_data_insert_interface(entries[i].src, &vis_if_list,
+				compare_orig(entries[i].src,
+						info->packet.vis_orig));
+		}
+
+		hlist_for_each_entry(entry, pos, &vis_if_list, list) {
+			buf_size += 18 + 26 * info->packet.entries;
+
+			/* add primary/secondary records */
+			if (compare_orig(entry->addr, info->packet.vis_orig))
+				buf_size +=
+					vis_data_count_prim_sec(&vis_if_list);
+
+			buf_size += 1;
+		}
+
+		hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
+			hlist_del(&entry->list);
+			kfree(entry);
+		}
+	}
+
+	buff = kmalloc(buf_size, GFP_ATOMIC);
+	if (!buff) {
+		spin_unlock_irqrestore(&vis_hash_lock, flags);
+		return -ENOMEM;
+	}
+	buff[0] = '\0';
+	buff_pos = 0;
+
 	while (hash_iterate(vis_hash, &hashit)) {
 		info = hashit.bucket->data;
 		entries = (struct vis_info_entry *)
 			((char *)info + sizeof(struct vis_info));
 
-		/* estimated line length */
-		if (count < bytes_written + 200)
-			break;
-
 		for (i = 0; i < info->packet.entries; i++) {
 			if (entries[i].quality == 0)
 				continue;
@@ -199,30 +252,22 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
 
 		hlist_for_each_entry(entry, pos, &vis_if_list, list) {
 			addr_to_string(tmp_addr_str, entry->addr);
-			tmp_len = sprintf(buff + bytes_written,
-					  "%s,", tmp_addr_str);
+			buff_pos += sprintf(buff + buff_pos, "%s,",
+					    tmp_addr_str);
 
 			for (i = 0; i < info->packet.entries; i++)
-				tmp_len += vis_data_read_entry(
-						buff + bytes_written + tmp_len,
-						&entries[i], entry->addr,
-						entry->primary);
+				buff_pos += vis_data_read_entry(buff + buff_pos,
+								&entries[i],
+								entry->addr,
+								entry->primary);
 
 			/* add primary/secondary records */
 			if (compare_orig(entry->addr, info->packet.vis_orig))
-				tmp_len += vis_data_read_prim_sec(
-						buff + bytes_written + tmp_len,
-						&vis_if_list);
-
-			tmp_len += sprintf(buff + bytes_written + tmp_len,
-					  "\n");
-
-			hdr_len += tmp_len;
+				buff_pos +=
+					vis_data_read_prim_sec(buff + buff_pos,
+							       &vis_if_list);
 
-			if (off >= hdr_len)
-				continue;
-
-			bytes_written += tmp_len;
+			buff_pos += sprintf(buff + buff_pos, "\n");
 		}
 
 		hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
@@ -230,9 +275,13 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
 			kfree(entry);
 		}
 	}
+
 	spin_unlock_irqrestore(&vis_hash_lock, flags);
 
-	return bytes_written;
+	seq_printf(seq, "%s", buff);
+	kfree(buff);
+
+	return 0;
 }
 
 /* add the info packet to the send list, if it was not
@@ -308,7 +357,8 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
 	old_info = hash_find(vis_hash, &search_elem);
 
 	if (old_info != NULL) {
-		if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) {
+		if (!seq_after(ntohl(vis_packet->seqno),
+				ntohl(old_info->packet.seqno))) {
 			if (old_info->packet.seqno == vis_packet->seqno) {
 				recv_list_add(&old_info->recv_list,
 					      vis_packet->sender_orig);
@@ -340,7 +390,7 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
 
 	/* Make it a broadcast packet, if required */
 	if (make_broadcast)
-		memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+		memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
 
 	/* repair if entries is longer than packet. */
 	if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
@@ -474,9 +524,9 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
 	info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
 
 	spin_lock_irqsave(&orig_hash_lock, flags);
-	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+	memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
 	info->packet.ttl = TTL;
-	info->packet.seqno++;
+	info->packet.seqno = htonl(ntohl(info->packet.seqno) + 1);
 	info->packet.entries = 0;
 
 	if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
@@ -547,7 +597,7 @@ static void purge_vis_packets(void)
 		if (info == my_vis_info)	/* never purge own data. */
 			continue;
 		if (time_after(jiffies,
-			       info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
+			       info->first_seen + VIS_TIMEOUT * HZ)) {
 			hash_remove_bucket(vis_hash, &hashit);
 			send_list_del(info);
 			kref_put(&info->refcount, free_info);
@@ -591,7 +641,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
 
 	}
 	spin_unlock_irqrestore(&orig_hash_lock, flags);
-	memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+	memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
 }
 
 static void unicast_vis_packet(struct vis_info *info, int packet_length)
@@ -628,11 +678,11 @@ static void send_vis_packet(struct vis_info *info)
 	int packet_length;
 
 	if (info->packet.ttl < 2) {
-		printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
+		pr_warning("Error - can't send vis packet: ttl exceeded\n");
 		return;
 	}
 
-	memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN);
+	memcpy(info->packet.sender_orig, main_if_addr, ETH_ALEN);
 	info->packet.ttl--;
 
 	packet_length = sizeof(struct vis_packet) +
@@ -690,18 +740,18 @@ int vis_init(void)
 
 	vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
 	if (!vis_hash) {
-		printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
+		pr_err("Can't initialize vis_hash\n");
 		goto err;
 	}
 
 	my_vis_info = kmalloc(1000, GFP_ATOMIC);
 	if (!my_vis_info) {
-		printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
+		pr_err("Can't initialize vis packet\n");
 		goto err;
 	}
 
 	/* prefill the vis info */
-	my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
+	my_vis_info->first_seen = jiffies - msecs_to_jiffies(VIS_INTERVAL);
 	INIT_LIST_HEAD(&my_vis_info->recv_list);
 	INIT_LIST_HEAD(&my_vis_info->send_list);
 	kref_init(&my_vis_info->refcount);
@@ -713,12 +763,11 @@ int vis_init(void)
 
 	INIT_LIST_HEAD(&send_list);
 
-	memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN);
-	memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
+	memcpy(my_vis_info->packet.vis_orig, main_if_addr, ETH_ALEN);
+	memcpy(my_vis_info->packet.sender_orig, main_if_addr, ETH_ALEN);
 
 	if (hash_add(vis_hash, my_vis_info) < 0) {
-		printk(KERN_ERR
-		       "batman-adv:Can't add own vis packet into hash\n");
+		pr_err("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;
@@ -764,5 +813,5 @@ void vis_quit(void)
 static void start_vis_timer(void)
 {
 	queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
-			   (atomic_read(&vis_interval) * HZ) / 1000);
+			   (VIS_INTERVAL * HZ) / 1000);
 }

+ 7 - 6
drivers/staging/batman-adv/vis.h

@@ -19,7 +19,10 @@
  *
  */
 
-#define VIS_TIMEOUT		200000
+#ifndef _NET_BATMAN_ADV_VIS_H_
+#define _NET_BATMAN_ADV_VIS_H_
+
+#define VIS_TIMEOUT		200	/* timeout of vis packets in seconds */
 
 struct vis_info {
 	unsigned long       first_seen;
@@ -44,11 +47,7 @@ struct recvlist_node {
 	uint8_t mac[ETH_ALEN];
 };
 
-extern struct hashtable_t *vis_hash;
-extern spinlock_t vis_hash_lock;
-
-ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
-			      size_t count, loff_t off);
+int vis_seq_print_text(struct seq_file *seq, void *offset);
 void receive_server_sync_packet(struct bat_priv *bat_priv,
 				struct vis_packet *vis_packet,
 				int vis_info_len);
@@ -57,3 +56,5 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
 				  int vis_info_len);
 int vis_init(void);
 void vis_quit(void);
+
+#endif /* _NET_BATMAN_ADV_VIS_H_ */

+ 0 - 1
drivers/staging/comedi/TODO

@@ -2,7 +2,6 @@ TODO:
 	- checkpatch.pl cleanups
 	- Lindent
 	- remove all wrappers
-	- remove typedefs
 	- audit userspace interface
 	- reserve major number
 	- cleanup the individual comedi drivers as well

+ 9 - 2
drivers/staging/comedi/comedi_fops.c

@@ -1845,8 +1845,15 @@ ok:
 		}
 	}
 
-	if (dev->attached && dev->use_count == 0 && dev->open)
-		dev->open(dev);
+	if (dev->attached && dev->use_count == 0 && dev->open) {
+		int rc = dev->open(dev);
+		if (rc < 0) {
+			module_put(dev->driver->module);
+			module_put(THIS_MODULE);
+			mutex_unlock(&dev->mutex);
+			return rc;
+		}
+	}
 
 	dev->use_count++;
 

+ 1 - 57
drivers/staging/comedi/comedidev.h

@@ -53,62 +53,6 @@
 	COMEDI_MINORVERSION, COMEDI_MICROVERSION)
 #define COMEDI_RELEASE VERSION
 
-#define COMEDI_INITCLEANUP_NOMODULE(x)					\
-	static int __init x ## _init_module(void)			\
-		{return comedi_driver_register(&(x)); }			\
-	static void __exit x ## _cleanup_module(void)			\
-		{comedi_driver_unregister(&(x)); }			\
-	module_init(x ## _init_module);					\
-	module_exit(x ## _cleanup_module);
-
-#define COMEDI_MODULE_MACROS						\
-	MODULE_AUTHOR("Comedi http://www.comedi.org");		\
-	MODULE_DESCRIPTION("Comedi low-level driver");			\
-	MODULE_LICENSE("GPL");
-
-#define COMEDI_INITCLEANUP(x)						\
-	COMEDI_MODULE_MACROS		\
-	COMEDI_INITCLEANUP_NOMODULE(x)
-
-#define COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) \
-	static int __devinit comedi_driver ## _pci_probe(struct pci_dev *dev, \
-		const struct pci_device_id *ent) \
-	{ \
-		return comedi_pci_auto_config(dev, comedi_driver.driver_name); \
-	} \
-	static void __devexit comedi_driver ## _pci_remove(\
-		struct pci_dev *dev) \
-	{ \
-		comedi_pci_auto_unconfig(dev); \
-	} \
-	static struct pci_driver comedi_driver ## _pci_driver = \
-	{ \
-		.id_table = pci_id_table, \
-		.probe = &comedi_driver ## _pci_probe, \
-		.remove = __devexit_p(&comedi_driver ## _pci_remove) \
-	}; \
-	static int __init comedi_driver ## _init_module(void) \
-	{ \
-		int retval; \
-		retval = comedi_driver_register(&comedi_driver); \
-		if (retval < 0) \
-			return retval; \
-			comedi_driver ## _pci_driver.name = \
-				(char *)comedi_driver.driver_name; \
-		return pci_register_driver(&comedi_driver ## _pci_driver); \
-	} \
-	static void __exit comedi_driver ## _cleanup_module(void) \
-	{ \
-		pci_unregister_driver(&comedi_driver ## _pci_driver); \
-		comedi_driver_unregister(&comedi_driver); \
-	} \
-	module_init(comedi_driver ## _init_module); \
-	module_exit(comedi_driver ## _cleanup_module);
-
-#define COMEDI_PCI_INITCLEANUP(comedi_driver, pci_id_table) \
-	COMEDI_MODULE_MACROS \
-	COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table)
-
 #define PCI_VENDOR_ID_ADLINK		0x144a
 #define PCI_VENDOR_ID_ICP		0x104c
 #define PCI_VENDOR_ID_CONTEC		0x1221
@@ -285,7 +229,7 @@ struct comedi_device {
 
 	struct fasync_struct *async_queue;
 
-	void (*open) (struct comedi_device *dev);
+	int (*open) (struct comedi_device *dev);
 	void (*close) (struct comedi_device *dev);
 };
 

+ 16 - 1
drivers/staging/comedi/drivers/8255.c

@@ -117,7 +117,18 @@ static struct comedi_driver driver_8255 = {
 	.detach = dev_8255_detach,
 };
 
-COMEDI_INITCLEANUP(driver_8255);
+static int __init driver_8255_init_module(void)
+{
+	return comedi_driver_register(&driver_8255);
+}
+
+static void __exit driver_8255_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_8255);
+}
+
+module_init(driver_8255_init_module);
+module_exit(driver_8255_cleanup_module);
 
 static void do_config(struct comedi_device *dev, struct comedi_subdevice *s);
 
@@ -457,3 +468,7 @@ static int dev_8255_detach(struct comedi_device *dev)
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 16 - 1
drivers/staging/comedi/drivers/acl7225b.c

@@ -49,7 +49,18 @@ static struct comedi_driver driver_acl7225b = {
 	.offset = sizeof(struct boardtype),
 };
 
-COMEDI_INITCLEANUP(driver_acl7225b);
+static int __init driver_acl7225b_init_module(void)
+{
+	return comedi_driver_register(&driver_acl7225b);
+}
+
+static void __exit driver_acl7225b_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_acl7225b);
+}
+
+module_init(driver_acl7225b_init_module);
+module_exit(driver_acl7225b_cleanup_module);
 
 static int acl7225b_do_insn(struct comedi_device *dev,
 			    struct comedi_subdevice *s,
@@ -150,3 +161,7 @@ static int acl7225b_detach(struct comedi_device *dev)
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 2 - 4
drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h

@@ -247,16 +247,14 @@ int i_pci_card_data(struct pcilst_struct *amcc,
 /* build list of amcc cards in this system */
 void v_pci_card_list_init(unsigned short pci_vendor, char display)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	struct pcilst_struct *amcc, *last;
 	int i;
 	int i_Count = 0;
 	amcc_devices = NULL;
 	last = NULL;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		for (i_Count = 0; i_Count < 2; i_Count++) {
 			pci_vendor = i_ADDIDATADeviceID[i_Count];
 			if (pcidev->vendor == pci_vendor) {

+ 37 - 1
drivers/staging/comedi/drivers/addi-data/addi_common.c

@@ -2541,7 +2541,43 @@ static struct comedi_driver driver_addi = {
 	.offset = sizeof(struct addi_board),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_addi, addi_apci_tbl);
+static int __devinit driver_addi_pci_probe(struct pci_dev *dev,
+					   const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_addi.driver_name);
+}
+
+static void __devexit driver_addi_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_addi_pci_driver = {
+	.id_table = addi_apci_tbl,
+	.probe = &driver_addi_pci_probe,
+	.remove = __devexit_p(&driver_addi_pci_remove)
+};
+
+static int __init driver_addi_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_addi);
+	if (retval < 0)
+		return retval;
+
+	driver_addi_pci_driver.name = (char *)driver_addi.driver_name;
+	return pci_register_driver(&driver_addi_pci_driver);
+}
+
+static void __exit driver_addi_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_addi_pci_driver);
+	comedi_driver_unregister(&driver_addi);
+}
+
+module_init(driver_addi_init_module);
+module_exit(driver_addi_cleanup_module);
 
 /*
 +----------------------------------------------------------------------------+

+ 6 - 6
drivers/staging/comedi/drivers/addi-data/addi_eeprom.c

@@ -101,10 +101,10 @@ struct str_TimerMainHeader {
 };
 
 
-typedef struct {
+struct str_AnalogOutputHeader {
 	unsigned short w_Nchannel;
 	unsigned char b_Resolution;
-} str_AnalogOutputHeader;
+};
 
 struct str_AnalogInputHeader {
 	unsigned short w_Nchannel;
@@ -136,7 +136,7 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
 
 int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
 	char *pc_PCIChipInformation, unsigned short w_Address,
-	str_AnalogOutputHeader *s_Header);
+	struct str_AnalogOutputHeader *s_Header);
 
 int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
 	char *pc_PCIChipInformation, unsigned short w_Address,
@@ -635,7 +635,7 @@ void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromComman
 
 | Input Parameters  : unsigned int dw_Address : PCI eeprom base address                  |
 
-|		      unsigned short    w_offset : Offset of the adress to read             |
+|		      unsigned short    w_offset : Offset of the address to read             |
 
 |		      unsigned short *   pw_Value : PCI eeprom 16 bit read value.            |
 
@@ -811,7 +811,7 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
 	struct str_DigitalInputHeader s_DigitalInputHeader;
 	struct str_DigitalOutputHeader s_DigitalOutputHeader;
 	/* struct str_TimerMainHeader     s_TimerMainHeader,s_WatchdogMainHeader; */
-	str_AnalogOutputHeader s_AnalogOutputHeader;
+	struct str_AnalogOutputHeader s_AnalogOutputHeader;
 	struct str_AnalogInputHeader s_AnalogInputHeader;
 
 	/* Read size */
@@ -1081,7 +1081,7 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
 
 int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
 	char *pc_PCIChipInformation, unsigned short w_Address,
-	str_AnalogOutputHeader *s_Header)
+	struct str_AnalogOutputHeader *s_Header)
 {
 	unsigned short w_Temp;
 	/*  No of channels for 1st hard component */

+ 4 - 4
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c

@@ -1090,13 +1090,13 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
  * and put into into an array array used may be for differnet pages
  */
 
-		/*  DMA Start Adress Low */
+		/*  DMA Start Address Low */
 		outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
 		outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF),
 			devpriv->i_IobaseAddon + 2);
 
 		/*************************/
-		/* DMA Start Adress High */
+		/* DMA Start Address High */
 		/*************************/
 		outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
 		outw((devpriv->ul_DmaBufferHw[0] / 65536),
@@ -1733,11 +1733,11 @@ void v_APCI3120_InterruptDma(int irq, void *d)
 		var = devpriv->ul_DmaBufferHw[next_dma_buf];
 		high_word = var / 65536;
 
-		/* DMA Start Adress Low */
+		/* DMA Start Address Low */
 		outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
 		outw(low_word, devpriv->i_IobaseAddon + 2);
 
-		/* DMA Start Adress High */
+		/* DMA Start Address High */
 		outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
 		outw(high_word, devpriv->i_IobaseAddon + 2);
 

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_035.c

@@ -5,3 +5,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_035"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_1032.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_1032"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_1500.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_1500"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_1516.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_1516"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_1564.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_1564"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_16xx.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_16xx"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_2016.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_2016"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_2032.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_2032"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_2200.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_2200"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_3001.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_3001"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_3120.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_3120"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_3501.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_3501"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 4 - 0
drivers/staging/comedi/drivers/addi_apci_3xxx.c

@@ -3,3 +3,7 @@
 #define ADDIDATA_DRIVER_NAME	"addi_apci_3xxx"
 
 #include "addi-data/addi_common.c"
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 43 - 5
drivers/staging/comedi/drivers/adl_pci6208.c

@@ -119,7 +119,43 @@ static struct comedi_driver driver_pci6208 = {
 	.detach = pci6208_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table);
+static int __devinit driver_pci6208_pci_probe(struct pci_dev *dev,
+					      const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_pci6208.driver_name);
+}
+
+static void __devexit driver_pci6208_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci6208_pci_driver = {
+	.id_table = pci6208_pci_table,
+	.probe = &driver_pci6208_pci_probe,
+	.remove = __devexit_p(&driver_pci6208_pci_remove)
+};
+
+static int __init driver_pci6208_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_pci6208);
+	if (retval < 0)
+		return retval;
+
+	driver_pci6208_pci_driver.name = (char *)driver_pci6208.driver_name;
+	return pci_register_driver(&driver_pci6208_pci_driver);
+}
+
+static void __exit driver_pci6208_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_pci6208_pci_driver);
+	comedi_driver_unregister(&driver_pci6208);
+}
+
+module_init(driver_pci6208_init_module);
+module_exit(driver_pci6208_cleanup_module);
 
 static int pci6208_find_device(struct comedi_device *dev, int bus, int slot);
 static int
@@ -315,12 +351,10 @@ static int pci6208_ao_rinsn(struct comedi_device *dev,
 
 static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
 {
-	struct pci_dev *pci_dev;
+	struct pci_dev *pci_dev = NULL;
 	int i;
 
-	for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pci_dev != NULL;
-	     pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+	for_each_pci_dev(pci_dev) {
 		if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
 			for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) {
 				if (pci6208_boards[i].dev_id ==
@@ -408,3 +442,7 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 45 - 6
drivers/staging/comedi/drivers/adl_pci7230.c

@@ -90,7 +90,7 @@ static int adl_pci7230_do_insn_bits(struct comedi_device *dev,
 static int adl_pci7230_attach(struct comedi_device *dev,
 	struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	struct comedi_subdevice *s;
 	int bus, slot;
 
@@ -106,10 +106,7 @@ static int adl_pci7230_attach(struct comedi_device *dev,
 	if (alloc_subdevices(dev, 2) < 0)
 		return -ENOMEM;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-		pcidev != NULL;
-		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
 			pcidev->device == PCI_DEVICE_ID_PCI7230) {
 			if (bus || slot) {
@@ -203,4 +200,46 @@ static int adl_pci7230_di_insn_bits(struct comedi_device *dev,
 	return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci7230, adl_pci7230_pci_table);
+static int __devinit driver_adl_pci7230_pci_probe(struct pci_dev *dev,
+						  const struct pci_device_id
+						  *ent)
+{
+	return comedi_pci_auto_config(dev, driver_adl_pci7230.driver_name);
+}
+
+static void __devexit driver_adl_pci7230_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci7230_pci_driver = {
+	.id_table = adl_pci7230_pci_table,
+	.probe = &driver_adl_pci7230_pci_probe,
+	.remove = __devexit_p(&driver_adl_pci7230_pci_remove)
+};
+
+static int __init driver_adl_pci7230_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_adl_pci7230);
+	if (retval < 0)
+		return retval;
+
+	driver_adl_pci7230_pci_driver.name =
+	    (char *)driver_adl_pci7230.driver_name;
+	return pci_register_driver(&driver_adl_pci7230_pci_driver);
+}
+
+static void __exit driver_adl_pci7230_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_adl_pci7230_pci_driver);
+	comedi_driver_unregister(&driver_adl_pci7230);
+}
+
+module_init(driver_adl_pci7230_init_module);
+module_exit(driver_adl_pci7230_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 45 - 6
drivers/staging/comedi/drivers/adl_pci7296.c

@@ -77,7 +77,7 @@ static struct comedi_driver driver_adl_pci7296 = {
 static int adl_pci7296_attach(struct comedi_device *dev,
 			      struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	struct comedi_subdevice *s;
 	int bus, slot;
 	int ret;
@@ -94,10 +94,7 @@ static int adl_pci7296_attach(struct comedi_device *dev,
 	if (alloc_subdevices(dev, 4) < 0)
 		return -ENOMEM;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
 		    pcidev->device == PCI_DEVICE_ID_PCI7296) {
 			if (bus || slot) {
@@ -177,4 +174,46 @@ static int adl_pci7296_detach(struct comedi_device *dev)
 	return 0;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci7296, adl_pci7296_pci_table);
+static int __devinit driver_adl_pci7296_pci_probe(struct pci_dev *dev,
+						  const struct pci_device_id
+						  *ent)
+{
+	return comedi_pci_auto_config(dev, driver_adl_pci7296.driver_name);
+}
+
+static void __devexit driver_adl_pci7296_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci7296_pci_driver = {
+	.id_table = adl_pci7296_pci_table,
+	.probe = &driver_adl_pci7296_pci_probe,
+	.remove = __devexit_p(&driver_adl_pci7296_pci_remove)
+};
+
+static int __init driver_adl_pci7296_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_adl_pci7296);
+	if (retval < 0)
+		return retval;
+
+	driver_adl_pci7296_pci_driver.name =
+	    (char *)driver_adl_pci7296.driver_name;
+	return pci_register_driver(&driver_adl_pci7296_pci_driver);
+}
+
+static void __exit driver_adl_pci7296_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_adl_pci7296_pci_driver);
+	comedi_driver_unregister(&driver_adl_pci7296);
+}
+
+module_init(driver_adl_pci7296_init_module);
+module_exit(driver_adl_pci7296_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 45 - 6
drivers/staging/comedi/drivers/adl_pci7432.c

@@ -86,7 +86,7 @@ static int adl_pci7432_do_insn_bits(struct comedi_device *dev,
 static int adl_pci7432_attach(struct comedi_device *dev,
 			      struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	struct comedi_subdevice *s;
 	int bus, slot;
 
@@ -102,10 +102,7 @@ static int adl_pci7432_attach(struct comedi_device *dev,
 	if (alloc_subdevices(dev, 2) < 0)
 		return -ENOMEM;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
 		    pcidev->device == PCI_DEVICE_ID_PCI7432) {
 			if (bus || slot) {
@@ -210,4 +207,46 @@ static int adl_pci7432_di_insn_bits(struct comedi_device *dev,
 	return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci7432, adl_pci7432_pci_table);
+static int __devinit driver_adl_pci7432_pci_probe(struct pci_dev *dev,
+						  const struct pci_device_id
+						  *ent)
+{
+	return comedi_pci_auto_config(dev, driver_adl_pci7432.driver_name);
+}
+
+static void __devexit driver_adl_pci7432_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci7432_pci_driver = {
+	.id_table = adl_pci7432_pci_table,
+	.probe = &driver_adl_pci7432_pci_probe,
+	.remove = __devexit_p(&driver_adl_pci7432_pci_remove)
+};
+
+static int __init driver_adl_pci7432_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_adl_pci7432);
+	if (retval < 0)
+		return retval;
+
+	driver_adl_pci7432_pci_driver.name =
+	    (char *)driver_adl_pci7432.driver_name;
+	return pci_register_driver(&driver_adl_pci7432_pci_driver);
+}
+
+static void __exit driver_adl_pci7432_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_adl_pci7432_pci_driver);
+	comedi_driver_unregister(&driver_adl_pci7432);
+}
+
+module_init(driver_adl_pci7432_init_module);
+module_exit(driver_adl_pci7432_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 45 - 6
drivers/staging/comedi/drivers/adl_pci8164.c

@@ -125,7 +125,7 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
 static int adl_pci8164_attach(struct comedi_device *dev,
 			      struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	struct comedi_subdevice *s;
 	int bus, slot;
 
@@ -142,10 +142,7 @@ static int adl_pci8164_attach(struct comedi_device *dev,
 	if (alloc_subdevices(dev, 4) < 0)
 		return -ENOMEM;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
 		    pcidev->device == PCI_DEVICE_ID_PCI8164) {
 			if (bus || slot) {
@@ -389,4 +386,46 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
 	return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_adl_pci8164, adl_pci8164_pci_table);
+static int __devinit driver_adl_pci8164_pci_probe(struct pci_dev *dev,
+						  const struct pci_device_id
+						  *ent)
+{
+	return comedi_pci_auto_config(dev, driver_adl_pci8164.driver_name);
+}
+
+static void __devexit driver_adl_pci8164_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_adl_pci8164_pci_driver = {
+	.id_table = adl_pci8164_pci_table,
+	.probe = &driver_adl_pci8164_pci_probe,
+	.remove = __devexit_p(&driver_adl_pci8164_pci_remove)
+};
+
+static int __init driver_adl_pci8164_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_adl_pci8164);
+	if (retval < 0)
+		return retval;
+
+	driver_adl_pci8164_pci_driver.name =
+	    (char *)driver_adl_pci8164.driver_name;
+	return pci_register_driver(&driver_adl_pci8164_pci_driver);
+}
+
+static void __exit driver_adl_pci8164_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_adl_pci8164_pci_driver);
+	comedi_driver_unregister(&driver_adl_pci8164);
+}
+
+module_init(driver_adl_pci8164_init_module);
+module_exit(driver_adl_pci8164_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 137 - 76
drivers/staging/comedi/drivers/adl_pci9111.c

@@ -38,8 +38,8 @@ Supports:
   - do_insn read/write
   - ai_do_cmd mode with the following sources:
 
-    - start_src 		TRIG_NOW
-    - scan_begin_src 		TRIG_FOLLOW	TRIG_TIMER	TRIG_EXT
+    - start_src			TRIG_NOW
+    - scan_begin_src		TRIG_FOLLOW	TRIG_TIMER	TRIG_EXT
     - convert_src				TRIG_TIMER	TRIG_EXT
     - scan_end_src		TRIG_COUNT
     - stop_src			TRIG_COUNT	TRIG_NONE
@@ -68,8 +68,9 @@ CHANGELOG:
 TODO:
 
   - Really test implemented functionality.
-  - Add support for the PCI-9111DG with a probe routine to identify the card type
-    (perhaps with the help of the channel number readback of the A/D Data register).
+  - Add support for the PCI-9111DG with a probe routine to identify the card
+    type (perhaps with the help of the channel number readback of the A/D Data
+    register).
   - Add external multiplexer support.
 
 */
@@ -83,12 +84,12 @@ TODO:
 #include "comedi_pci.h"
 #include "comedi_fc.h"
 
-#define PCI9111_DRIVER_NAME 	"adl_pci9111"
-#define PCI9111_HR_DEVICE_ID 	0x9111
+#define PCI9111_DRIVER_NAME	"adl_pci9111"
+#define PCI9111_HR_DEVICE_ID	0x9111
 
 /*  TODO: Add other pci9111 board id */
 
-#define PCI9111_IO_RANGE 	0x0100
+#define PCI9111_IO_RANGE	0x0100
 
 #define PCI9111_FIFO_HALF_SIZE	512
 
@@ -134,27 +135,29 @@ TODO:
 
 /* IO address map */
 
-#define PCI9111_REGISTER_AD_FIFO_VALUE 			0x00	/*  AD Data stored in FIFO */
-#define PCI9111_REGISTER_DA_OUTPUT 			0x00
-#define PCI9111_REGISTER_DIGITAL_IO 			0x02
-#define PCI9111_REGISTER_EXTENDED_IO_PORTS 		0x04
-#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 		0x06	/*  Channel selection */
-#define PCI9111_REGISTER_AD_CHANNEL_READBACK 		0x06
-#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 		0x08
-#define PCI9111_REGISTER_RANGE_STATUS_READBACK 		0x08
-#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 		0x0A
-#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 	0x0A
-#define PCI9111_REGISTER_SOFTWARE_TRIGGER 		0x0E
-#define PCI9111_REGISTER_INTERRUPT_CONTROL 		0x0C
+#define PCI9111_REGISTER_AD_FIFO_VALUE			0x00 /* AD Data stored
+								in FIFO */
+#define PCI9111_REGISTER_DA_OUTPUT			0x00
+#define PCI9111_REGISTER_DIGITAL_IO			0x02
+#define PCI9111_REGISTER_EXTENDED_IO_PORTS		0x04
+#define PCI9111_REGISTER_AD_CHANNEL_CONTROL		0x06 /* Channel
+								selection */
+#define PCI9111_REGISTER_AD_CHANNEL_READBACK		0x06
+#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE		0x08
+#define PCI9111_REGISTER_RANGE_STATUS_READBACK		0x08
+#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL		0x0A
+#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK	0x0A
+#define PCI9111_REGISTER_SOFTWARE_TRIGGER		0x0E
+#define PCI9111_REGISTER_INTERRUPT_CONTROL		0x0C
 #define PCI9111_REGISTER_8254_COUNTER_0			0x40
 #define PCI9111_REGISTER_8254_COUNTER_1			0x42
-#define PCI9111_REGISTER_8254_COUNTER_2 		0X44
+#define PCI9111_REGISTER_8254_COUNTER_2			0X44
 #define PCI9111_REGISTER_8254_CONTROL			0x46
-#define PCI9111_REGISTER_INTERRUPT_CLEAR 		0x48
+#define PCI9111_REGISTER_INTERRUPT_CLEAR		0x48
 
-#define PCI9111_TRIGGER_MASK 				0x0F
-#define PCI9111_PTRG_OFF 				(0 << 3)
-#define PCI9111_PTRG_ON 				(1 << 3)
+#define PCI9111_TRIGGER_MASK				0x0F
+#define PCI9111_PTRG_OFF				(0 << 3)
+#define PCI9111_PTRG_ON					(1 << 3)
 #define PCI9111_EITS_EXTERNAL				(1 << 2)
 #define PCI9111_EITS_INTERNAL				(0 << 2)
 #define PCI9111_TPST_SOFTWARE_TRIGGER			(0 << 1)
@@ -164,9 +167,9 @@ TODO:
 
 #define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
 #define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL		(1 << 0)
-#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK  		(0 << 1)
-#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG 		(1 << 1)
-#define PCI9111_FFEN_SET_FIFO_ENABLE 			(0 << 2)
+#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK		(0 << 1)
+#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG			(1 << 1)
+#define PCI9111_FFEN_SET_FIFO_ENABLE			(0 << 2)
 #define PCI9111_FFEN_SET_FIFO_DISABLE			(1 << 2)
 
 #define PCI9111_CHANNEL_MASK				0x0F
@@ -177,7 +180,7 @@ TODO:
 #define PCI9111_FIFO_FULL_MASK				0x40
 #define PCI9111_AD_BUSY_MASK				0x80
 
-#define PCI9111_IO_BASE dev->iobase
+#define PCI9111_IO_BASE (dev->iobase)
 
 /*
  * Define inlined function
@@ -189,8 +192,9 @@ TODO:
 #define pci9111_trigger_and_autoscan_set(flags) \
   outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
 
-#define pci9111_interrupt_and_fifo_get() \
-  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) &0x03)
+#define pci9111_interrupt_and_fifo_get()				   \
+  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) \
+   &0x03)
 
 #define pci9111_interrupt_and_fifo_set(flags) \
   outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
@@ -201,45 +205,56 @@ TODO:
 #define pci9111_software_trigger() \
   outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
 
-#define pci9111_fifo_reset() \
-  outb(PCI9111_FFEN_SET_FIFO_ENABLE, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
-  outb(PCI9111_FFEN_SET_FIFO_DISABLE, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
-  outb(PCI9111_FFEN_SET_FIFO_ENABLE, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+#define pci9111_fifo_reset() do {					\
+  outb(PCI9111_FFEN_SET_FIFO_ENABLE,					\
+       PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL);		\
+  outb(PCI9111_FFEN_SET_FIFO_DISABLE,					\
+       PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL);		\
+  outb(PCI9111_FFEN_SET_FIFO_ENABLE,					\
+       PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL);		\
+  } while (0)
 
 #define pci9111_is_fifo_full() \
   ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
-    PCI9111_FIFO_FULL_MASK)==0)
+    PCI9111_FIFO_FULL_MASK) == 0)
 
 #define pci9111_is_fifo_half_full() \
   ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
-    PCI9111_FIFO_HALF_FULL_MASK)==0)
+    PCI9111_FIFO_HALF_FULL_MASK) == 0)
 
 #define pci9111_is_fifo_empty() \
   ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
-    PCI9111_FIFO_EMPTY_MASK)==0)
+    PCI9111_FIFO_EMPTY_MASK) == 0)
 
-#define pci9111_ai_channel_set(channel) \
-  outb((channel)&PCI9111_CHANNEL_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
+#define pci9111_ai_channel_set(channel)					\
+  outb((channel)&PCI9111_CHANNEL_MASK,					\
+       PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
 
-#define pci9111_ai_channel_get() \
-  inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)&PCI9111_CHANNEL_MASK
+#define pci9111_ai_channel_get()					\
+  (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)		\
+   &PCI9111_CHANNEL_MASK)
 
-#define pci9111_ai_range_set(range) \
-  outb((range)&PCI9111_RANGE_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
+#define pci9111_ai_range_set(range)					\
+  outb((range)&PCI9111_RANGE_MASK,					\
+       PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
 
-#define pci9111_ai_range_get() \
-  inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)&PCI9111_RANGE_MASK
+#define pci9111_ai_range_get()						\
+  (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)		\
+   &PCI9111_RANGE_MASK)
 
-#define pci9111_ai_get_data() \
-  ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)&PCI9111_AI_RESOLUTION_MASK) \
-  ^ PCI9111_AI_RESOLUTION_2_CMP_BIT
+#define pci9111_ai_get_data()						\
+  (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)		\
+    &PCI9111_AI_RESOLUTION_MASK)					\
+   ^ PCI9111_AI_RESOLUTION_2_CMP_BIT)
 
-#define pci9111_hr_ai_get_data() \
-  (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
-  ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
+#define pci9111_hr_ai_get_data()					\
+  ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)			\
+    & PCI9111_HR_AI_RESOLUTION_MASK)					\
+   ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT)
 
-#define pci9111_ao_set_data(data) \
-  outw(data&PCI9111_AO_RESOLUTION_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
+#define pci9111_ao_set_data(data)					\
+  outw(data&PCI9111_AO_RESOLUTION_MASK,					\
+       PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
 
 #define pci9111_di_get_bits() \
   inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
@@ -284,12 +299,11 @@ static const struct comedi_lrange pci9111_hr_ai_range = {
 };
 
 static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
-	{
-	PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0},
-	    /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
-	{
-	0}
+	{ PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, 0 },
+	/* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 *   0, 0, 0 }, */
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
@@ -337,7 +351,43 @@ static struct comedi_driver pci9111_driver = {
 	.detach = pci9111_detach,
 };
 
-COMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table);
+static int __devinit pci9111_driver_pci_probe(struct pci_dev *dev,
+					      const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, pci9111_driver.driver_name);
+}
+
+static void __devexit pci9111_driver_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver pci9111_driver_pci_driver = {
+	.id_table = pci9111_pci_table,
+	.probe = &pci9111_driver_pci_probe,
+	.remove = __devexit_p(&pci9111_driver_pci_remove)
+};
+
+static int __init pci9111_driver_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&pci9111_driver);
+	if (retval < 0)
+		return retval;
+
+	pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name;
+	return pci_register_driver(&pci9111_driver_pci_driver);
+}
+
+static void __exit pci9111_driver_cleanup_module(void)
+{
+	pci_unregister_driver(&pci9111_driver_pci_driver);
+	comedi_driver_unregister(&pci9111_driver);
+}
+
+module_init(pci9111_driver_init_module);
+module_exit(pci9111_driver_cleanup_module);
 
 /*  Private data structure */
 
@@ -345,7 +395,8 @@ struct pci9111_private_data {
 	struct pci_dev *pci_device;
 	unsigned long io_range;	/*  PCI6503 io range */
 
-	unsigned long lcr_io_base;	/*  Local configuration register base address */
+	unsigned long lcr_io_base; /* Local configuration register base
+				    * address */
 	unsigned long lcr_io_range;
 
 	int stop_counter;
@@ -358,7 +409,8 @@ struct pci9111_private_data {
 
 	int ao_readback;	/*  Last written analog output data */
 
-	unsigned int timer_divisor_1;	/*  Divisor values for the 8254 timer pacer */
+	unsigned int timer_divisor_1; /* Divisor values for the 8254 timer
+				       * pacer */
 	unsigned int timer_divisor_2;
 
 	int is_valid;		/*  Is device valid */
@@ -366,7 +418,7 @@ struct pci9111_private_data {
 	short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
 };
 
-#define dev_private 	((struct pci9111_private_data *)dev->private)
+#define dev_private	((struct pci9111_private_data *)dev->private)
 
 /*  ------------------------------------------------------------------ */
 /*  PLX9050 SECTION */
@@ -548,10 +600,12 @@ static int pci9111_ai_cancel(struct comedi_device *dev,
 
 /*  Test analog input command */
 
-#define pci9111_check_trigger_src(src, flags) \
-  tmp = src; \
-  src &= flags; \
-  if (!src || tmp != src) error++
+#define pci9111_check_trigger_src(src, flags)	do {			\
+		tmp = src;						\
+		src &= flags;						\
+		if (!src || tmp != src)					\
+			error++;					\
+	} while (false);
 
 static int
 pci9111_ai_do_cmd_test(struct comedi_device *dev,
@@ -575,7 +629,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 	if (error)
 		return 1;
 
-	/*  step 2 : make sure trigger sources are unique and mutually compatible */
+	/*  step 2 : make sure trigger sources are unique and mutually
+	 *  compatible */
 
 	if (cmd->start_src != TRIG_NOW)
 		error++;
@@ -637,7 +692,8 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 		cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
 		error++;
 	}
-	if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) {
+	if ((cmd->scan_begin_src == TRIG_FOLLOW)
+	    && (cmd->scan_begin_arg != 0)) {
 		cmd->scan_begin_arg = 0;
 		error++;
 	}
@@ -1216,7 +1272,7 @@ static int pci9111_attach(struct comedi_device *dev,
 {
 	struct comedi_subdevice *subdevice;
 	unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
-	struct pci_dev *pci_device;
+	struct pci_dev *pci_device = NULL;
 	int error, i;
 	const struct pci9111_board *board;
 
@@ -1226,17 +1282,17 @@ static int pci9111_attach(struct comedi_device *dev,
 
 	printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
 
-	for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pci_device != NULL;
-	     pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+	for_each_pci_dev(pci_device) {
 		if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
 			for (i = 0; i < pci9111_board_nbr; i++) {
 				if (pci9111_boards[i].device_id ==
 				    pci_device->device) {
-					/*  was a particular bus/slot requested? */
+					/* was a particular bus/slot
+					 * requested? */
 					if ((it->options[0] != 0)
 					    || (it->options[1] != 0)) {
-						/*  are we on the wrong bus/slot? */
+						/* are we on the wrong
+						 * bus/slot? */
 						if (pci_device->bus->number !=
 						    it->options[0]
 						    ||
@@ -1272,7 +1328,8 @@ found:
 
 	/*  TODO: Warn about non-tested boards. */
 
-	/*  Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
+	/*  Read local configuration register base address
+	 *  [PCI_BASE_ADDRESS #1]. */
 
 	lcr_io_base = pci_resource_start(pci_device, 1);
 	lcr_io_range = pci_resource_len(pci_device, 1);
@@ -1399,3 +1456,7 @@ static int pci9111_detach(struct comedi_device *dev)
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 41 - 1
drivers/staging/comedi/drivers/adl_pci9118.c

@@ -289,7 +289,43 @@ static struct comedi_driver driver_pci9118 = {
 	.offset = sizeof(struct boardtype),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
+static int __devinit driver_pci9118_pci_probe(struct pci_dev *dev,
+					      const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_pci9118.driver_name);
+}
+
+static void __devexit driver_pci9118_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci9118_pci_driver = {
+	.id_table = pci9118_pci_table,
+	.probe = &driver_pci9118_pci_probe,
+	.remove = __devexit_p(&driver_pci9118_pci_remove)
+};
+
+static int __init driver_pci9118_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_pci9118);
+	if (retval < 0)
+		return retval;
+
+	driver_pci9118_pci_driver.name = (char *)driver_pci9118.driver_name;
+	return pci_register_driver(&driver_pci9118_pci_driver);
+}
+
+static void __exit driver_pci9118_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_pci9118_pci_driver);
+	comedi_driver_unregister(&driver_pci9118);
+}
+
+module_init(driver_pci9118_init_module);
+module_exit(driver_pci9118_cleanup_module);
 
 struct pci9118_private {
 	unsigned long iobase_a;	/* base+size for AMCC chip */
@@ -2432,3 +2468,7 @@ static int pci9118_detach(struct comedi_device *dev)
 /*
 ==============================================================================
 */
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 16 - 1
drivers/staging/comedi/drivers/adq12b.c

@@ -402,4 +402,19 @@ static int adq12b_do_insn_bits(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_INITCLEANUP(driver_adq12b);
+static int __init driver_adq12b_init_module(void)
+{
+	return comedi_driver_register(&driver_adq12b);
+}
+
+static void __exit driver_adq12b_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_adq12b);
+}
+
+module_init(driver_adq12b_init_module);
+module_exit(driver_adq12b_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 69 - 20
drivers/staging/comedi/drivers/adv_pci1710.c

@@ -19,7 +19,7 @@
 /*
 Driver: adv_pci1710
 Description: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,
-             Advantech PCI-1720, PCI-1731
+	     Advantech PCI-1720, PCI-1731
 Author: Michal Dobes <dobes@tesnet.cz>
 Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG (pci1710hg),
   PCI-1711 (adv_pci1710), PCI-1713, PCI-1720,
@@ -37,8 +37,8 @@ PCI driver.
 Configuration options:
   [0] - PCI bus of device (optional)
   [1] - PCI slot of device (optional)
-          If bus/slot is not specified, the first available PCI
-          device will be used.
+	If bus/slot is not specified, the first available PCI
+	device will be used.
 */
 
 #include <linux/interrupt.h>
@@ -50,7 +50,9 @@ Configuration options:
 #include "8253.h"
 #include "amcc_s5933.h"
 
-#define PCI171x_PARANOIDCHECK	/* if defined, then is used code which control correct channel number on every 12 bit sample */
+#define PCI171x_PARANOIDCHECK	/* if defined, then is used code which control
+				 * correct channel number on every 12 bit
+				 * sample */
 
 #undef PCI171X_EXTDEBUG
 
@@ -70,8 +72,8 @@ Configuration options:
 #define TYPE_PCI1713	2
 #define TYPE_PCI1720	3
 
-#define IORANGE_171x 	32
-#define IORANGE_1720 	16
+#define IORANGE_171x	32
+#define IORANGE_1720	16
 
 #define PCI171x_AD_DATA	 0	/* R:   A/D data */
 #define PCI171x_SOFTTRG	 0	/* W:   soft trigger for A/D */
@@ -91,13 +93,15 @@ Configuration options:
 #define PCI171x_CNT2	28	/* R/W: 8254 counter 2 */
 #define PCI171x_CNTCTRL	30	/* W:   8254 counter control */
 
-/* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */
+/* upper bits from status register (PCI171x_STATUS) (lower is same with control
+ * reg) */
 #define	Status_FE	0x0100	/* 1=FIFO is empty */
 #define Status_FH	0x0200	/* 1=FIFO is half full */
 #define Status_FF	0x0400	/* 1=FIFO is full, fatal error */
 #define Status_IRQ	0x0800	/* 1=IRQ occured */
 /* bits from control register (PCI171x_CONTROL) */
-#define Control_CNT0	0x0040	/* 1=CNT0 have external source, 0=have internal 100kHz source */
+#define Control_CNT0	0x0040	/* 1=CNT0 have external source,
+				 * 0=have internal 100kHz source */
 #define Control_ONEFH	0x0020	/* 1=IRQ on FIFO is half full, 0=every sample */
 #define Control_IRQEN	0x0010	/* 1=enable IRQ */
 #define Control_GATE	0x0008	/* 1=enable external trigger GATE (8254?) */
@@ -112,7 +116,8 @@ Configuration options:
 #define Counter_RW0     0x0010	/* RW0/RW1 select read/write mode */
 #define Counter_RW1     0x0020
 #define Counter_SC0     0x0040	/* Select Counter. Only 00 or 11 may */
-#define Counter_SC1     0x0080	/* be used, 00 for CNT0, 11 for read-back command */
+#define Counter_SC1     0x0080	/* be used, 00 for CNT0,
+				 * 11 for read-back command */
 
 #define PCI1720_DA0	 0	/* W:   D/A register 0 */
 #define PCI1720_DA1	 2	/* W:   D/A register 1 */
@@ -138,8 +143,8 @@ static const struct comedi_lrange range_pci1710_3 = { 9, {
 							  }
 };
 
-static const char range_codes_pci1710_3[] =
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
+static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
+					      0x10, 0x11, 0x12, 0x13 };
 
 static const struct comedi_lrange range_pci1710hg = { 12, {
 							   BIP_RANGE(5),
@@ -157,10 +162,9 @@ static const struct comedi_lrange range_pci1710hg = { 12, {
 							   }
 };
 
-static const char range_codes_pci1710hg[] =
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
-	0x13
-};
+static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
+					      0x05, 0x06, 0x07, 0x10, 0x11,
+					      0x12, 0x13 };
 
 static const struct comedi_lrange range_pci17x1 = { 5, {
 							BIP_RANGE(10),
@@ -301,7 +305,8 @@ struct pci1710_private {
 	unsigned int ai_timer1;	/*  timers */
 	unsigned int ai_timer2;
 	short ao_data[4];	/*  data output buffer */
-	unsigned int cnt0_write_wait;	/*  after a write, wait for update of the internal state */
+	unsigned int cnt0_write_wait;	/* after a write, wait for update of the
+					 * internal state */
 };
 
 #define devpriv ((struct pci1710_private *)dev->private)
@@ -324,7 +329,9 @@ static int pci1710_reset(struct comedi_device *dev);
 static int pci171x_ai_cancel(struct comedi_device *dev,
 			     struct comedi_subdevice *s);
 
-static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,	/*  used for gain list programming */
+/*  used for gain list programming */
+static const unsigned int muxonechan[] = {
+	0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
 	0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
 	0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
 	0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
@@ -774,7 +781,8 @@ static void interrupt_pci1710_half_fifo(void *d)
 	}
 
 	if (!devpriv->neverending_ai)
-		if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+		if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data
+								    sampled */
 			pci171x_ai_cancel(dev, s);
 			s->async->events |= COMEDI_CB_EOA;
 			comedi_event(dev, s);
@@ -1559,7 +1567,8 @@ static int pci1710_attach(struct comedi_device *dev,
 		s->maxdata = 1;
 		s->len_chanlist = this_board->n_dochan;
 		s->range_table = &range_digital;
-		s->io_bits = (1 << this_board->n_dochan) - 1;	/* all bits output */
+		/* all bits output */
+		s->io_bits = (1 << this_board->n_dochan) - 1;
 		s->state = 0;
 		s->insn_bits = pci171x_insn_bits_do;
 		subdev++;
@@ -1609,7 +1618,47 @@ static int pci1710_detach(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-COMEDI_PCI_INITCLEANUP(driver_pci1710, pci1710_pci_table);
+static int __devinit driver_pci1710_pci_probe(struct pci_dev *dev,
+					      const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_pci1710.driver_name);
+}
+
+static void __devexit driver_pci1710_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci1710_pci_driver = {
+	.id_table = pci1710_pci_table,
+	.probe = &driver_pci1710_pci_probe,
+	.remove = __devexit_p(&driver_pci1710_pci_remove)
+};
+
+static int __init driver_pci1710_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_pci1710);
+	if (retval < 0)
+		return retval;
+
+	driver_pci1710_pci_driver.name = (char *)driver_pci1710.driver_name;
+	return pci_register_driver(&driver_pci1710_pci_driver);
+}
+
+static void __exit driver_pci1710_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_pci1710_pci_driver);
+	comedi_driver_unregister(&driver_pci1710);
+}
+
+module_init(driver_pci1710_init_module);
+module_exit(driver_pci1710_cleanup_module);
 /*
 ==============================================================================
 */
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 41 - 1
drivers/staging/comedi/drivers/adv_pci1723.c

@@ -496,4 +496,44 @@ static int pci1723_detach(struct comedi_device *dev)
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_pci1723, pci1723_pci_table);
+static int __devinit driver_pci1723_pci_probe(struct pci_dev *dev,
+					      const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_pci1723.driver_name);
+}
+
+static void __devexit driver_pci1723_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci1723_pci_driver = {
+	.id_table = pci1723_pci_table,
+	.probe = &driver_pci1723_pci_probe,
+	.remove = __devexit_p(&driver_pci1723_pci_remove)
+};
+
+static int __init driver_pci1723_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_pci1723);
+	if (retval < 0)
+		return retval;
+
+	driver_pci1723_pci_driver.name = (char *)driver_pci1723.driver_name;
+	return pci_register_driver(&driver_pci1723_pci_driver);
+}
+
+static void __exit driver_pci1723_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_pci1723_pci_driver);
+	comedi_driver_unregister(&driver_pci1723);
+}
+
+module_init(driver_pci1723_init_module);
+module_exit(driver_pci1723_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 223 - 132
drivers/staging/comedi/drivers/adv_pci_dio.c

@@ -8,8 +8,8 @@
 /*
 Driver: adv_pci_dio
 Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
-             PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
-             PCI-1754, PCI-1756, PCI-1762
+	PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
+	PCI-1754, PCI-1756, PCI-1762
 Author: Michal Dobes <dobes@tesnet.cz>
 Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
   PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750,
@@ -24,8 +24,8 @@ This driver supports now only insn interface for DI/DO/DIO.
 Configuration options:
   [0] - PCI bus of device (optional)
   [1] - PCI slot of device (optional)
-          If bus/slot is not specified, the first available PCI
-          device will be used.
+	If bus/slot is not specified, the first available PCI
+	device will be used.
 
 */
 
@@ -67,9 +67,12 @@ enum hw_io_access {
 
 #define MAX_DI_SUBDEVS	2	/* max number of DI subdevices per card */
 #define MAX_DO_SUBDEVS	2	/* max number of DO subdevices per card */
-#define MAX_DIO_SUBDEVG	2	/* max number of DIO subdevices group per card */
-#define MAX_8254_SUBDEVS   1	/* max number of 8254 counter subdevs per card */
-				/* (could be more than one 8254 per subdevice) */
+#define MAX_DIO_SUBDEVG	2	/* max number of DIO subdevices group per
+				 * card */
+#define MAX_8254_SUBDEVS   1	/* max number of 8254 counter subdevs per
+				 * card */
+				/* (could be more than one 8254 per
+				 * subdevice) */
 
 #define SIZE_8254	   4	/* 8254 IO space length */
 #define SIZE_8255	   4	/* 8255 IO space length */
@@ -84,7 +87,8 @@ enum hw_io_access {
 #define PCI1730_DO	   2	/* W:   Digital output 0-15 */
 #define PCI1733_IDI	   0	/* R:   Isolated digital input  0-31 */
 #define	PCI1730_3_INT_EN	0x08	/* R/W: enable/disable interrupts */
-#define	PCI1730_3_INT_RF	0x0c	/* R/W: set falling/raising edge for interrupts */
+#define	PCI1730_3_INT_RF	0x0c	/* R/W: set falling/raising edge for
+					 * interrupts */
 #define	PCI1730_3_INT_CLR	0x10	/* R/W: clear interrupts */
 #define PCI1734_IDO	   0	/* W:   Isolated digital output 0-31 */
 #define PCI173x_BOARDID	   4	/* R:   Board I/D switch for 1730/3/4 */
@@ -99,7 +103,8 @@ enum hw_io_access {
 #define PCI1736_IDI        0	/* R:   Isolated digital input  0-15 */
 #define PCI1736_IDO        0	/* W:   Isolated digital output 0-15 */
 #define PCI1736_3_INT_EN        0x08	/* R/W: enable/disable interrupts */
-#define PCI1736_3_INT_RF        0x0c	/* R/W: set falling/raising edge for interrupts */
+#define PCI1736_3_INT_RF        0x0c	/* R/W: set falling/raising edge for
+					 * interrupts */
 #define PCI1736_3_INT_CLR       0x10	/* R/W: clear interrupts */
 #define PCI1736_BOARDID    4	/* R:   Board I/D switch for 1736UP */
 #define PCI1736_MAINREG    0	/* Normal register (2) doesn't work */
@@ -161,37 +166,66 @@ enum hw_io_access {
 #define INTCSR3		0x3b
 
 /*  PCI-1760 mailbox commands */
-#define CMD_ClearIMB2		0x00	/* Clear IMB2 status and return actaul DI status in IMB3 */
+#define CMD_ClearIMB2		0x00	/* Clear IMB2 status and return actual
+					 * DI status in IMB3 */
 #define CMD_SetRelaysOutput	0x01	/* Set relay output from OMB0 */
 #define CMD_GetRelaysStatus	0x02	/* Get relay status to IMB0 */
-#define CMD_ReadCurrentStatus	0x07	/* Read the current status of the register in OMB0, result in IMB0 */
-#define CMD_ReadFirmwareVersion	0x0e	/* Read the firmware ver., result in IMB1.IMB0 */
-#define CMD_ReadHardwareVersion	0x0f	/* Read the hardware ver., result in IMB1.IMB0 */
-#define CMD_EnableIDIFilters	0x20	/* Enable IDI filters based on bits in OMB0 */
-#define CMD_EnableIDIPatternMatch 0x21	/* Enable IDI pattern match based on bits in OMB0 */
-#define CMD_SetIDIPatternMatch	0x22	/* Enable IDI pattern match based on bits in OMB0 */
-#define CMD_EnableIDICounters	0x28	/* Enable IDI counters based on bits in OMB0 */
-#define CMD_ResetIDICounters	0x29	/* Reset IDI counters based on bits in OMB0 to its reset values */
-#define CMD_OverflowIDICounters	0x2a	/* Enable IDI counters overflow interrupts  based on bits in OMB0 */
-#define CMD_MatchIntIDICounters	0x2b	/* Enable IDI counters match value interrupts  based on bits in OMB0 */
-#define CMD_EdgeIDICounters	0x2c	/* Set IDI up counters count edge (bit=0 - rising, =1 - falling) */
-#define CMD_GetIDICntCurValue	0x2f	/* Read IDI{OMB0} up counter current value */
-#define CMD_SetIDI0CntResetValue 0x40	/* Set IDI0 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntResetValue 0x41	/* Set IDI1 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntResetValue 0x42	/* Set IDI2 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntResetValue 0x43	/* Set IDI3 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntResetValue 0x44	/* Set IDI4 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntResetValue 0x45	/* Set IDI5 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntResetValue 0x46	/* Set IDI6 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntResetValue 0x47	/* Set IDI7 Counter Reset Value 256*OMB1+OMB0 */
-#define CMD_SetIDI0CntMatchValue 0x48	/* Set IDI0 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI1CntMatchValue 0x49	/* Set IDI1 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI2CntMatchValue 0x4a	/* Set IDI2 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI3CntMatchValue 0x4b	/* Set IDI3 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI4CntMatchValue 0x4c	/* Set IDI4 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI5CntMatchValue 0x4d	/* Set IDI5 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI6CntMatchValue 0x4e	/* Set IDI6 Counter Match Value 256*OMB1+OMB0 */
-#define CMD_SetIDI7CntMatchValue 0x4f	/* Set IDI7 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_ReadCurrentStatus	0x07	/* Read the current status of the
+					 * register in OMB0, result in IMB0 */
+#define CMD_ReadFirmwareVersion	0x0e	/* Read the firmware ver., result in
+					 * IMB1.IMB0 */
+#define CMD_ReadHardwareVersion	0x0f	/* Read the hardware ver., result in
+					 * IMB1.IMB0 */
+#define CMD_EnableIDIFilters	0x20	/* Enable IDI filters based on bits in
+					 * OMB0 */
+#define CMD_EnableIDIPatternMatch 0x21	/* Enable IDI pattern match based on
+					 * bits in OMB0 */
+#define CMD_SetIDIPatternMatch	0x22	/* Enable IDI pattern match based on
+					 * bits in OMB0 */
+#define CMD_EnableIDICounters	0x28	/* Enable IDI counters based on bits in
+					 * OMB0 */
+#define CMD_ResetIDICounters	0x29	/* Reset IDI counters based on bits in
+					 * OMB0 to its reset values */
+#define CMD_OverflowIDICounters	0x2a	/* Enable IDI counters overflow
+					 * interrupts  based on bits in OMB0 */
+#define CMD_MatchIntIDICounters	0x2b	/* Enable IDI counters match value
+					 * interrupts  based on bits in OMB0 */
+#define CMD_EdgeIDICounters	0x2c	/* Set IDI up counters count edge (bit=0
+					 * - rising, =1 - falling) */
+#define CMD_GetIDICntCurValue	0x2f	/* Read IDI{OMB0} up counter current
+					 * value */
+#define CMD_SetIDI0CntResetValue 0x40	/* Set IDI0 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntResetValue 0x41	/* Set IDI1 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntResetValue 0x42	/* Set IDI2 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntResetValue 0x43	/* Set IDI3 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntResetValue 0x44	/* Set IDI4 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntResetValue 0x45	/* Set IDI5 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntResetValue 0x46	/* Set IDI6 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntResetValue 0x47	/* Set IDI7 Counter Reset Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI0CntMatchValue 0x48	/* Set IDI0 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntMatchValue 0x49	/* Set IDI1 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntMatchValue 0x4a	/* Set IDI2 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntMatchValue 0x4b	/* Set IDI3 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntMatchValue 0x4c	/* Set IDI4 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntMatchValue 0x4d	/* Set IDI5 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntMatchValue 0x4e	/* Set IDI6 Counter Match Value
+					 * 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntMatchValue 0x4f	/* Set IDI7 Counter Match Value
+					 * 256*OMB1+OMB0 */
 
 #define OMBCMD_RETRY	0x03	/* 3 times try request before error */
 
@@ -244,115 +278,115 @@ MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
 static const struct dio_boardtype boardtypes[] = {
 	{"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG,
 	 TYPE_PCI1730,
-	 {{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
-	 {{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0} },
+	 { {16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
 	 TYPE_PCI1733,
-	 {{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
 	 TYPE_PCI1734,
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1735", PCI_VENDOR_ID_ADVANTECH, 0x1735, PCIDIO_MAINREG,
 	 TYPE_PCI1735,
-	 {{32, PCI1735_DI, 4, 0}, {0, 0, 0, 0}},
-	 {{32, PCI1735_DO, 4, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {32, PCI1735_DI, 4, 0}, {0, 0, 0, 0} },
+	 { {32, PCI1735_DO, 4, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 { 4, PCI1735_BOARDID, 1, SDF_INTERNAL},
-	 {{3, PCI1735_C8254, 1, 0}},
+	 { {3, PCI1735_C8254, 1, 0} },
 	 IO_8b},
 	{"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
 	 TYPE_PCI1736,
-	 {{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
-	 {{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0} },
+	 { {0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI1736_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
 	 TYPE_PCI1750,
-	 {{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
-	 {{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0} },
+	 { {0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {0, 0, 0, 0},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
 	 TYPE_PCI1751,
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0} },
 	 {0, 0, 0, 0},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
 	 TYPE_PCI1752,
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_16b},
 	{"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
 	 TYPE_PCI1753,
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0} },
 	 {0, 0, 0, 0},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
 	 TYPE_PCI1753E,
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0} },
 	 {0, 0, 0, 0},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
 	 TYPE_PCI1754,
-	 {{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_16b},
 	{"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
 	 TYPE_PCI1756,
-	 {{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
-	 {{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0} },
+	 { {0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_16b},
 	{"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
 	 TYPE_PCI1760,
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},	/*  This card have own setup work */
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} }, /* This card have own setup work */
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {0, 0, 0, 0},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_8b},
 	{"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
 	 TYPE_PCI1762,
-	 {{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
-	 {{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
-	 {{0, 0, 0, 0}, {0, 0, 0, 0}},
+	 { {0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0} },
+	 { {0, 0, 0, 0}, {16, PCI1762_RO, 1, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 {4, PCI1762_BOARDID, 1, SDF_INTERNAL},
-	 {{0, 0, 0, 0}},
+	 { {0, 0, 0, 0} },
 	 IO_16b}
 };
 
@@ -372,13 +406,16 @@ struct pci_dio_private {
 	char valid;		/*  card is usable */
 	char GlobalIrqEnabled;	/*  1= any IRQ source is enabled */
 	/*  PCI-1760 specific data */
-	unsigned char IDICntEnable;	/*  counter's counting enable status */
-	unsigned char IDICntOverEnable;	/*  counter's overflow interrupts enable status */
-	unsigned char IDICntMatchEnable;	/*  counter's match interrupts enable status */
-	unsigned char IDICntEdge;	/*  counter's count edge value (bit=0 - rising, =1 - falling) */
+	unsigned char IDICntEnable;	/* counter's counting enable status */
+	unsigned char IDICntOverEnable;	/* counter's overflow interrupts enable
+					 * status */
+	unsigned char IDICntMatchEnable;	/* counter's match interrupts
+						 * enable status */
+	unsigned char IDICntEdge;	/* counter's count edge value
+					 * (bit=0 - rising, =1 - falling) */
 	unsigned short CntResValue[8];	/*  counters' reset value */
-	unsigned short CntMatchValue[8];	/*  counters' match interrupt value */
-	unsigned char IDIFiltersEn;	/*  IDI's digital filters enable status */
+	unsigned short CntMatchValue[8]; /*  counters' match interrupt value */
+	unsigned char IDIFiltersEn; /*  IDI's digital filters enable status */
 	unsigned char IDIPatMatchEn;	/*  IDI's pattern match enable status */
 	unsigned char IDIPatMatchValue;	/*  IDI's pattern match value */
 	unsigned short IDIFiltrLow[8];	/*  IDI's filter value low signal */
@@ -691,7 +728,8 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev,
 	};
 	unsigned char imb[4];
 
-	if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {	/*  Set reset value if different */
+	/* Set reset value if different */
+	if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {
 		ret = pci1760_mbxrequest(dev, omb, imb);
 		if (!ret)
 			return ret;
@@ -704,7 +742,8 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev,
 	if (!ret)
 		return ret;
 
-	if (!(bitmask & devpriv->IDICntEnable)) {	/*  start counter if it don't run */
+	/*  start counter if it don't run */
+	if (!(bitmask & devpriv->IDICntEnable)) {
 		omb[0] = bitmask;
 		omb[2] = CMD_EnableIDICounters;
 		ret = pci1760_mbxrequest(dev, omb, imb);
@@ -740,12 +779,14 @@ static int pci1760_reset(struct comedi_device *dev)
 	devpriv->IDICntEnable = 0;
 
 	omb[0] = 0x00;
-	omb[2] = CMD_OverflowIDICounters;	/*  disable counters overflow interrupts */
+	omb[2] = CMD_OverflowIDICounters; /* disable counters overflow
+					   * interrupts */
 	pci1760_mbxrequest(dev, omb, imb);
 	devpriv->IDICntOverEnable = 0;
 
 	omb[0] = 0x00;
-	omb[2] = CMD_MatchIntIDICounters;	/*  disable counters match value interrupts */
+	omb[2] = CMD_MatchIntIDICounters; /* disable counters match value
+					   * interrupts */
 	pci1760_mbxrequest(dev, omb, imb);
 	devpriv->IDICntMatchEnable = 0;
 
@@ -766,7 +807,8 @@ static int pci1760_reset(struct comedi_device *dev)
 	}
 
 	omb[0] = 0xff;
-	omb[2] = CMD_ResetIDICounters;	/*  reset IDI up counters to reset values */
+	omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset
+					* values */
 	pci1760_mbxrequest(dev, omb, imb);
 
 	omb[0] = 0x00;
@@ -807,9 +849,12 @@ static int pci_dio_reset(struct comedi_device *dev)
 		outb(0, dev->iobase + PCI1730_IDO + 1);
 		/* NO break there! */
 	case TYPE_PCI1733:
-		outb(0, dev->iobase + PCI1730_3_INT_EN);	/*  disable interrupts */
-		outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);	/*  clear interrupts */
-		outb(0, dev->iobase + PCI1730_3_INT_RF);	/*  set rising edge trigger */
+		/* disable interrupts */
+		outb(0, dev->iobase + PCI1730_3_INT_EN);
+		/* clear interrupts */
+		outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);
+		/* set rising edge trigger */
+		outb(0, dev->iobase + PCI1730_3_INT_RF);
 		break;
 	case TYPE_PCI1734:
 		outb(0, dev->iobase + PCI1734_IDO);	/*  clear outputs */
@@ -830,43 +875,53 @@ static int pci_dio_reset(struct comedi_device *dev)
 	case TYPE_PCI1736:
 		outb(0, dev->iobase + PCI1736_IDO);
 		outb(0, dev->iobase + PCI1736_IDO + 1);
-		outb(0, dev->iobase + PCI1736_3_INT_EN);	/*  disable interrupts */
-		outb(0x0f, dev->iobase + PCI1736_3_INT_CLR);	/*  clear interrupts */
-		outb(0, dev->iobase + PCI1736_3_INT_RF);	/*  set rising edge trigger */
+		/* disable interrupts */
+		outb(0, dev->iobase + PCI1736_3_INT_EN);
+		/* clear interrupts */
+		outb(0x0f, dev->iobase + PCI1736_3_INT_CLR);
+		/* set rising edge trigger */
+		outb(0, dev->iobase + PCI1736_3_INT_RF);
 		break;
 
 	case TYPE_PCI1750:
 	case TYPE_PCI1751:
-		outb(0x88, dev->iobase + PCI1750_ICR);	/*  disable & clear interrupts */
+		/* disable & clear interrupts */
+		outb(0x88, dev->iobase + PCI1750_ICR);
 		break;
 	case TYPE_PCI1752:
-		outw(0, dev->iobase + PCI1752_6_CFC);	/*  disable channel freeze function */
+		outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
+						       * function */
 		outw(0, dev->iobase + PCI1752_IDO);	/*  clear outputs */
 		outw(0, dev->iobase + PCI1752_IDO + 2);
 		outw(0, dev->iobase + PCI1752_IDO2);
 		outw(0, dev->iobase + PCI1752_IDO2 + 2);
 		break;
 	case TYPE_PCI1753E:
-		outb(0x88, dev->iobase + PCI1753E_ICR0);	/*  disable & clear interrupts */
+		outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear
+							  * interrupts */
 		outb(0x80, dev->iobase + PCI1753E_ICR1);
 		outb(0x80, dev->iobase + PCI1753E_ICR2);
 		outb(0x80, dev->iobase + PCI1753E_ICR3);
 		/* NO break there! */
 	case TYPE_PCI1753:
-		outb(0x88, dev->iobase + PCI1753_ICR0);	/*  disable & clear interrupts */
+		outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear
+							 * interrupts */
 		outb(0x80, dev->iobase + PCI1753_ICR1);
 		outb(0x80, dev->iobase + PCI1753_ICR2);
 		outb(0x80, dev->iobase + PCI1753_ICR3);
 		break;
 	case TYPE_PCI1754:
-		outw(0x08, dev->iobase + PCI1754_6_ICR0);	/*  disable and clear interrupts */
+		outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
+							   * interrupts */
 		outw(0x08, dev->iobase + PCI1754_6_ICR1);
 		outw(0x08, dev->iobase + PCI1754_ICR2);
 		outw(0x08, dev->iobase + PCI1754_ICR3);
 		break;
 	case TYPE_PCI1756:
-		outw(0, dev->iobase + PCI1752_6_CFC);	/*  disable channel freeze function */
-		outw(0x08, dev->iobase + PCI1754_6_ICR0);	/*  disable and clear interrupts */
+		outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
+						       * function */
+		outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
+							   * interrupts */
 		outw(0x08, dev->iobase + PCI1754_6_ICR1);
 		outw(0, dev->iobase + PCI1756_IDO);	/*  clear outputs */
 		outw(0, dev->iobase + PCI1756_IDO + 2);
@@ -875,7 +930,8 @@ static int pci_dio_reset(struct comedi_device *dev)
 		pci1760_reset(dev);
 		break;
 	case TYPE_PCI1762:
-		outw(0x0101, dev->iobase + PCI1762_ICR);	/*  disable & clear interrupts */
+		outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear
+							  * interrupts */
 		break;
 	}
 
@@ -996,7 +1052,7 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
 ==============================================================================
 */
 static int pci_dio_add_8254(struct comedi_device *dev,
-			    struct comedi_subdevice * s,
+			    struct comedi_subdevice *s,
 			    const struct diosubd_data *d, int subdev)
 {
 	s->type = COMEDI_SUBD_COUNTER;
@@ -1023,7 +1079,7 @@ static int CheckAndAllocCard(struct comedi_device *dev,
 
 	for (pr = pci_priv, prev = NULL; pr != NULL; prev = pr, pr = pr->next) {
 		if (pr->pcidev == pcidev)
-			return 0;	/*  this card is used, look for another */
+			return 0; /* this card is used, look for another */
 
 	}
 
@@ -1048,7 +1104,7 @@ static int pci_dio_attach(struct comedi_device *dev,
 	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices, i, j;
 	unsigned long iobase;
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 
 	printk("comedi%d: adv_pci_dio: ", dev->minor);
 
@@ -1058,9 +1114,7 @@ static int pci_dio_attach(struct comedi_device *dev,
 		return -ENOMEM;
 	}
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		/*  loop through cards supported by this driver */
 		for (i = 0; i < n_boardtypes; ++i) {
 			if (boardtypes[i].vendor_id != pcidev->vendor)
@@ -1215,15 +1269,12 @@ static int pci_dio_detach(struct comedi_device *dev)
 			}
 		}
 
-		if (this_board->boardid.chans) {
+		if (this_board->boardid.chans)
 			subdev++;
-		}
 
-		for (i = 0; i < MAX_8254_SUBDEVS; i++) {
-			if (this_board->s8254[i].chans) {
+		for (i = 0; i < MAX_8254_SUBDEVS; i++)
+			if (this_board->s8254[i].chans)
 				subdev++;
-			}
-		}
 
 		for (i = 0; i < dev->n_subdevices; i++) {
 			s = dev->subdevices + i;
@@ -1253,7 +1304,47 @@ static int pci_dio_detach(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-COMEDI_PCI_INITCLEANUP(driver_pci_dio, pci_dio_pci_table);
+static int __devinit driver_pci_dio_pci_probe(struct pci_dev *dev,
+					      const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_pci_dio.driver_name);
+}
+
+static void __devexit driver_pci_dio_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_pci_dio_pci_driver = {
+	.id_table = pci_dio_pci_table,
+	.probe = &driver_pci_dio_pci_probe,
+	.remove = __devexit_p(&driver_pci_dio_pci_remove)
+};
+
+static int __init driver_pci_dio_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_pci_dio);
+	if (retval < 0)
+		return retval;
+
+	driver_pci_dio_pci_driver.name = (char *)driver_pci_dio.driver_name;
+	return pci_register_driver(&driver_pci_dio_pci_driver);
+}
+
+static void __exit driver_pci_dio_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_pci_dio_pci_driver);
+	comedi_driver_unregister(&driver_pci_dio);
+}
+
+module_init(driver_pci_dio_init_module);
+module_exit(driver_pci_dio_cleanup_module);
 /*
 ==============================================================================
 */
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 16 - 1
drivers/staging/comedi/drivers/aio_aio12_8.c

@@ -227,4 +227,19 @@ static struct comedi_driver driver_aio_aio12_8 = {
 	.offset = sizeof(struct aio12_8_boardtype),
 };
 
-COMEDI_INITCLEANUP(driver_aio_aio12_8);
+static int __init driver_aio_aio12_8_init_module(void)
+{
+	return comedi_driver_register(&driver_aio_aio12_8);
+}
+
+static void __exit driver_aio_aio12_8_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_aio_aio12_8);
+}
+
+module_init(driver_aio_aio12_8_init_module);
+module_exit(driver_aio_aio12_8_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 16 - 1
drivers/staging/comedi/drivers/aio_iiro_16.c

@@ -184,4 +184,19 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
 	return 2;
 }
 
-COMEDI_INITCLEANUP(driver_aio_iiro_16);
+static int __init driver_aio_iiro_16_init_module(void)
+{
+	return comedi_driver_register(&driver_aio_iiro_16);
+}
+
+static void __exit driver_aio_iiro_16_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_aio_iiro_16);
+}
+
+module_init(driver_aio_iiro_16_init_module);
+module_exit(driver_aio_iiro_16_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 11 - 11
drivers/staging/comedi/drivers/am9513.h

@@ -47,32 +47,32 @@
 #ifdef Am9513_8BITBUS
 
 #define Am9513_write_register(reg, val)				\
-	do{							\
+	do {							\
 		Am9513_output_control(reg);			\
 		Am9513_output_data(val>>8);			\
 		Am9513_output_data(val&0xff);			\
-	}while (0)
+	} while (0)
 
 #define Am9513_read_register(reg, val)				\
-	do{							\
+	do {							\
 		Am9513_output_control(reg);			\
-		val=Am9513_input_data()<<8;			\
-		val|=Am9513_input_data();			\
-	}while (0)
+		val = Am9513_input_data()<<8;			\
+		val |= Am9513_input_data();			\
+	} while (0)
 
 #else /* Am9513_16BITBUS */
 
 #define Am9513_write_register(reg, val)				\
-	do{							\
+	do {							\
 		Am9513_output_control(reg);			\
 		Am9513_output_data(val);			\
-	}while (0)
+	} while (0)
 
 #define Am9513_read_register(reg, val)				\
-	do{							\
+	do {							\
 		Am9513_output_control(reg);			\
-		val=Am9513_input_data();			\
-	}while (0)
+		val = Am9513_input_data();			\
+	} while (0)
 
 #endif
 

+ 55 - 2
drivers/staging/comedi/drivers/amplc_dio200.c

@@ -494,9 +494,58 @@ static struct comedi_driver driver_amplc_dio200 = {
 };
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
+static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev,
+						   const struct pci_device_id
+						   *ent)
+{
+	return comedi_pci_auto_config(dev, driver_amplc_dio200.driver_name);
+}
+
+static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_dio200_pci_driver = {
+	.id_table = dio200_pci_table,
+	.probe = &driver_amplc_dio200_pci_probe,
+	.remove = __devexit_p(&driver_amplc_dio200_pci_remove)
+};
+
+static int __init driver_amplc_dio200_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_amplc_dio200);
+	if (retval < 0)
+		return retval;
+
+	driver_amplc_dio200_pci_driver.name =
+	    (char *)driver_amplc_dio200.driver_name;
+	return pci_register_driver(&driver_amplc_dio200_pci_driver);
+}
+
+static void __exit driver_amplc_dio200_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_amplc_dio200_pci_driver);
+	comedi_driver_unregister(&driver_amplc_dio200);
+}
+
+module_init(driver_amplc_dio200_init_module);
+module_exit(driver_amplc_dio200_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_amplc_dio200);
+static int __init driver_amplc_dio200_init_module(void)
+{
+	return comedi_driver_register(&driver_amplc_dio200);
+}
+
+static void __exit driver_amplc_dio200_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_amplc_dio200);
+}
+
+module_init(driver_amplc_dio200_init_module);
+module_exit(driver_amplc_dio200_cleanup_module);
 #endif
 
 /*
@@ -1501,3 +1550,7 @@ static int dio200_detach(struct comedi_device *dev)
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 55 - 2
drivers/staging/comedi/drivers/amplc_pc236.c

@@ -182,9 +182,58 @@ static struct comedi_driver driver_amplc_pc236 = {
 };
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_amplc_pc236, pc236_pci_table);
+static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev,
+						  const struct pci_device_id
+						  *ent)
+{
+	return comedi_pci_auto_config(dev, driver_amplc_pc236.driver_name);
+}
+
+static void __devexit driver_amplc_pc236_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pc236_pci_driver = {
+	.id_table = pc236_pci_table,
+	.probe = &driver_amplc_pc236_pci_probe,
+	.remove = __devexit_p(&driver_amplc_pc236_pci_remove)
+};
+
+static int __init driver_amplc_pc236_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_amplc_pc236);
+	if (retval < 0)
+		return retval;
+
+	driver_amplc_pc236_pci_driver.name =
+	    (char *)driver_amplc_pc236.driver_name;
+	return pci_register_driver(&driver_amplc_pc236_pci_driver);
+}
+
+static void __exit driver_amplc_pc236_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_amplc_pc236_pci_driver);
+	comedi_driver_unregister(&driver_amplc_pc236);
+}
+
+module_init(driver_amplc_pc236_init_module);
+module_exit(driver_amplc_pc236_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_amplc_pc236);
+static int __init driver_amplc_pc236_init_module(void)
+{
+	return comedi_driver_register(&driver_amplc_pc236);
+}
+
+static void __exit driver_amplc_pc236_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_amplc_pc236);
+}
+
+module_init(driver_amplc_pc236_init_module);
+module_exit(driver_amplc_pc236_cleanup_module);
 #endif
 
 static int pc236_request_region(unsigned minor, unsigned long from,
@@ -664,3 +713,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d)
 	}
 	return IRQ_RETVAL(handled);
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 55 - 2
drivers/staging/comedi/drivers/amplc_pc263.c

@@ -432,7 +432,60 @@ static int pc263_dio_insn_config(struct comedi_device *dev,
  * as necessary.
  */
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_amplc_pc263, pc263_pci_table);
+static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev,
+						  const struct pci_device_id
+						  *ent)
+{
+	return comedi_pci_auto_config(dev, driver_amplc_pc263.driver_name);
+}
+
+static void __devexit driver_amplc_pc263_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pc263_pci_driver = {
+	.id_table = pc263_pci_table,
+	.probe = &driver_amplc_pc263_pci_probe,
+	.remove = __devexit_p(&driver_amplc_pc263_pci_remove)
+};
+
+static int __init driver_amplc_pc263_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_amplc_pc263);
+	if (retval < 0)
+		return retval;
+
+	driver_amplc_pc263_pci_driver.name =
+	    (char *)driver_amplc_pc263.driver_name;
+	return pci_register_driver(&driver_amplc_pc263_pci_driver);
+}
+
+static void __exit driver_amplc_pc263_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_amplc_pc263_pci_driver);
+	comedi_driver_unregister(&driver_amplc_pc263);
+}
+
+module_init(driver_amplc_pc263_init_module);
+module_exit(driver_amplc_pc263_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_amplc_pc263);
+static int __init driver_amplc_pc263_init_module(void)
+{
+	return comedi_driver_register(&driver_amplc_pc263);
+}
+
+static void __exit driver_amplc_pc263_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_amplc_pc263);
+}
+
+module_init(driver_amplc_pc263_init_module);
+module_exit(driver_amplc_pc263_cleanup_module);
 #endif
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 43 - 1
drivers/staging/comedi/drivers/amplc_pci224.c

@@ -443,7 +443,45 @@ static struct comedi_driver driver_amplc_pci224 = {
 	.num_names = ARRAY_SIZE(pci224_boards),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
+static int __devinit driver_amplc_pci224_pci_probe(struct pci_dev *dev,
+						   const struct pci_device_id
+						   *ent)
+{
+	return comedi_pci_auto_config(dev, driver_amplc_pci224.driver_name);
+}
+
+static void __devexit driver_amplc_pci224_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pci224_pci_driver = {
+	.id_table = pci224_pci_table,
+	.probe = &driver_amplc_pci224_pci_probe,
+	.remove = __devexit_p(&driver_amplc_pci224_pci_remove)
+};
+
+static int __init driver_amplc_pci224_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_amplc_pci224);
+	if (retval < 0)
+		return retval;
+
+	driver_amplc_pci224_pci_driver.name =
+	    (char *)driver_amplc_pci224.driver_name;
+	return pci_register_driver(&driver_amplc_pci224_pci_driver);
+}
+
+static void __exit driver_amplc_pci224_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_amplc_pci224_pci_driver);
+	comedi_driver_unregister(&driver_amplc_pci224);
+}
+
+module_init(driver_amplc_pci224_init_module);
+module_exit(driver_amplc_pci224_cleanup_module);
 
 /*
  * Called from the 'insn_write' function to perform a single write.
@@ -1557,3 +1595,7 @@ static int pci224_detach(struct comedi_device *dev)
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 45 - 5
drivers/staging/comedi/drivers/amplc_pci230.c

@@ -617,7 +617,45 @@ static struct comedi_driver driver_amplc_pci230 = {
 	.num_names = ARRAY_SIZE(pci230_boards),
 };
 
-COMEDI_PCI_INITCLEANUP(driver_amplc_pci230, pci230_pci_table);
+static int __devinit driver_amplc_pci230_pci_probe(struct pci_dev *dev,
+						   const struct pci_device_id
+						   *ent)
+{
+	return comedi_pci_auto_config(dev, driver_amplc_pci230.driver_name);
+}
+
+static void __devexit driver_amplc_pci230_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_amplc_pci230_pci_driver = {
+	.id_table = pci230_pci_table,
+	.probe = &driver_amplc_pci230_pci_probe,
+	.remove = __devexit_p(&driver_amplc_pci230_pci_remove)
+};
+
+static int __init driver_amplc_pci230_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_amplc_pci230);
+	if (retval < 0)
+		return retval;
+
+	driver_amplc_pci230_pci_driver.name =
+	    (char *)driver_amplc_pci230.driver_name;
+	return pci_register_driver(&driver_amplc_pci230_pci_driver);
+}
+
+static void __exit driver_amplc_pci230_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_amplc_pci230_pci_driver);
+	comedi_driver_unregister(&driver_amplc_pci230);
+}
+
+module_init(driver_amplc_pci230_init_module);
+module_exit(driver_amplc_pci230_cleanup_module);
 
 static int pci230_ai_rinsn(struct comedi_device *dev,
 			   struct comedi_subdevice *s, struct comedi_insn *insn,
@@ -726,7 +764,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	struct comedi_subdevice *s;
 	unsigned long iobase1, iobase2;
 	/* PCI230's I/O spaces 1 and 2 respectively. */
-	struct pci_dev *pci_dev;
+	struct pci_dev *pci_dev = NULL;
 	int i = 0, irq_hdl, rc;
 
 	printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
@@ -742,9 +780,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	spin_lock_init(&devpriv->ai_stop_spinlock);
 	spin_lock_init(&devpriv->ao_stop_spinlock);
 	/* Find card */
-	for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pci_dev != NULL;
-	     pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+	for_each_pci_dev(pci_dev) {
 		if (it->options[0] || it->options[1]) {
 			/* Match against bus/slot options. */
 			if (it->options[0] != pci_dev->bus->number ||
@@ -3014,3 +3050,7 @@ static int pci230_ai_cancel(struct comedi_device *dev,
 	pci230_ai_stop(dev, s);
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 16 - 1
drivers/staging/comedi/drivers/c6xdigio.c

@@ -517,4 +517,19 @@ static int c6xdigio_detach(struct comedi_device *dev)
 	return 0;
 }
 
-COMEDI_INITCLEANUP(driver_c6xdigio);
+static int __init driver_c6xdigio_init_module(void)
+{
+	return comedi_driver_register(&driver_c6xdigio);
+}
+
+static void __exit driver_c6xdigio_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_c6xdigio);
+}
+
+module_init(driver_c6xdigio_init_module);
+module_exit(driver_c6xdigio_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 13 - 3
drivers/staging/comedi/drivers/cb_das16_cs.c

@@ -719,8 +719,7 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
 	((struct local_info_t *)link->priv)->stop = 1;
 	das16cs_pcmcia_release(link);
 	/* This points to the parent struct local_info_t struct */
-	if (link->priv)
-		kfree(link->priv);
+	kfree(link->priv);
 }				/* das16cs_pcmcia_detach */
 
 
@@ -881,5 +880,16 @@ void __exit cleanup_module(void)
 }
 
 #else
-COMEDI_INITCLEANUP(driver_das16cs);
+static int __init driver_das16cs_init_module(void)
+{
+	return comedi_driver_register(&driver_das16cs);
+}
+
+static void __exit driver_das16cs_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_das16cs);
+}
+
+module_init(driver_das16cs_init_module);
+module_exit(driver_das16cs_cleanup_module);
 #endif /* CONFIG_PCMCIA */

+ 43 - 5
drivers/staging/comedi/drivers/cb_pcidas.c

@@ -533,7 +533,7 @@ static int cb_pcidas_attach(struct comedi_device *dev,
 			    struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	int index;
 	int i;
 
@@ -550,9 +550,7 @@ static int cb_pcidas_attach(struct comedi_device *dev,
  */
 	printk("\n");
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
 		if (pcidev->vendor != PCI_VENDOR_ID_CB)
 			continue;
@@ -1871,4 +1869,44 @@ static int nvram_read(struct comedi_device *dev, unsigned int address,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);
+static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev,
+						const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name);
+}
+
+static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidas_pci_driver = {
+	.id_table = cb_pcidas_pci_table,
+	.probe = &driver_cb_pcidas_pci_probe,
+	.remove = __devexit_p(&driver_cb_pcidas_pci_remove)
+};
+
+static int __init driver_cb_pcidas_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_cb_pcidas);
+	if (retval < 0)
+		return retval;
+
+	driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name;
+	return pci_register_driver(&driver_cb_pcidas_pci_driver);
+}
+
+static void __exit driver_cb_pcidas_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_cb_pcidas_pci_driver);
+	comedi_driver_unregister(&driver_cb_pcidas);
+}
+
+module_init(driver_cb_pcidas_init_module);
+module_exit(driver_cb_pcidas_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 43 - 5
drivers/staging/comedi/drivers/cb_pcidas64.c

@@ -1237,7 +1237,43 @@ static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags);
 static void load_ao_dma(struct comedi_device *dev,
 			const struct comedi_cmd *cmd);
 
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, pcidas64_pci_table);
+static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev,
+						const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name);
+}
+
+static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidas_pci_driver = {
+	.id_table = pcidas64_pci_table,
+	.probe = &driver_cb_pcidas_pci_probe,
+	.remove = __devexit_p(&driver_cb_pcidas_pci_remove)
+};
+
+static int __init driver_cb_pcidas_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_cb_pcidas);
+	if (retval < 0)
+		return retval;
+
+	driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name;
+	return pci_register_driver(&driver_cb_pcidas_pci_driver);
+}
+
+static void __exit driver_cb_pcidas_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_cb_pcidas_pci_driver);
+	comedi_driver_unregister(&driver_cb_pcidas);
+}
+
+module_init(driver_cb_pcidas_init_module);
+module_exit(driver_cb_pcidas_cleanup_module);
 
 static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
 				       unsigned int range_index)
@@ -1718,7 +1754,7 @@ static inline void warn_external_queue(struct comedi_device *dev)
  */
 static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	int index;
 	uint32_t local_range, local_decode;
 	int retval;
@@ -1735,9 +1771,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
  * Probe the device to determine what device in the series it is.
  */
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
 		if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
 			continue;
@@ -4303,3 +4337,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
 	}
 	i2c_stop(dev);
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 43 - 5
drivers/staging/comedi/drivers/cb_pcidda.c

@@ -280,7 +280,7 @@ static int cb_pcidda_attach(struct comedi_device *dev,
 			    struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	int index;
 
 	printk("comedi%d: cb_pcidda: ", dev->minor);
@@ -296,9 +296,7 @@ static int cb_pcidda_attach(struct comedi_device *dev,
  */
 	printk("\n");
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_CB) {
 			if (it->options[0] || it->options[1]) {
 				if (pcidev->bus->number != it->options[0] ||
@@ -856,4 +854,44 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidda, cb_pcidda_pci_table);
+static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev,
+						const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name);
+}
+
+static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidda_pci_driver = {
+	.id_table = cb_pcidda_pci_table,
+	.probe = &driver_cb_pcidda_pci_probe,
+	.remove = __devexit_p(&driver_cb_pcidda_pci_remove)
+};
+
+static int __init driver_cb_pcidda_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_cb_pcidda);
+	if (retval < 0)
+		return retval;
+
+	driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name;
+	return pci_register_driver(&driver_cb_pcidda_pci_driver);
+}
+
+static void __exit driver_cb_pcidda_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_cb_pcidda_pci_driver);
+	comedi_driver_unregister(&driver_cb_pcidda);
+}
+
+module_init(driver_cb_pcidda_init_module);
+module_exit(driver_cb_pcidda_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 42 - 4
drivers/staging/comedi/drivers/cb_pcidio.c

@@ -202,9 +202,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  * Probe the device to determine what device in the series it is.
  */
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
 		if (pcidev->vendor != PCI_VENDOR_ID_CB)
 			continue;
@@ -300,4 +298,44 @@ static int pcidio_detach(struct comedi_device *dev)
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcidio, pcidio_pci_table);
+static int __devinit driver_cb_pcidio_pci_probe(struct pci_dev *dev,
+						const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_cb_pcidio.driver_name);
+}
+
+static void __devexit driver_cb_pcidio_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcidio_pci_driver = {
+	.id_table = pcidio_pci_table,
+	.probe = &driver_cb_pcidio_pci_probe,
+	.remove = __devexit_p(&driver_cb_pcidio_pci_remove)
+};
+
+static int __init driver_cb_pcidio_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_cb_pcidio);
+	if (retval < 0)
+		return retval;
+
+	driver_cb_pcidio_pci_driver.name = (char *)driver_cb_pcidio.driver_name;
+	return pci_register_driver(&driver_cb_pcidio_pci_driver);
+}
+
+static void __exit driver_cb_pcidio_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_cb_pcidio_pci_driver);
+	comedi_driver_unregister(&driver_cb_pcidio);
+}
+
+module_init(driver_cb_pcidio_init_module);
+module_exit(driver_cb_pcidio_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 45 - 5
drivers/staging/comedi/drivers/cb_pcimdas.c

@@ -210,7 +210,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev,
 			     struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	int index;
 	/* int i; */
 
@@ -227,9 +227,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev,
  */
 	printk("\n");
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
 		if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
 			continue;
@@ -491,4 +489,46 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev,
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
  */
-COMEDI_PCI_INITCLEANUP(driver_cb_pcimdas, cb_pcimdas_pci_table);
+static int __devinit driver_cb_pcimdas_pci_probe(struct pci_dev *dev,
+						 const struct pci_device_id
+						 *ent)
+{
+	return comedi_pci_auto_config(dev, driver_cb_pcimdas.driver_name);
+}
+
+static void __devexit driver_cb_pcimdas_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_cb_pcimdas_pci_driver = {
+	.id_table = cb_pcimdas_pci_table,
+	.probe = &driver_cb_pcimdas_pci_probe,
+	.remove = __devexit_p(&driver_cb_pcimdas_pci_remove)
+};
+
+static int __init driver_cb_pcimdas_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_cb_pcimdas);
+	if (retval < 0)
+		return retval;
+
+	driver_cb_pcimdas_pci_driver.name =
+	    (char *)driver_cb_pcimdas.driver_name;
+	return pci_register_driver(&driver_cb_pcimdas_pci_driver);
+}
+
+static void __exit driver_cb_pcimdas_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_cb_pcimdas_pci_driver);
+	comedi_driver_unregister(&driver_cb_pcimdas);
+}
+
+module_init(driver_cb_pcimdas_init_module);
+module_exit(driver_cb_pcimdas_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 41 - 5
drivers/staging/comedi/drivers/cb_pcimdda.c

@@ -195,7 +195,45 @@ MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
 		   "series.  Currently only supports PCIM-DDA06-16 (which "
 		   "also happens to be the only board in this series. :) ) ");
 MODULE_LICENSE("GPL");
-COMEDI_PCI_INITCLEANUP_NOMODULE(cb_pcimdda_driver, pci_table);
+static int __devinit cb_pcimdda_driver_pci_probe(struct pci_dev *dev,
+						 const struct pci_device_id
+						 *ent)
+{
+	return comedi_pci_auto_config(dev, cb_pcimdda_driver.driver_name);
+}
+
+static void __devexit cb_pcimdda_driver_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver cb_pcimdda_driver_pci_driver = {
+	.id_table = pci_table,
+	.probe = &cb_pcimdda_driver_pci_probe,
+	.remove = __devexit_p(&cb_pcimdda_driver_pci_remove)
+};
+
+static int __init cb_pcimdda_driver_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&cb_pcimdda_driver);
+	if (retval < 0)
+		return retval;
+
+	cb_pcimdda_driver_pci_driver.name =
+	    (char *)cb_pcimdda_driver.driver_name;
+	return pci_register_driver(&cb_pcimdda_driver_pci_driver);
+}
+
+static void __exit cb_pcimdda_driver_cleanup_module(void)
+{
+	pci_unregister_driver(&cb_pcimdda_driver_pci_driver);
+	comedi_driver_unregister(&cb_pcimdda_driver);
+}
+
+module_init(cb_pcimdda_driver_init_module);
+module_exit(cb_pcimdda_driver_cleanup_module);
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 		    struct comedi_insn *insn, unsigned int *data);
@@ -426,13 +464,11 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  */
 static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	int index;
 	unsigned long registers;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
 		if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
 			continue;

+ 0 - 37
drivers/staging/comedi/drivers/comedi_bond.c

@@ -50,43 +50,6 @@ Configuration Options:
   within each minor will be concatenated together in the order given here.
 */
 
-/*
- * The previous block comment is used to automatically generate
- * documentation in Comedi and Comedilib.  The fields:
- *
- * Driver: the name of the driver
- * Description: a short phrase describing the driver.  Don't list boards.
- * Devices: a full list of the boards that attempt to be supported by
- *   the driver.  Format is "(manufacturer) board name [comedi name]",
- *   where comedi_name is the name that is used to configure the board.
- *   See the comment near board_name: in the struct comedi_driver structure
- *   below.  If (manufacturer) or [comedi name] is missing, the previous
- *   value is used.
- * Author: you
- * Updated: date when the _documentation_ was last updated.  Use 'date -R'
- *   to get a value for this.
- * Status: a one-word description of the status.  Valid values are:
- *   works - driver works correctly on most boards supported, and
- *     passes comedi_test.
- *   unknown - unknown.  Usually put there by ds.
- *   experimental - may not work in any particular release.  Author
- *     probably wants assistance testing it.
- *   bitrotten - driver has not been update in a long time, probably
- *     doesn't work, and probably is missing support for significant
- *     Comedi interface features.
- *   untested - author probably wrote it "blind", and is believed to
- *     work, but no confirmation.
- *
- * These headers should be followed by a blank line, and any comments
- * you wish to say about the driver.  The comment area is the place
- * to put any known bugs, limitations, unsupported features, supported
- * command triggers, whether or not commands are supported on particular
- * subdevices, etc.
- *
- * Somewhere in the comment should be information about configuration
- * options that are used with comedi_config.
- */
-
 #include <linux/string.h>
 #include <linux/slab.h>
 #include "../comedi.h"

+ 16 - 1
drivers/staging/comedi/drivers/comedi_parport.c

@@ -101,7 +101,18 @@ static struct comedi_driver driver_parport = {
 	.detach = parport_detach,
 };
 
-COMEDI_INITCLEANUP(driver_parport);
+static int __init driver_parport_init_module(void)
+{
+	return comedi_driver_register(&driver_parport);
+}
+
+static void __exit driver_parport_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_parport);
+}
+
+module_init(driver_parport_init_module);
+module_exit(driver_parport_cleanup_module);
 
 struct parport_private {
 	unsigned int a_data;
@@ -396,3 +407,7 @@ static int parport_detach(struct comedi_device *dev)
 
 	return 0;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 16 - 1
drivers/staging/comedi/drivers/comedi_test.c

@@ -107,7 +107,18 @@ static struct comedi_driver driver_waveform = {
 	.num_names = ARRAY_SIZE(waveform_boards),
 };
 
-COMEDI_INITCLEANUP(driver_waveform);
+static int __init driver_waveform_init_module(void)
+{
+	return comedi_driver_register(&driver_waveform);
+}
+
+static void __exit driver_waveform_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_waveform);
+}
+
+module_init(driver_waveform_init_module);
+module_exit(driver_waveform_cleanup_module);
 
 static int waveform_ai_cmdtest(struct comedi_device *dev,
 			       struct comedi_subdevice *s,
@@ -549,3 +560,7 @@ static int waveform_ao_insn_write(struct comedi_device *dev,
 
 	return insn->n;
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 43 - 6
drivers/staging/comedi/drivers/contec_pci_dio.c

@@ -103,7 +103,7 @@ static int contec_ns_to_timer(unsigned int *ns, int round);
 
 static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	struct pci_dev *pcidev;
+	struct pci_dev *pcidev = NULL;
 	struct comedi_subdevice *s;
 
 	printk("comedi%d: contec: ", dev->minor);
@@ -116,10 +116,7 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (alloc_subdevices(dev, 2) < 0)
 		return -ENOMEM;
 
-	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	     pcidev != NULL;
-	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
-
+	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
 		    pcidev->device == PCI_DEVICE_ID_PIO1616L) {
 			if (it->options[0] || it->options[1]) {
@@ -232,4 +229,44 @@ static int contec_di_insn_bits(struct comedi_device *dev,
 	return 2;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_contec, contec_pci_table);
+static int __devinit driver_contec_pci_probe(struct pci_dev *dev,
+					     const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_contec.driver_name);
+}
+
+static void __devexit driver_contec_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_contec_pci_driver = {
+	.id_table = contec_pci_table,
+	.probe = &driver_contec_pci_probe,
+	.remove = __devexit_p(&driver_contec_pci_remove)
+};
+
+static int __init driver_contec_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_contec);
+	if (retval < 0)
+		return retval;
+
+	driver_contec_pci_driver.name = (char *)driver_contec.driver_name;
+	return pci_register_driver(&driver_contec_pci_driver);
+}
+
+static void __exit driver_contec_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_contec_pci_driver);
+	comedi_driver_unregister(&driver_contec);
+}
+
+module_init(driver_contec_init_module);
+module_exit(driver_contec_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 43 - 1
drivers/staging/comedi/drivers/daqboard2000.c

@@ -887,4 +887,46 @@ static int daqboard2000_detach(struct comedi_device *dev)
 	return 0;
 }
 
-COMEDI_PCI_INITCLEANUP(driver_daqboard2000, daqboard2000_pci_table);
+static int __devinit driver_daqboard2000_pci_probe(struct pci_dev *dev,
+						   const struct pci_device_id
+						   *ent)
+{
+	return comedi_pci_auto_config(dev, driver_daqboard2000.driver_name);
+}
+
+static void __devexit driver_daqboard2000_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_daqboard2000_pci_driver = {
+	.id_table = daqboard2000_pci_table,
+	.probe = &driver_daqboard2000_pci_probe,
+	.remove = __devexit_p(&driver_daqboard2000_pci_remove)
+};
+
+static int __init driver_daqboard2000_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_daqboard2000);
+	if (retval < 0)
+		return retval;
+
+	driver_daqboard2000_pci_driver.name =
+	    (char *)driver_daqboard2000.driver_name;
+	return pci_register_driver(&driver_daqboard2000_pci_driver);
+}
+
+static void __exit driver_daqboard2000_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_daqboard2000_pci_driver);
+	comedi_driver_unregister(&driver_daqboard2000);
+}
+
+module_init(driver_daqboard2000_init_module);
+module_exit(driver_daqboard2000_cleanup_module);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 60 - 11
drivers/staging/comedi/drivers/das08.c

@@ -29,11 +29,11 @@
  * Description: DAS-08 compatible boards
  * Author: Warren Jasper, ds, Frank Hess
  * Devices: [Keithley Metrabyte] DAS08 (isa-das08),
- * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
- * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
- * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
- * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
- * PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
+ *   [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
+ *   DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
+ *   DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
+ *   DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
+ *   PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
  * Status: works
  *
  * This is a rewrite of the das08 and das08jr drivers.
@@ -980,7 +980,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	unsigned long iobase;
 #ifdef CONFIG_COMEDI_PCI
 	unsigned long pci_iobase = 0;
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 #endif
 
 	ret = alloc_private(dev, sizeof(struct das08_private_struct));
@@ -997,9 +997,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		}
 		printk("\n");
 		/*  find card */
-		for (pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-		     pdev != NULL;
-		     pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
+		for_each_pci_dev(pdev) {
 			if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS
 			    && pdev->device == PCI_DEVICE_ID_PCIDAS08) {
 				if (it->options[0] || it->options[1]) {
@@ -1082,11 +1080,62 @@ int das08_common_detach(struct comedi_device *dev)
 EXPORT_SYMBOL_GPL(das08_common_detach);
 
 #ifdef CONFIG_COMEDI_PCI
-COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table);
+static int __devinit driver_das08_pci_probe(struct pci_dev *dev,
+					    const struct pci_device_id *ent)
+{
+	return comedi_pci_auto_config(dev, driver_das08.driver_name);
+}
+
+static void __devexit driver_das08_pci_remove(struct pci_dev *dev)
+{
+	comedi_pci_auto_unconfig(dev);
+}
+
+static struct pci_driver driver_das08_pci_driver = {
+	.id_table = das08_pci_table,
+	.probe = &driver_das08_pci_probe,
+	.remove = __devexit_p(&driver_das08_pci_remove)
+};
+
+static int __init driver_das08_init_module(void)
+{
+	int retval;
+
+	retval = comedi_driver_register(&driver_das08);
+	if (retval < 0)
+		return retval;
+
+	driver_das08_pci_driver.name = (char *)driver_das08.driver_name;
+	return pci_register_driver(&driver_das08_pci_driver);
+}
+
+static void __exit driver_das08_cleanup_module(void)
+{
+	pci_unregister_driver(&driver_das08_pci_driver);
+	comedi_driver_unregister(&driver_das08);
+}
+
+module_init(driver_das08_init_module);
+module_exit(driver_das08_cleanup_module);
 #else
-COMEDI_INITCLEANUP(driver_das08);
+static int __init driver_das08_init_module(void)
+{
+	return comedi_driver_register(&driver_das08);
+}
+
+static void __exit driver_das08_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_das08);
+}
+
+module_init(driver_das08_init_module);
+module_exit(driver_das08_cleanup_module);
 #endif
 
 #ifdef CONFIG_COMEDI_PCMCIA
 EXPORT_SYMBOL_GPL(das08_cs_boards);
 #endif
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

+ 1 - 2
drivers/staging/comedi/drivers/das08_cs.c

@@ -206,8 +206,7 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
 	das08_pcmcia_release(link);
 
 	/* This points to the parent struct local_info_t struct */
-	if (link->priv)
-		kfree(link->priv);
+	kfree(link->priv);
 
 }				/* das08_pcmcia_detach */
 

+ 16 - 1
drivers/staging/comedi/drivers/das16.c

@@ -1717,7 +1717,18 @@ static int das16_detach(struct comedi_device *dev)
 	return 0;
 }
 
-COMEDI_INITCLEANUP(driver_das16);
+static int __init driver_das16_init_module(void)
+{
+	return comedi_driver_register(&driver_das16);
+}
+
+static void __exit driver_das16_cleanup_module(void)
+{
+	comedi_driver_unregister(&driver_das16);
+}
+
+module_init(driver_das16_init_module);
+module_exit(driver_das16_cleanup_module);
 
 /* utility function that suggests a dma transfer size in bytes */
 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
@@ -1776,3 +1787,7 @@ static void das16_ai_munge(struct comedi_device *dev,
 
 	}
 }
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_LICENSE("GPL");

部分文件因文件數量過多而無法顯示