You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (510 commits) staging: speakup: fix failure handling staging: usbip: remove double giveback of URB Staging: batman-adv: Remove batman-adv from staging Staging: hv: Use only one txf buffer per channel and kmalloc/GFP_KERNEL on initialize staging: hv: remove unneeded osd_schedule_callback staging: hv: convert channel_mgmt.c to not call osd_schedule_callback staging: hv: convert vmbus_on_msg_dpc to not call osd_schedule_callback staging: brcm80211: Fix WL_<type> logging macros Staging: IIO: DDS: AD9833 / AD9834 driver Staging: IIO: dds.h convenience macros Staging: IIO: Direct digital synthesis abi documentation staging: brcm80211: Convert ETHER_TYPE_802_1X to ETH_P_PAE staging: brcm80211: Remove unused ETHER_TYPE_<foo> #defines staging: brcm80211: Remove ETHER_HDR_LEN, use ETH_HLEN staging: brcm80211: Convert ETHER_ADDR_LEN to ETH_ALEN staging: brcm80211: Convert ETHER_IS<FOO> to is_<foo>_ether_addr staging: brcm80211: Remove unused ether_<foo> #defines and struct staging: brcm80211: Convert ETHER_IS_MULTI to is_multicast_ether_addr staging: brcm80211: Remove unused #defines ETHER_<foo>_LOCALADDR Staging: comedi: Fix checkpatch.pl issues in file s526.c ... Fix up trivial conflict in drivers/video/udlfb.c
This commit is contained in:
+3
-1
@@ -1423,7 +1423,9 @@ F: drivers/net/tg3.*
|
||||
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
|
||||
M: Brett Rudley <brudley@broadcom.com>
|
||||
M: Henry Ptasinski <henryp@broadcom.com>
|
||||
M: Nohee Ko <noheek@broadcom.com>
|
||||
M: Dowan Kim <dowan@broadcom.com>
|
||||
M: Roland Vossen <rvossen@broadcom.com>
|
||||
M: Arend van Spriel <arend@broadcom.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/staging/brcm80211/
|
||||
|
||||
@@ -119,6 +119,8 @@ source "drivers/staging/vme/Kconfig"
|
||||
|
||||
source "drivers/staging/memrar/Kconfig"
|
||||
|
||||
source "drivers/staging/sep/Kconfig"
|
||||
|
||||
source "drivers/staging/iio/Kconfig"
|
||||
|
||||
source "drivers/staging/zram/Kconfig"
|
||||
@@ -127,8 +129,6 @@ source "drivers/staging/wlags49_h2/Kconfig"
|
||||
|
||||
source "drivers/staging/wlags49_h25/Kconfig"
|
||||
|
||||
source "drivers/staging/batman-adv/Kconfig"
|
||||
|
||||
source "drivers/staging/samsung-laptop/Kconfig"
|
||||
|
||||
source "drivers/staging/sm7xx/Kconfig"
|
||||
@@ -141,8 +141,6 @@ source "drivers/staging/cxt1e1/Kconfig"
|
||||
|
||||
source "drivers/staging/ti-st/Kconfig"
|
||||
|
||||
source "drivers/staging/adis16255/Kconfig"
|
||||
|
||||
source "drivers/staging/xgifb/Kconfig"
|
||||
|
||||
source "drivers/staging/msm/Kconfig"
|
||||
@@ -175,5 +173,9 @@ source "drivers/staging/intel_sst/Kconfig"
|
||||
|
||||
source "drivers/staging/speakup/Kconfig"
|
||||
|
||||
source "drivers/staging/cptm1217/Kconfig"
|
||||
|
||||
source "drivers/staging/ste_rmi4/Kconfig"
|
||||
|
||||
endif # !STAGING_EXCLUDE_BUILD
|
||||
endif # STAGING
|
||||
|
||||
@@ -42,18 +42,17 @@ obj-$(CONFIG_VT6656) += vt6656/
|
||||
obj-$(CONFIG_HYPERV) += hv/
|
||||
obj-$(CONFIG_VME_BUS) += vme/
|
||||
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
|
||||
obj-$(CONFIG_DX_SEP) += sep/
|
||||
obj-$(CONFIG_IIO) += iio/
|
||||
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_VIDEO_DT3155) += dt3155v4l/
|
||||
obj-$(CONFIG_CRYSTALHD) += crystalhd/
|
||||
obj-$(CONFIG_CXT1E1) += cxt1e1/
|
||||
obj-$(CONFIG_TI_ST) += ti-st/
|
||||
obj-$(CONFIG_ADIS16255) += adis16255/
|
||||
obj-$(CONFIG_FB_XGI) += xgifb/
|
||||
obj-$(CONFIG_MSM_STAGING) += msm/
|
||||
obj-$(CONFIG_EASYCAP) += easycap/
|
||||
@@ -68,3 +67,5 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/
|
||||
obj-$(CONFIG_FT1000) += ft1000/
|
||||
obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
|
||||
obj-$(CONFIG_SPEAKUP) += speakup/
|
||||
obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
|
||||
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
config ADIS16255
|
||||
tristate "Analog Devices ADIS16250/16255"
|
||||
depends on SPI && SYSFS
|
||||
---help---
|
||||
If you say yes here you get support for the Analog Devices
|
||||
ADIS16250/16255 Low Power Gyroscope. The driver exposes
|
||||
orientation and gyroscope value, as well as sample rate
|
||||
to the sysfs.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called adis16255.
|
||||
@@ -1 +0,0 @@
|
||||
obj-$(CONFIG_ADIS16255) += adis16255.o
|
||||
@@ -1,468 +0,0 @@
|
||||
/*
|
||||
* Analog Devices ADIS16250/ADIS16255 Low Power Gyroscope
|
||||
*
|
||||
* Written by: Matthias Brugger <m_brugger@web.de>
|
||||
*
|
||||
* Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The driver just has a bare interface to the sysfs (sample rate in Hz,
|
||||
* orientation (x, y, z) and gyroscope data in °/sec.
|
||||
*
|
||||
* It should be added to iio subsystem when this has left staging.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "adis16255.h"
|
||||
|
||||
#define ADIS_STATUS 0x3d
|
||||
#define ADIS_SMPL_PRD_MSB 0x37
|
||||
#define ADIS_SMPL_PRD_LSB 0x36
|
||||
#define ADIS_MSC_CTRL_MSB 0x35
|
||||
#define ADIS_MSC_CTRL_LSB 0x34
|
||||
#define ADIS_GPIO_CTRL 0x33
|
||||
#define ADIS_ALM_SMPL1 0x25
|
||||
#define ADIS_ALM_MAG1 0x21
|
||||
#define ADIS_GYRO_SCALE 0x17
|
||||
#define ADIS_GYRO_OUT 0x05
|
||||
#define ADIS_SUPPLY_OUT 0x03
|
||||
#define ADIS_ENDURANCE 0x01
|
||||
|
||||
/*
|
||||
* data structure for every sensor
|
||||
*
|
||||
* @dev: Driver model representation of the device.
|
||||
* @spi: Pointer to the spi device which will manage i/o to spi bus.
|
||||
* @data: Last read data from device.
|
||||
* @irq_adis: GPIO Number of IRQ signal
|
||||
* @irq: irq line manage by kernel
|
||||
* @negative: indicates if sensor is upside down (negative == 1)
|
||||
* @direction: indicates axis (x, y, z) the sensor is meassuring
|
||||
*/
|
||||
struct spi_adis16255_data {
|
||||
struct device dev;
|
||||
struct spi_device *spi;
|
||||
s16 data;
|
||||
int irq;
|
||||
u8 negative;
|
||||
char direction;
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int spi_adis16255_read_data(struct spi_adis16255_data *spiadis,
|
||||
u8 adr,
|
||||
u8 *rbuf)
|
||||
{
|
||||
struct spi_device *spi = spiadis->spi;
|
||||
struct spi_message msg;
|
||||
struct spi_transfer xfer1, xfer2;
|
||||
u8 *buf, *rx;
|
||||
int ret;
|
||||
|
||||
buf = kzalloc(4, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rx = kzalloc(4, GFP_KERNEL);
|
||||
if (rx == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_buf;
|
||||
}
|
||||
|
||||
buf[0] = adr;
|
||||
|
||||
spi_message_init(&msg);
|
||||
memset(&xfer1, 0, sizeof(xfer1));
|
||||
memset(&xfer2, 0, sizeof(xfer2));
|
||||
|
||||
xfer1.tx_buf = buf;
|
||||
xfer1.rx_buf = buf + 2;
|
||||
xfer1.len = 2;
|
||||
xfer1.delay_usecs = 9;
|
||||
|
||||
xfer2.tx_buf = rx + 2;
|
||||
xfer2.rx_buf = rx;
|
||||
xfer2.len = 2;
|
||||
|
||||
spi_message_add_tail(&xfer1, &msg);
|
||||
spi_message_add_tail(&xfer2, &msg);
|
||||
|
||||
ret = spi_sync(spi, &msg);
|
||||
if (ret == 0) {
|
||||
rbuf[0] = rx[0];
|
||||
rbuf[1] = rx[1];
|
||||
}
|
||||
|
||||
kfree(rx);
|
||||
err_buf:
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis,
|
||||
u8 adr1,
|
||||
u8 adr2,
|
||||
u8 *wbuf)
|
||||
{
|
||||
struct spi_device *spi = spiadis->spi;
|
||||
struct spi_message msg;
|
||||
struct spi_transfer xfer1, xfer2;
|
||||
u8 *buf, *rx;
|
||||
int ret;
|
||||
|
||||
buf = kmalloc(4, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rx = kzalloc(4, GFP_KERNEL);
|
||||
if (rx == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err_buf;
|
||||
}
|
||||
|
||||
spi_message_init(&msg);
|
||||
memset(&xfer1, 0, sizeof(xfer1));
|
||||
memset(&xfer2, 0, sizeof(xfer2));
|
||||
|
||||
buf[0] = adr1 | 0x80;
|
||||
buf[1] = *wbuf;
|
||||
|
||||
buf[2] = adr2 | 0x80;
|
||||
buf[3] = *(wbuf + 1);
|
||||
|
||||
xfer1.tx_buf = buf;
|
||||
xfer1.rx_buf = rx;
|
||||
xfer1.len = 2;
|
||||
xfer1.delay_usecs = 9;
|
||||
|
||||
xfer2.tx_buf = buf+2;
|
||||
xfer2.rx_buf = rx+2;
|
||||
xfer2.len = 2;
|
||||
|
||||
spi_message_add_tail(&xfer1, &msg);
|
||||
spi_message_add_tail(&xfer2, &msg);
|
||||
|
||||
ret = spi_sync(spi, &msg);
|
||||
if (ret != 0)
|
||||
dev_warn(&spi->dev, "write data to %#x %#x failed\n",
|
||||
buf[0], buf[2]);
|
||||
|
||||
kfree(rx);
|
||||
err_buf:
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static irqreturn_t adis_irq_thread(int irq, void *dev_id)
|
||||
{
|
||||
struct spi_adis16255_data *spiadis = dev_id;
|
||||
int status;
|
||||
u16 value = 0;
|
||||
|
||||
status = spi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value);
|
||||
if (status != 0) {
|
||||
dev_warn(&spiadis->spi->dev, "SPI FAILED\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* perform on new data only... */
|
||||
if (value & 0x8000) {
|
||||
/* delete error and new data bit */
|
||||
value = value & 0x3fff;
|
||||
/* set negative value */
|
||||
if (value & 0x2000)
|
||||
value = value | 0xe000;
|
||||
|
||||
if (likely(spiadis->negative))
|
||||
value = -value;
|
||||
|
||||
spiadis->data = (s16) value;
|
||||
}
|
||||
|
||||
exit:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
ssize_t adis16255_show_data(struct device *device,
|
||||
struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(device);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", spiadis->data);
|
||||
}
|
||||
DEVICE_ATTR(data, S_IRUGO , adis16255_show_data, NULL);
|
||||
|
||||
ssize_t adis16255_show_direction(struct device *device,
|
||||
struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(device);
|
||||
return snprintf(buf, PAGE_SIZE, "%c\n", spiadis->direction);
|
||||
}
|
||||
DEVICE_ATTR(direction, S_IRUGO , adis16255_show_direction, NULL);
|
||||
|
||||
ssize_t adis16255_show_sample_rate(struct device *device,
|
||||
struct device_attribute *da,
|
||||
char *buf)
|
||||
{
|
||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(device);
|
||||
int status = 0;
|
||||
u16 value = 0;
|
||||
int ts = 0;
|
||||
|
||||
status = spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB,
|
||||
(u8 *)&value);
|
||||
if (status != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (value & 0x80) {
|
||||
/* timebase = 60.54 ms */
|
||||
ts = 60540 * ((0x7f & value) + 1);
|
||||
} else {
|
||||
/* timebase = 1.953 ms */
|
||||
ts = 1953 * ((0x7f & value) + 1);
|
||||
}
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", (1000*1000)/ts);
|
||||
}
|
||||
DEVICE_ATTR(sample_rate, S_IRUGO , adis16255_show_sample_rate, NULL);
|
||||
|
||||
static struct attribute *adis16255_attributes[] = {
|
||||
&dev_attr_data.attr,
|
||||
&dev_attr_direction.attr,
|
||||
&dev_attr_sample_rate.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group adis16255_attr_group = {
|
||||
.attrs = adis16255_attributes,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int spi_adis16255_shutdown(struct spi_adis16255_data *spiadis)
|
||||
{
|
||||
u16 value = 0;
|
||||
/* turn sensor off */
|
||||
spi_adis16255_write_data(spiadis,
|
||||
ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB,
|
||||
(u8 *)&value);
|
||||
spi_adis16255_write_data(spiadis,
|
||||
ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB,
|
||||
(u8 *)&value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
|
||||
{
|
||||
int status = 0;
|
||||
u16 value = 0;
|
||||
|
||||
status = spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE,
|
||||
(u8 *)&value);
|
||||
if (status != 0)
|
||||
goto err;
|
||||
if (value != 0x0800) {
|
||||
dev_warn(&spiadis->spi->dev, "Scale factor is none default "
|
||||
"value (%.4x)\n", value);
|
||||
}
|
||||
|
||||
/* timebase = 1.953 ms, Ns = 0 -> 512 Hz sample rate */
|
||||
value = 0x0001;
|
||||
status = spi_adis16255_write_data(spiadis,
|
||||
ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB,
|
||||
(u8 *)&value);
|
||||
if (status != 0)
|
||||
goto err;
|
||||
|
||||
/* start internal self-test */
|
||||
value = 0x0400;
|
||||
status = spi_adis16255_write_data(spiadis,
|
||||
ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB,
|
||||
(u8 *)&value);
|
||||
if (status != 0)
|
||||
goto err;
|
||||
|
||||
/* wait 35 ms to finish self-test */
|
||||
msleep(35);
|
||||
|
||||
value = 0x0000;
|
||||
status = spi_adis16255_read_data(spiadis, ADIS_STATUS,
|
||||
(u8 *)&value);
|
||||
if (status != 0)
|
||||
goto err;
|
||||
|
||||
if (value & 0x23) {
|
||||
if (value & 0x20) {
|
||||
dev_warn(&spiadis->spi->dev, "self-test error\n");
|
||||
status = -ENODEV;
|
||||
goto err;
|
||||
} else if (value & 0x3) {
|
||||
dev_warn(&spiadis->spi->dev, "Sensor voltage "
|
||||
"out of range.\n");
|
||||
status = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* set interrupt to active high on DIO0 when data ready */
|
||||
value = 0x0006;
|
||||
status = spi_adis16255_write_data(spiadis,
|
||||
ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB,
|
||||
(u8 *)&value);
|
||||
if (status != 0)
|
||||
goto err;
|
||||
return status;
|
||||
|
||||
err:
|
||||
spi_adis16255_shutdown(spiadis);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __devinit spi_adis16255_probe(struct spi_device *spi)
|
||||
{
|
||||
|
||||
struct adis16255_init_data *init_data = spi->dev.platform_data;
|
||||
struct spi_adis16255_data *spiadis;
|
||||
int status = 0;
|
||||
|
||||
spiadis = kzalloc(sizeof(*spiadis), GFP_KERNEL);
|
||||
if (!spiadis)
|
||||
return -ENOMEM;
|
||||
|
||||
spiadis->spi = spi;
|
||||
spiadis->direction = init_data->direction;
|
||||
|
||||
if (init_data->negative)
|
||||
spiadis->negative = 1;
|
||||
|
||||
status = gpio_request(init_data->irq, "adis16255");
|
||||
if (status != 0)
|
||||
goto err;
|
||||
|
||||
status = gpio_direction_input(init_data->irq);
|
||||
if (status != 0)
|
||||
goto gpio_err;
|
||||
|
||||
spiadis->irq = gpio_to_irq(init_data->irq);
|
||||
|
||||
status = request_threaded_irq(spiadis->irq,
|
||||
NULL, adis_irq_thread,
|
||||
IRQF_DISABLED, "adis-driver", spiadis);
|
||||
|
||||
if (status != 0) {
|
||||
dev_err(&spi->dev, "IRQ request failed\n");
|
||||
goto gpio_err;
|
||||
}
|
||||
|
||||
dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", init_data->irq, spiadis->irq);
|
||||
|
||||
dev_set_drvdata(&spi->dev, spiadis);
|
||||
status = sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group);
|
||||
if (status != 0)
|
||||
goto irq_err;
|
||||
|
||||
status = spi_adis16255_bringup(spiadis);
|
||||
if (status != 0)
|
||||
goto sysfs_err;
|
||||
|
||||
dev_info(&spi->dev, "spi_adis16255 driver added!\n");
|
||||
|
||||
return status;
|
||||
|
||||
sysfs_err:
|
||||
sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group);
|
||||
irq_err:
|
||||
free_irq(spiadis->irq, spiadis);
|
||||
gpio_err:
|
||||
gpio_free(init_data->irq);
|
||||
err:
|
||||
kfree(spiadis);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int __devexit spi_adis16255_remove(struct spi_device *spi)
|
||||
{
|
||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev);
|
||||
|
||||
spi_adis16255_shutdown(spiadis);
|
||||
|
||||
free_irq(spiadis->irq, spiadis);
|
||||
gpio_free(irq_to_gpio(spiadis->irq));
|
||||
|
||||
sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group);
|
||||
|
||||
kfree(spiadis);
|
||||
|
||||
dev_info(&spi->dev, "spi_adis16255 driver removed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver spi_adis16255_drv = {
|
||||
.driver = {
|
||||
.name = "spi_adis16255",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = spi_adis16255_probe,
|
||||
.remove = __devexit_p(spi_adis16255_remove),
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init spi_adis16255_init(void)
|
||||
{
|
||||
return spi_register_driver(&spi_adis16255_drv);
|
||||
}
|
||||
module_init(spi_adis16255_init);
|
||||
|
||||
static void __exit spi_adis16255_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&spi_adis16255_drv);
|
||||
}
|
||||
module_exit(spi_adis16255_exit);
|
||||
|
||||
MODULE_AUTHOR("Matthias Brugger");
|
||||
MODULE_DESCRIPTION("SPI device driver for ADIS16255 sensor");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef ADIS16255_H
|
||||
#define ADIS16255_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct adis16255_init_data {
|
||||
char direction;
|
||||
u8 negative;
|
||||
int irq;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -70,7 +70,7 @@ module_param(start_off, uint, 0644);
|
||||
MODULE_PARM_DESC(start_off,
|
||||
"Set to 1 to switch off OLED display after it is attached");
|
||||
|
||||
enum oled_pack_mode{
|
||||
enum oled_pack_mode {
|
||||
PACK_MODE_G1,
|
||||
PACK_MODE_G50,
|
||||
PACK_MODE_LAST
|
||||
|
||||
@@ -876,7 +876,7 @@ HIFAckInterrupt(HIF_DEVICE *device)
|
||||
void
|
||||
HIFUnMaskInterrupt(HIF_DEVICE *device)
|
||||
{
|
||||
int ret;;
|
||||
int ret;
|
||||
|
||||
AR_DEBUG_ASSERT(device != NULL);
|
||||
AR_DEBUG_ASSERT(device->func != NULL);
|
||||
@@ -1188,7 +1188,7 @@ addHifDevice(struct sdio_func *func)
|
||||
HIF_DEVICE *hifdevice;
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
|
||||
AR_DEBUG_ASSERT(func != NULL);
|
||||
hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
|
||||
hifdevice = kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
|
||||
AR_DEBUG_ASSERT(hifdevice != NULL);
|
||||
#if HIF_USE_DMA_BOUNCE_BUFFER
|
||||
hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
|
||||
|
||||
@@ -4439,7 +4439,7 @@ skip_key:
|
||||
for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
|
||||
sprintf(pos, "%2.2x", assocInfo[i]);
|
||||
pos += 2;;
|
||||
pos += 2;
|
||||
}
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ void autofs_update_usage(struct autofs_dirhash *dh,
|
||||
struct autofs_dir_ent *ent)
|
||||
{
|
||||
autofs_delete_usage(ent); /* Unlink from current position */
|
||||
autofs_init_usage(dh,ent); /* Relink at queue tail */
|
||||
autofs_init_usage(dh, ent); /* Relink at queue tail */
|
||||
}
|
||||
|
||||
struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||
@@ -45,17 +45,18 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||
struct path path;
|
||||
int umount_ok;
|
||||
|
||||
if ( list_empty(&dh->expiry_head) || sbi->catatonic )
|
||||
if (list_empty(&dh->expiry_head) || sbi->catatonic)
|
||||
return NULL; /* No entries */
|
||||
/* We keep the list sorted by last_usage and want old stuff */
|
||||
ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp);
|
||||
ent = list_entry(dh->expiry_head.next,
|
||||
struct autofs_dir_ent, exp);
|
||||
if (jiffies - ent->last_usage < timeout)
|
||||
break;
|
||||
/* Move to end of list in case expiry isn't desirable */
|
||||
autofs_update_usage(dh, ent);
|
||||
|
||||
/* Check to see that entry is expirable */
|
||||
if ( ent->ino < AUTOFS_FIRST_DIR_INO )
|
||||
if (ent->ino < AUTOFS_FIRST_DIR_INO)
|
||||
return ent; /* Symlinks are always expirable */
|
||||
|
||||
/* Get the dentry for the autofs subdirectory */
|
||||
@@ -63,14 +64,15 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||
|
||||
if (!path.dentry) {
|
||||
/* Should only happen in catatonic mode */
|
||||
printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
|
||||
printk(KERN_DEBUG "autofs: dentry == NULL but inode \
|
||||
range is directory, entry %s\n", ent->name);
|
||||
autofs_delete_usage(ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!path.dentry->d_inode) {
|
||||
dput(path.dentry);
|
||||
printk("autofs: negative dentry on expiry queue: %s\n",
|
||||
printk(KERN_DEBUG "autofs: negative dentry on expiry queue: %s\n",
|
||||
ent->name);
|
||||
autofs_delete_usage(ent);
|
||||
continue;
|
||||
@@ -80,14 +82,16 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||
point to the mounted-on-top root. */
|
||||
if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
|
||||
!d_mountpoint(path.dentry)) {
|
||||
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
||||
DPRINTK(("autofs: not expirable \
|
||||
(not a mounted directory): %s\n", ent->name));
|
||||
continue;
|
||||
}
|
||||
path.mnt = mnt;
|
||||
path_get(&path);
|
||||
if (!follow_down(&path)) {
|
||||
path_put(&path);
|
||||
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
||||
DPRINTK(("autofs: not expirable\
|
||||
(not a mounted directory): %s\n", ent->name));
|
||||
continue;
|
||||
}
|
||||
while (d_mountpoint(path.dentry) && follow_down(&path))
|
||||
@@ -96,30 +100,37 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||
path_put(&path);
|
||||
|
||||
if (umount_ok) {
|
||||
DPRINTK(("autofs: signaling expire on %s\n", ent->name));
|
||||
DPRINTK(("autofs: signaling expire on %s\n",
|
||||
ent->name));
|
||||
return ent; /* Expirable! */
|
||||
}
|
||||
DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
|
||||
|
||||
DPRINTK(("autofs: didn't expire due to may_umount: %s\n",
|
||||
ent->name));
|
||||
}
|
||||
return NULL; /* No expirable entries */
|
||||
}
|
||||
|
||||
void autofs_initialize_hash(struct autofs_dirhash *dh) {
|
||||
void autofs_initialize_hash(struct autofs_dirhash *dh)
|
||||
{
|
||||
memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
|
||||
INIT_LIST_HEAD(&dh->expiry_head);
|
||||
}
|
||||
|
||||
struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name)
|
||||
struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh,
|
||||
struct qstr *name)
|
||||
{
|
||||
struct autofs_dir_ent *dhn;
|
||||
|
||||
DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash));
|
||||
autofs_say(name->name,name->len);
|
||||
autofs_say(name->name, name->len);
|
||||
|
||||
for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) {
|
||||
if ( name->hash == dhn->hash &&
|
||||
for (dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE];
|
||||
dhn;
|
||||
dhn = dhn->next) {
|
||||
if (name->hash == dhn->hash &&
|
||||
name->len == dhn->len &&
|
||||
!memcmp(name->name, dhn->name, name->len) )
|
||||
!memcmp(name->name, dhn->name, name->len))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -131,9 +142,9 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
|
||||
struct autofs_dir_ent **dhnp;
|
||||
|
||||
DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
|
||||
autofs_say(ent->name,ent->len);
|
||||
autofs_say(ent->name, ent->len);
|
||||
|
||||
autofs_init_usage(dh,ent);
|
||||
autofs_init_usage(dh, ent);
|
||||
if (ent->dentry)
|
||||
dget(ent->dentry);
|
||||
|
||||
@@ -141,19 +152,19 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
|
||||
ent->next = *dhnp;
|
||||
ent->back = dhnp;
|
||||
*dhnp = ent;
|
||||
if ( ent->next )
|
||||
if (ent->next)
|
||||
ent->next->back = &(ent->next);
|
||||
}
|
||||
|
||||
void autofs_hash_delete(struct autofs_dir_ent *ent)
|
||||
{
|
||||
*(ent->back) = ent->next;
|
||||
if ( ent->next )
|
||||
if (ent->next)
|
||||
ent->next->back = ent->back;
|
||||
|
||||
autofs_delete_usage(ent);
|
||||
|
||||
if ( ent->dentry )
|
||||
if (ent->dentry)
|
||||
dput(ent->dentry);
|
||||
kfree(ent->name);
|
||||
kfree(ent);
|
||||
@@ -176,20 +187,19 @@ struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
|
||||
bucket = (*ptr >> 16) - 1;
|
||||
ecount = *ptr & 0xffff;
|
||||
|
||||
if ( bucket < 0 ) {
|
||||
if (bucket < 0)
|
||||
bucket = ecount = 0;
|
||||
}
|
||||
|
||||
DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
|
||||
|
||||
ent = last ? last->next : NULL;
|
||||
|
||||
if ( ent ) {
|
||||
if (ent) {
|
||||
ecount++;
|
||||
} else {
|
||||
while ( bucket < AUTOFS_HASH_SIZE ) {
|
||||
while (bucket < AUTOFS_HASH_SIZE) {
|
||||
ent = dh->h[bucket];
|
||||
for ( i = ecount ; ent && i ; i-- )
|
||||
for (i = ecount ; ent && i ; i--)
|
||||
ent = ent->next;
|
||||
|
||||
if (ent) {
|
||||
@@ -202,11 +212,12 @@ struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( !ent )
|
||||
printk("autofs_hash_enum: nothing found\n");
|
||||
if (!ent)
|
||||
printk(KERN_DEBUG "autofs_hash_enum: nothing found\n");
|
||||
else {
|
||||
printk("autofs_hash_enum: found hash %08x, name", ent->hash);
|
||||
autofs_say(ent->name,ent->len);
|
||||
printk(KERN_DEBUG "autofs_hash_enum: found hash %08x, name",
|
||||
ent->hash);
|
||||
autofs_say(ent->name, ent->len);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -221,9 +232,9 @@ void autofs_hash_dputall(struct autofs_dirhash *dh)
|
||||
int i;
|
||||
struct autofs_dir_ent *ent;
|
||||
|
||||
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
|
||||
for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
|
||||
if ( ent->dentry ) {
|
||||
for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) {
|
||||
for (ent = dh->h[i] ; ent ; ent = ent->next) {
|
||||
if (ent->dentry) {
|
||||
dput(ent->dentry);
|
||||
ent->dentry = NULL;
|
||||
}
|
||||
@@ -238,10 +249,10 @@ void autofs_hash_nuke(struct autofs_sb_info *sbi)
|
||||
int i;
|
||||
struct autofs_dir_ent *ent, *nent;
|
||||
|
||||
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
|
||||
for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
|
||||
for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) {
|
||||
for (ent = sbi->dirhash.h[i] ; ent ; ent = nent) {
|
||||
nent = ent->next;
|
||||
if ( ent->dentry )
|
||||
if (ent->dentry)
|
||||
dput(ent->dentry);
|
||||
kfree(ent->name);
|
||||
kfree(ent);
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#
|
||||
# B.A.T.M.A.N meshing protocol
|
||||
#
|
||||
|
||||
config BATMAN_ADV
|
||||
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
|
||||
depends on NET
|
||||
default n
|
||||
---help---
|
||||
|
||||
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
|
||||
a routing protocol for multi-hop ad-hoc mesh networks. The
|
||||
networks may be wired or wireless. See
|
||||
http://www.open-mesh.org/ for more information and user space
|
||||
tools.
|
||||
|
||||
config BATMAN_ADV_DEBUG
|
||||
bool "B.A.T.M.A.N. debugging"
|
||||
depends on BATMAN_ADV != n
|
||||
---help---
|
||||
|
||||
This is an option for use by developers; most people should
|
||||
say N here. This enables compilation of support for
|
||||
outputting debugging information to the kernel log. The
|
||||
output is controlled via the module parameter debug.
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
||||
#
|
||||
# Marek Lindner, Simon Wunderlich
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
|
||||
batman-adv-y := 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 unicast.o
|
||||
@@ -1,240 +0,0 @@
|
||||
[state: 04-09-2010]
|
||||
|
||||
BATMAN-ADV
|
||||
----------
|
||||
|
||||
Batman advanced is a new approach to wireless networking which
|
||||
does no longer operate on the IP basis. Unlike the batman daemon,
|
||||
which exchanges information using UDP packets and sets routing
|
||||
tables, batman-advanced operates on ISO/OSI Layer 2 only and uses
|
||||
and routes (or better: bridges) Ethernet Frames. It emulates a
|
||||
virtual network switch of all nodes participating. Therefore all
|
||||
nodes appear to be link local, thus all higher operating proto-
|
||||
cols won't be affected by any changes within the network. You can
|
||||
run almost any protocol above batman advanced, prominent examples
|
||||
are: IPv4, IPv6, DHCP, IPX.
|
||||
|
||||
Batman advanced was implemented as a Linux kernel driver to re-
|
||||
duce the overhead to a minimum. It does not depend on any (other)
|
||||
network driver, and can be used on wifi as well as ethernet lan,
|
||||
vpn, etc ... (anything with ethernet-style layer 2).
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
Load the batman-adv module into your kernel:
|
||||
|
||||
# insmod batman-adv.ko
|
||||
|
||||
The module is now waiting for activation. You must add some in-
|
||||
terfaces on which batman can operate. After loading the module
|
||||
batman advanced will scan your systems interfaces to search for
|
||||
compatible interfaces. Once found, it will create subfolders in
|
||||
the /sys directories of each supported interface, e.g.
|
||||
|
||||
# ls /sys/class/net/eth0/batman_adv/
|
||||
# iface_status mesh_iface
|
||||
|
||||
If an interface does not have the "batman_adv" subfolder it prob-
|
||||
ably is not supported. Not supported interfaces are: loopback,
|
||||
non-ethernet and batman's own interfaces.
|
||||
|
||||
Note: After the module was loaded it will continuously watch for
|
||||
new interfaces to verify the compatibility. There is no need to
|
||||
reload the module if you plug your USB wifi adapter into your ma-
|
||||
chine after batman advanced was initially loaded.
|
||||
|
||||
To activate a given interface simply write "bat0" into its
|
||||
"mesh_iface" file inside the batman_adv subfolder:
|
||||
|
||||
# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface
|
||||
|
||||
Repeat this step for all interfaces you wish to add. Now batman
|
||||
starts using/broadcasting on this/these interface(s).
|
||||
|
||||
By reading the "iface_status" file you can check its status:
|
||||
|
||||
# cat /sys/class/net/eth0/batman_adv/iface_status
|
||||
# active
|
||||
|
||||
To deactivate an interface you have to write "none" into its
|
||||
"mesh_iface" file:
|
||||
|
||||
# echo none > /sys/class/net/eth0/batman_adv/mesh_iface
|
||||
|
||||
|
||||
All mesh wide settings can be found in batman's own interface
|
||||
folder:
|
||||
|
||||
# ls /sys/class/net/bat0/mesh/
|
||||
# aggregated_ogms bonding orig_interval vis_mode
|
||||
|
||||
|
||||
There is a special folder for debugging informations:
|
||||
|
||||
# ls /sys/kernel/debug/batman_adv/bat0/
|
||||
# originators socket transtable_global transtable_local
|
||||
# vis_data
|
||||
|
||||
|
||||
Some of the files contain all sort of status information regard-
|
||||
ing the mesh network. For example, you can view the table of
|
||||
originators (mesh participants) with:
|
||||
|
||||
# cat /sys/kernel/debug/batman_adv/bat0/originators
|
||||
|
||||
Other files allow to change batman's behaviour to better fit your
|
||||
requirements. For instance, you can check the current originator
|
||||
interval (value in milliseconds which determines how often batman
|
||||
sends its broadcast packets):
|
||||
|
||||
# cat /sys/class/net/bat0/mesh/orig_interval
|
||||
# 1000
|
||||
|
||||
and also change its value:
|
||||
|
||||
# echo 3000 > /sys/class/net/bat0/mesh/orig_interval
|
||||
|
||||
In very mobile scenarios, you might want to adjust the originator
|
||||
interval to a lower value. This will make the mesh more respon-
|
||||
sive to topology changes, but will also increase the overhead.
|
||||
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
To make use of your newly created mesh, batman advanced provides
|
||||
a new interface "bat0" which you should use from this point on.
|
||||
All interfaces added to batman advanced are not relevant any
|
||||
longer because batman handles them for you. Basically, one "hands
|
||||
over" the data by using the batman interface and batman will make
|
||||
sure it reaches its destination.
|
||||
|
||||
The "bat0" interface can be used like any other regular inter-
|
||||
face. It needs an IP address which can be either statically con-
|
||||
figured or dynamically (by using DHCP or similar services):
|
||||
|
||||
# NodeA: ifconfig bat0 192.168.0.1
|
||||
# NodeB: ifconfig bat0 192.168.0.2
|
||||
# NodeB: ping 192.168.0.1
|
||||
|
||||
Note: In order to avoid problems remove all IP addresses previ-
|
||||
ously assigned to interfaces now used by batman advanced, e.g.
|
||||
|
||||
# ifconfig eth0 0.0.0.0
|
||||
|
||||
|
||||
VISUALIZATION
|
||||
-------------
|
||||
|
||||
If you want topology visualization, at least one mesh node must
|
||||
be configured as VIS-server:
|
||||
|
||||
# echo "server" > /sys/class/net/bat0/mesh/vis_mode
|
||||
|
||||
Each node is either configured as "server" or as "client" (de-
|
||||
fault: "client"). Clients send their topology data to the server
|
||||
next to them, and server synchronize with other servers. If there
|
||||
is no server configured (default) within the mesh, no topology
|
||||
information will be transmitted. With these "synchronizing
|
||||
servers", there can be 1 or more vis servers sharing the same (or
|
||||
at least very similar) data.
|
||||
|
||||
When configured as server, you can get a topology snapshot of
|
||||
your mesh:
|
||||
|
||||
# cat /sys/kernel/debug/batman_adv/bat0/vis_data
|
||||
|
||||
This raw output is intended to be easily parsable and convertable
|
||||
with other tools. Have a look at the batctl README if you want a
|
||||
vis output in dot or json format for instance and how those out-
|
||||
puts could then be visualised in an image.
|
||||
|
||||
The raw format consists of comma separated values per entry where
|
||||
each entry is giving information about a certain source inter-
|
||||
face. Each entry can/has to have the following values:
|
||||
-> "mac" - mac address of an originator's source interface
|
||||
(each line begins with it)
|
||||
-> "TQ mac value" - src mac's link quality towards mac address
|
||||
of a neighbor originator's interface which
|
||||
is being used for routing
|
||||
-> "HNA mac" - HNA announced by source mac
|
||||
-> "PRIMARY" - this is a primary interface
|
||||
-> "SEC mac" - secondary mac address of source
|
||||
(requires preceding PRIMARY)
|
||||
|
||||
The TQ value has a range from 4 to 255 with 255 being the best.
|
||||
The HNA entries are showing which hosts are connected to the mesh
|
||||
via bat0 or being bridged into the mesh network. The PRIMARY/SEC
|
||||
values are only applied on primary interfaces
|
||||
|
||||
|
||||
LOGGING/DEBUGGING
|
||||
-----------------
|
||||
|
||||
All error messages, warnings and information messages are sent to
|
||||
the kernel log. Depending on your operating system distribution
|
||||
this can be read in one of a number of ways. Try using the com-
|
||||
mands: dmesg, logread, or looking in the files /var/log/kern.log
|
||||
or /var/log/syslog. All batman-adv messages are prefixed with
|
||||
"batman-adv:" So to see just these messages try
|
||||
|
||||
# dmesg | grep batman-adv
|
||||
|
||||
When investigating problems with your mesh network it is some-
|
||||
times necessary to see more detail debug messages. This must be
|
||||
enabled when compiling the batman-adv module. When building bat-
|
||||
man-adv as part of kernel, use "make menuconfig" and enable the
|
||||
option "B.A.T.M.A.N. debugging".
|
||||
|
||||
Those additional debug messages can be accessed using a special
|
||||
file in debugfs
|
||||
|
||||
# cat /sys/kernel/debug/batman_adv/bat0/log
|
||||
|
||||
The additional debug output is by default disabled. It can be en-
|
||||
abled during run time. Following log_levels are defined:
|
||||
|
||||
0 - All debug output disabled
|
||||
1 - Enable messages related to routing / flooding / broadcasting
|
||||
2 - Enable route or hna added / changed / deleted
|
||||
3 - Enable all messages
|
||||
|
||||
The debug output can be changed at runtime using the file
|
||||
/sys/class/net/bat0/mesh/log_level. e.g.
|
||||
|
||||
# echo 2 > /sys/class/net/bat0/mesh/log_level
|
||||
|
||||
will enable debug messages for when routes or HNAs change.
|
||||
|
||||
|
||||
BATCTL
|
||||
------
|
||||
|
||||
As batman advanced operates on layer 2 all hosts participating in
|
||||
the virtual switch are completely transparent for all protocols
|
||||
above layer 2. Therefore the common diagnosis tools do not work
|
||||
as expected. To overcome these problems batctl was created. At
|
||||
the moment the batctl contains ping, traceroute, tcpdump and
|
||||
interfaces to the kernel module settings.
|
||||
|
||||
For more information, please see the manpage (man batctl).
|
||||
|
||||
batctl is available on http://www.open-mesh.org/
|
||||
|
||||
|
||||
CONTACT
|
||||
-------
|
||||
|
||||
Please send us comments, experiences, questions, anything :)
|
||||
|
||||
IRC: #batman on irc.freenode.org
|
||||
Mailing-list: b.a.t.m.a.n@b.a.t.m.a.n@lists.open-mesh.org
|
||||
(optional subscription at
|
||||
https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n)
|
||||
|
||||
You can also contact the Authors:
|
||||
|
||||
Marek Lindner <lindner_marek@yahoo.de>
|
||||
Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
* remove own list functionality from hash
|
||||
* use hlist_head, hlist_node in hash
|
||||
* don't use callbacks for compare+choose in hash
|
||||
* think about more efficient ways instead of abstraction of hash
|
||||
* 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>
|
||||
Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
||||
Andrew Lunn <andrew@lunn.ch>
|
||||
b.a.t.m.a.n@lists.open-mesh.org
|
||||
Greg Kroah-Hartman <gregkh@suse.de>
|
||||
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
||||
*
|
||||
* Marek Lindner, Simon Wunderlich
|
||||
*
|
||||
* 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 "aggregation.h"
|
||||
#include "send.h"
|
||||
#include "routing.h"
|
||||
|
||||
/* calculate the size of the hna information for a given packet */
|
||||
static int hna_len(struct batman_packet *batman_packet)
|
||||
{
|
||||
return batman_packet->num_hna * ETH_ALEN;
|
||||
}
|
||||
|
||||
/* return true if new_packet can be aggregated with forw_packet */
|
||||
static bool can_aggregate_with(struct batman_packet *new_batman_packet,
|
||||
int packet_len,
|
||||
unsigned long send_time,
|
||||
bool directlink,
|
||||
struct batman_if *if_incoming,
|
||||
struct forw_packet *forw_packet)
|
||||
{
|
||||
struct batman_packet *batman_packet =
|
||||
(struct batman_packet *)forw_packet->skb->data;
|
||||
int aggregated_bytes = forw_packet->packet_len + packet_len;
|
||||
|
||||
/**
|
||||
* we can aggregate the current packet to this aggregated packet
|
||||
* if:
|
||||
*
|
||||
* - the send time is within our MAX_AGGREGATION_MS time
|
||||
* - the resulting packet wont be bigger than
|
||||
* MAX_AGGREGATION_BYTES
|
||||
*/
|
||||
|
||||
if (time_before(send_time, forw_packet->send_time) &&
|
||||
time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
|
||||
forw_packet->send_time) &&
|
||||
(aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
|
||||
|
||||
/**
|
||||
* check aggregation compatibility
|
||||
* -> direct link packets are broadcasted on
|
||||
* their interface only
|
||||
* -> aggregate packet if the current packet is
|
||||
* a "global" packet as well as the base
|
||||
* packet
|
||||
*/
|
||||
|
||||
/* packets without direct link flag and high TTL
|
||||
* are flooded through the net */
|
||||
if ((!directlink) &&
|
||||
(!(batman_packet->flags & DIRECTLINK)) &&
|
||||
(batman_packet->ttl != 1) &&
|
||||
|
||||
/* own packets originating non-primary
|
||||
* interfaces leave only that interface */
|
||||
((!forw_packet->own) ||
|
||||
(forw_packet->if_incoming->if_num == 0)))
|
||||
return true;
|
||||
|
||||
/* if the incoming packet is sent via this one
|
||||
* interface only - we still can aggregate */
|
||||
if ((directlink) &&
|
||||
(new_batman_packet->ttl == 1) &&
|
||||
(forw_packet->if_incoming == if_incoming) &&
|
||||
|
||||
/* packets from direct neighbors or
|
||||
* own secondary interface packets
|
||||
* (= secondary interface packets in general) */
|
||||
(batman_packet->flags & DIRECTLINK ||
|
||||
(forw_packet->own &&
|
||||
forw_packet->if_incoming->if_num != 0)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
|
||||
/* create a new aggregated packet and add this packet to it */
|
||||
static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
|
||||
unsigned long send_time, bool direct_link,
|
||||
struct batman_if *if_incoming,
|
||||
int own_packet)
|
||||
{
|
||||
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
||||
struct forw_packet *forw_packet_aggr;
|
||||
unsigned long flags;
|
||||
unsigned char *skb_buff;
|
||||
|
||||
/* own packet should always be scheduled */
|
||||
if (!own_packet) {
|
||||
if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
|
||||
bat_dbg(DBG_BATMAN, bat_priv,
|
||||
"batman packet queue full\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
|
||||
if (!forw_packet_aggr) {
|
||||
if (!own_packet)
|
||||
atomic_inc(&bat_priv->batman_queue_left);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((atomic_read(&bat_priv->aggregation_enabled)) &&
|
||||
(packet_len < MAX_AGGREGATION_BYTES))
|
||||
forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
|
||||
sizeof(struct ethhdr));
|
||||
else
|
||||
forw_packet_aggr->skb = dev_alloc_skb(packet_len +
|
||||
sizeof(struct ethhdr));
|
||||
|
||||
if (!forw_packet_aggr->skb) {
|
||||
if (!own_packet)
|
||||
atomic_inc(&bat_priv->batman_queue_left);
|
||||
kfree(forw_packet_aggr);
|
||||
return;
|
||||
}
|
||||
skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
|
||||
|
||||
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
||||
|
||||
skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
|
||||
forw_packet_aggr->packet_len = packet_len;
|
||||
memcpy(skb_buff, packet_buff, packet_len);
|
||||
|
||||
forw_packet_aggr->own = own_packet;
|
||||
forw_packet_aggr->if_incoming = if_incoming;
|
||||
forw_packet_aggr->num_packets = 0;
|
||||
forw_packet_aggr->direct_link_flags = 0;
|
||||
forw_packet_aggr->send_time = send_time;
|
||||
|
||||
/* save packet direct link flag status */
|
||||
if (direct_link)
|
||||
forw_packet_aggr->direct_link_flags |= 1;
|
||||
|
||||
/* add new packet to packet list */
|
||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
||||
hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
|
||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
||||
|
||||
/* start timer for this packet */
|
||||
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
|
||||
send_outstanding_bat_packet);
|
||||
queue_delayed_work(bat_event_workqueue,
|
||||
&forw_packet_aggr->delayed_work,
|
||||
send_time - jiffies);
|
||||
}
|
||||
|
||||
/* aggregate a new packet into the existing aggregation */
|
||||
static void aggregate(struct forw_packet *forw_packet_aggr,
|
||||
unsigned char *packet_buff,
|
||||
int packet_len,
|
||||
bool direct_link)
|
||||
{
|
||||
unsigned char *skb_buff;
|
||||
|
||||
skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
|
||||
memcpy(skb_buff, packet_buff, packet_len);
|
||||
forw_packet_aggr->packet_len += packet_len;
|
||||
forw_packet_aggr->num_packets++;
|
||||
|
||||
/* save packet direct link flag status */
|
||||
if (direct_link)
|
||||
forw_packet_aggr->direct_link_flags |=
|
||||
(1 << forw_packet_aggr->num_packets);
|
||||
}
|
||||
|
||||
void add_bat_packet_to_list(struct bat_priv *bat_priv,
|
||||
unsigned char *packet_buff, int packet_len,
|
||||
struct batman_if *if_incoming, char own_packet,
|
||||
unsigned long send_time)
|
||||
{
|
||||
/**
|
||||
* _aggr -> pointer to the packet we want to aggregate with
|
||||
* _pos -> pointer to the position in the queue
|
||||
*/
|
||||
struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
|
||||
struct hlist_node *tmp_node;
|
||||
struct batman_packet *batman_packet =
|
||||
(struct batman_packet *)packet_buff;
|
||||
bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
|
||||
unsigned long flags;
|
||||
|
||||
/* find position for the packet in the forward queue */
|
||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
||||
/* own packets are not to be aggregated */
|
||||
if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) {
|
||||
hlist_for_each_entry(forw_packet_pos, tmp_node,
|
||||
&bat_priv->forw_bat_list, list) {
|
||||
if (can_aggregate_with(batman_packet,
|
||||
packet_len,
|
||||
send_time,
|
||||
direct_link,
|
||||
if_incoming,
|
||||
forw_packet_pos)) {
|
||||
forw_packet_aggr = forw_packet_pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing to aggregate with - either aggregation disabled or no
|
||||
* suitable aggregation packet found */
|
||||
if (forw_packet_aggr == NULL) {
|
||||
/* the following section can run without the lock */
|
||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
||||
|
||||
/**
|
||||
* if we could not aggregate this packet with one of the others
|
||||
* we hold it back for a while, so that it might be aggregated
|
||||
* later on
|
||||
*/
|
||||
if ((!own_packet) &&
|
||||
(atomic_read(&bat_priv->aggregation_enabled)))
|
||||
send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
|
||||
|
||||
new_aggregated_packet(packet_buff, packet_len,
|
||||
send_time, direct_link,
|
||||
if_incoming, own_packet);
|
||||
} else {
|
||||
aggregate(forw_packet_aggr,
|
||||
packet_buff, packet_len,
|
||||
direct_link);
|
||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* unpack the aggregated packets and process them one by one */
|
||||
void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
|
||||
int packet_len, struct batman_if *if_incoming)
|
||||
{
|
||||
struct batman_packet *batman_packet;
|
||||
int buff_pos = 0;
|
||||
unsigned char *hna_buff;
|
||||
|
||||
batman_packet = (struct batman_packet *)packet_buff;
|
||||
|
||||
do {
|
||||
/* network to host order for our 32bit seqno, and the
|
||||
orig_interval. */
|
||||
batman_packet->seqno = ntohl(batman_packet->seqno);
|
||||
|
||||
hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
|
||||
receive_bat_packet(ethhdr, batman_packet,
|
||||
hna_buff, hna_len(batman_packet),
|
||||
if_incoming);
|
||||
|
||||
buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
|
||||
batman_packet = (struct batman_packet *)
|
||||
(packet_buff + buff_pos);
|
||||
} while (aggregated_packet(buff_pos, packet_len,
|
||||
batman_packet->num_hna));
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
||||
*
|
||||
* Marek Lindner, Simon Wunderlich
|
||||
*
|
||||
* 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_AGGREGATION_H_
|
||||
#define _NET_BATMAN_ADV_AGGREGATION_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/* is there another aggregated packet here? */
|
||||
static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
|
||||
{
|
||||
int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN);
|
||||
|
||||
return (next_buff_pos <= packet_len) &&
|
||||
(next_buff_pos <= MAX_AGGREGATION_BYTES);
|
||||
}
|
||||
|
||||
void add_bat_packet_to_list(struct bat_priv *bat_priv,
|
||||
unsigned char *packet_buff, int packet_len,
|
||||
struct batman_if *if_incoming, char own_packet,
|
||||
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_ */
|
||||
@@ -1,343 +0,0 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
nonseekable_open(inode, 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,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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_ */
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user