Staging: merge staging patches into Linus's main branch
There were a number of patches that went into Linus's tree already that conflicted with other changes in the staging branch. This merge resolves those merge conflicts. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
commit
f341dddf1d
478 changed files with 29154 additions and 24466 deletions
|
@ -71,8 +71,6 @@ source "drivers/staging/asus_oled/Kconfig"
|
|||
|
||||
source "drivers/staging/panel/Kconfig"
|
||||
|
||||
source "drivers/staging/altpciechdma/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8187se/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192su/Kconfig"
|
||||
|
@ -81,20 +79,14 @@ source "drivers/staging/rtl8192u/Kconfig"
|
|||
|
||||
source "drivers/staging/rtl8192e/Kconfig"
|
||||
|
||||
source "drivers/staging/mimio/Kconfig"
|
||||
|
||||
source "drivers/staging/frontier/Kconfig"
|
||||
|
||||
source "drivers/staging/dream/Kconfig"
|
||||
|
||||
source "drivers/staging/pohmelfs/Kconfig"
|
||||
|
||||
source "drivers/staging/b3dfg/Kconfig"
|
||||
|
||||
source "drivers/staging/phison/Kconfig"
|
||||
|
||||
source "drivers/staging/p9auth/Kconfig"
|
||||
|
||||
source "drivers/staging/line6/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/vmwgfx/Kconfig"
|
||||
|
@ -117,7 +109,7 @@ source "drivers/staging/hv/Kconfig"
|
|||
|
||||
source "drivers/staging/vme/Kconfig"
|
||||
|
||||
source "drivers/staging/rar/Kconfig"
|
||||
source "drivers/staging/rar_register/Kconfig"
|
||||
|
||||
source "drivers/staging/sep/Kconfig"
|
||||
|
||||
|
@ -143,5 +135,9 @@ source "drivers/staging/netwave/Kconfig"
|
|||
|
||||
source "drivers/staging/sm7xx/Kconfig"
|
||||
|
||||
source "drivers/staging/dt3155/Kconfig"
|
||||
|
||||
source "drivers/staging/crystalhd/Kconfig"
|
||||
|
||||
endif # !STAGING_EXCLUDE_BUILD
|
||||
endif # STAGING
|
||||
|
|
|
@ -18,18 +18,14 @@ obj-$(CONFIG_RT2870) += rt2870/
|
|||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
obj-$(CONFIG_PANEL) += panel/
|
||||
obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
|
||||
obj-$(CONFIG_R8187SE) += rtl8187se/
|
||||
obj-$(CONFIG_RTL8192SU) += rtl8192su/
|
||||
obj-$(CONFIG_RTL8192U) += rtl8192u/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_INPUT_MIMIO) += mimio/
|
||||
obj-$(CONFIG_TRANZPORT) += frontier/
|
||||
obj-$(CONFIG_DREAM) += dream/
|
||||
obj-$(CONFIG_POHMELFS) += pohmelfs/
|
||||
obj-$(CONFIG_B3DFG) += b3dfg/
|
||||
obj-$(CONFIG_IDE_PHISON) += phison/
|
||||
obj-$(CONFIG_PLAN9AUTH) += p9auth/
|
||||
obj-$(CONFIG_LINE6_USB) += line6/
|
||||
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
|
||||
obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/
|
||||
|
@ -39,7 +35,7 @@ obj-$(CONFIG_VT6656) += vt6656/
|
|||
obj-$(CONFIG_FB_UDL) += udlfb/
|
||||
obj-$(CONFIG_HYPERV) += hv/
|
||||
obj-$(CONFIG_VME_BUS) += vme/
|
||||
obj-$(CONFIG_RAR_REGISTER) += rar/
|
||||
obj-$(CONFIG_RAR_REGISTER) += rar_register/
|
||||
obj-$(CONFIG_DX_SEP) += sep/
|
||||
obj-$(CONFIG_IIO) += iio/
|
||||
obj-$(CONFIG_RAMZSWAP) += ramzswap/
|
||||
|
@ -53,3 +49,5 @@ obj-$(CONFIG_WAVELAN) += wavelan/
|
|||
obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/
|
||||
obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
|
||||
obj-$(CONFIG_FB_SM7XX) += sm7xx/
|
||||
obj-$(CONFIG_DT3155) += dt3155/
|
||||
obj-$(CONFIG_CRYSTALHD) += crystalhd/
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
config ALTERA_PCIE_CHDMA
|
||||
tristate "Altera PCI Express Chaining DMA driver"
|
||||
depends on PCI
|
||||
default N
|
||||
---help---
|
||||
A reference driver that exercises the Chaining DMA logic reference
|
||||
design generated along the Altera FPGA PCI Express soft or hard core,
|
||||
only if instantiated using the MegaWizard, not the SOPC builder, of
|
||||
Quartus 8.1.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma.o
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
DONE:
|
||||
- functionality similar to logic testbench
|
||||
|
||||
TODO:
|
||||
- checkpatch.pl cleanups.
|
||||
- keep state of DMA engines.
|
||||
- keep data structure that keeps state of each transfer.
|
||||
- interrupt handler should iterate over outstanding descriptor tables.
|
||||
- complete userspace cdev to read/write using the DMA engines.
|
||||
- split off the DMA support functions in a module, re-usable by custom
|
||||
drivers.
|
||||
|
||||
Please coordinate work with, and send patches to
|
||||
Leon Woestenberg <leon@sidebranch.com>
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,3 @@
|
|||
obj-$(CONFIG_ARLAN) += arlan.o
|
||||
obj-$(CONFIG_ARLAN) += arlan.o
|
||||
|
||||
arlan-objs := arlan-main.o arlan-proc.o
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 1997 Cullen Jennings
|
||||
* Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
|
||||
* Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
|
||||
* GNU General Public License applies
|
||||
*/
|
||||
|
||||
|
@ -20,14 +20,14 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
|
||||
//#define ARLAN_DEBUGGING 1
|
||||
/* #define ARLAN_DEBUGGING 1 */
|
||||
|
||||
#define ARLAN_PROC_INTERFACE
|
||||
#define MAX_ARLANS 4 /* not more than 4 ! */
|
||||
|
@ -51,8 +51,8 @@ extern int arlan_debug;
|
|||
extern int arlan_entry_debug;
|
||||
extern int arlan_exit_debug;
|
||||
extern int testMemory;
|
||||
extern int arlan_command(struct net_device * dev, int command);
|
||||
|
||||
extern int arlan_command(struct net_device *dev, int command);
|
||||
|
||||
#define SIDUNKNOWN -1
|
||||
#define radioNodeIdUNKNOWN -1
|
||||
#define irqUNKNOWN 0
|
||||
|
@ -65,22 +65,21 @@ extern int arlan_command(struct net_device * dev, int command);
|
|||
#define registrationModeUNKNOWN -1
|
||||
|
||||
|
||||
#define IFDEBUG( L ) if ( (L) & arlan_debug )
|
||||
#define ARLAN_FAKE_HDR_LEN 12
|
||||
#define IFDEBUG(L) if ((L) & arlan_debug)
|
||||
#define ARLAN_FAKE_HDR_LEN 12
|
||||
|
||||
#ifdef ARLAN_DEBUGGING
|
||||
#define DEBUG 1
|
||||
#define ARLAN_ENTRY_EXIT_DEBUGGING 1
|
||||
#define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b)
|
||||
#define ARLAN_DEBUG(a, b) printk(KERN_DEBUG a, b)
|
||||
#else
|
||||
#define ARLAN_DEBUG(a,b)
|
||||
#define ARLAN_DEBUG(a, b)
|
||||
#endif
|
||||
|
||||
#define ARLAN_SHMEM_SIZE 0x2000
|
||||
|
||||
struct arlan_shmem
|
||||
{
|
||||
/* Header Signature */
|
||||
struct arlan_shmem {
|
||||
/* Header Signature */
|
||||
volatile char textRegion[48];
|
||||
volatile u_char resetFlag;
|
||||
volatile u_char diagnosticInfo;
|
||||
|
@ -91,10 +90,10 @@ struct arlan_shmem
|
|||
volatile u_char hardwareType;
|
||||
volatile u_char majorHardwareVersion;
|
||||
volatile u_char minorHardwareVersion;
|
||||
volatile u_char radioModule;// shows EEPROM, can be overridden at 0x111
|
||||
volatile u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A
|
||||
volatile u_char radioModule;/* shows EEPROM, can be overridden at 0x111 */
|
||||
volatile u_char defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */
|
||||
volatile u_char _2[47];
|
||||
|
||||
|
||||
/* Control/Status Block - 0x0080 */
|
||||
volatile u_char interruptInProgress; /* not used by lancpu */
|
||||
volatile u_char cntrlRegImage; /* not used by lancpu */
|
||||
|
@ -113,7 +112,7 @@ struct arlan_shmem
|
|||
volatile u_char rxQuality;
|
||||
volatile u_char scrambled;
|
||||
volatile u_char _4[1];
|
||||
|
||||
|
||||
/* Transmit Status - 0x00b0 */
|
||||
volatile u_char txStatus;
|
||||
volatile u_char txAckQuality;
|
||||
|
@ -151,7 +150,7 @@ struct arlan_shmem
|
|||
volatile u_short routerId;
|
||||
volatile u_char _10[9];
|
||||
volatile u_char txAttenuation;
|
||||
volatile u_char systemId[4];
|
||||
volatile u_char systemId[4];
|
||||
volatile u_short globalChecksum;
|
||||
volatile u_char _11[4];
|
||||
volatile u_short maxDatagramSize;
|
||||
|
@ -207,19 +206,19 @@ struct arlan_shmem
|
|||
volatile u_char hostcpuLock;
|
||||
volatile u_char lancpuLock;
|
||||
volatile u_char resetTime[18];
|
||||
|
||||
|
||||
volatile u_char numDatagramsTransmitted[4];
|
||||
volatile u_char numReTransmissions[4];
|
||||
volatile u_char numFramesDiscarded[4];
|
||||
volatile u_char numDatagramsReceived[4];
|
||||
volatile u_char numDuplicateReceivedFrames[4];
|
||||
volatile u_char numDatagramsDiscarded[4];
|
||||
|
||||
|
||||
volatile u_short maxNumReTransmitDatagram;
|
||||
volatile u_short maxNumReTransmitFrames;
|
||||
volatile u_short maxNumConsecutiveDuplicateFrames;
|
||||
/* misaligned here so we have to go to characters */
|
||||
|
||||
|
||||
volatile u_char numBytesTransmitted[4];
|
||||
volatile u_char numBytesReceived[4];
|
||||
volatile u_char numCRCErrors[4];
|
||||
|
@ -259,7 +258,7 @@ struct arlan_conf_stru {
|
|||
int channelNumber;
|
||||
int scramblingDisable;
|
||||
int txAttenuation;
|
||||
int systemId;
|
||||
int systemId;
|
||||
int maxDatagramSize;
|
||||
int maxFrameSize;
|
||||
int maxRetries;
|
||||
|
@ -316,8 +315,7 @@ struct arlan_conf_stru {
|
|||
|
||||
extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
|
||||
|
||||
struct TxParam
|
||||
{
|
||||
struct TxParam {
|
||||
volatile short offset;
|
||||
volatile short length;
|
||||
volatile u_char dest[6];
|
||||
|
@ -330,12 +328,12 @@ struct TxParam
|
|||
#define TX_RING_SIZE 2
|
||||
/* Information that need to be kept for each board. */
|
||||
struct arlan_private {
|
||||
struct arlan_shmem __iomem * card;
|
||||
struct arlan_shmem * conf;
|
||||
struct arlan_shmem __iomem *card;
|
||||
struct arlan_shmem *conf;
|
||||
|
||||
struct arlan_conf_stru * Conf;
|
||||
struct arlan_conf_stru *Conf;
|
||||
int bad;
|
||||
int reset;
|
||||
int reset;
|
||||
unsigned long lastReset;
|
||||
struct timer_list timer;
|
||||
struct timer_list tx_delay_timer;
|
||||
|
@ -407,38 +405,38 @@ struct arlan_private {
|
|||
|
||||
#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
|
||||
#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
|
||||
|
||||
#define READSHM(to,from,atype) {\
|
||||
|
||||
#define READSHM(to, from, atype) {\
|
||||
atype tmp;\
|
||||
memcpy_fromio(&(tmp),&(from),sizeof(atype));\
|
||||
memcpy_fromio(&(tmp), &(from), sizeof(atype));\
|
||||
to = tmp;\
|
||||
}
|
||||
|
||||
#define READSHMEM(from,atype)\
|
||||
#define READSHMEM(from, atype)\
|
||||
atype from; \
|
||||
READSHM(from, arlan->from, atype);
|
||||
|
||||
#define WRITESHM(to,from,atype) \
|
||||
#define WRITESHM(to, from, atype) \
|
||||
{ atype tmpSHM = from;\
|
||||
memcpy_toio(&(to),&tmpSHM,sizeof(atype));\
|
||||
memcpy_toio(&(to), &tmpSHM, sizeof(atype));\
|
||||
}
|
||||
|
||||
#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \
|
||||
#define DEBUGSHM(levelSHM, stringSHM, stuff, atype) \
|
||||
{ atype tmpSHM; \
|
||||
memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\
|
||||
IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\
|
||||
memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\
|
||||
IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\
|
||||
}
|
||||
|
||||
#define WRITESHMB(to, val) \
|
||||
writeb(val,&(to))
|
||||
writeb(val, &(to))
|
||||
#define READSHMB(to) \
|
||||
readb(&(to))
|
||||
#define WRITESHMS(to, val) \
|
||||
writew(val,&(to))
|
||||
writew(val, &(to))
|
||||
#define READSHMS(to) \
|
||||
readw(&(to))
|
||||
#define WRITESHMI(to, val) \
|
||||
writel(val,&(to))
|
||||
writel(val, &(to))
|
||||
#define READSHMI(to) \
|
||||
readl(&(to))
|
||||
|
||||
|
@ -447,51 +445,51 @@ struct arlan_private {
|
|||
|
||||
|
||||
#define registrationBad(dev)\
|
||||
( ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \
|
||||
( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0) )
|
||||
(( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \
|
||||
( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0))
|
||||
|
||||
|
||||
#define readControlRegister(dev)\
|
||||
READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
|
||||
READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
|
||||
|
||||
#define writeControlRegister(dev, v){\
|
||||
WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage ,((v) &0xF) );\
|
||||
WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister ,(v) );}
|
||||
#define writeControlRegister(dev, v) {\
|
||||
WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\
|
||||
WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); }
|
||||
|
||||
|
||||
#define arlan_interrupt_lancpu(dev) {\
|
||||
int cr; \
|
||||
\
|
||||
cr = readControlRegister(dev);\
|
||||
if (cr & ARLAN_CHANNEL_ATTENTION){ \
|
||||
if (cr & ARLAN_CHANNEL_ATTENTION) { \
|
||||
writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
|
||||
}else \
|
||||
} else \
|
||||
writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
|
||||
}
|
||||
|
||||
#define clearChannelAttention(dev){ \
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);}
|
||||
#define clearChannelAttention(dev) { \
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); }
|
||||
#define setHardwareReset(dev) {\
|
||||
writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);}
|
||||
writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); }
|
||||
#define clearHardwareReset(dev) {\
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);}
|
||||
#define setInterruptEnable(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ;}
|
||||
#define clearInterruptEnable(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ;}
|
||||
#define setClearInterrupt(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ;}
|
||||
#define clearClearInterrupt(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);}
|
||||
#define setPowerOff(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
|
||||
#define setPowerOn(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER)); }
|
||||
#define arlan_lock_card_access(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
|
||||
#define arlan_unlock_card_access(dev){\
|
||||
writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); }
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); }
|
||||
#define setInterruptEnable(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ; }
|
||||
#define clearInterruptEnable(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ; }
|
||||
#define setClearInterrupt(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ; }
|
||||
#define clearClearInterrupt(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); }
|
||||
#define setPowerOff(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
|
||||
#define setPowerOn(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); }
|
||||
#define arlan_lock_card_access(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
|
||||
#define arlan_unlock_card_access(dev) {\
|
||||
writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); }
|
||||
|
||||
|
||||
|
||||
|
@ -525,7 +523,6 @@ struct arlan_private {
|
|||
| ARLAN_COMMAND_RESET)
|
||||
|
||||
|
||||
|
||||
#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001
|
||||
#define ARLAN_DEBUG_RESET 0x00002
|
||||
#define ARLAN_DEBUG_TIMING 0x00004
|
||||
|
@ -536,4 +533,3 @@ struct arlan_private {
|
|||
#define ARLAN_DEBUG_INTERRUPT 0x00080
|
||||
#define ARLAN_DEBUG_STARTUP 0x00100
|
||||
#define ARLAN_DEBUG_SHUTDOWN 0x00200
|
||||
|
||||
|
|
|
@ -52,6 +52,10 @@
|
|||
#define ASUS_OLED_DISP_HEIGHT 32
|
||||
#define ASUS_OLED_PACKET_BUF_SIZE 256
|
||||
|
||||
#define USB_VENDOR_ID_ASUS 0x0b05
|
||||
#define USB_DEVICE_ID_ASUS_LCM 0x1726
|
||||
#define USB_DEVICE_ID_ASUS_LCM2 0x175b
|
||||
|
||||
MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
|
||||
MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -83,18 +87,20 @@ struct oled_dev_desc_str {
|
|||
};
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id id_table[] = {
|
||||
static const struct usb_device_id id_table[] = {
|
||||
/* Asus G1/G2 (and variants)*/
|
||||
{ USB_DEVICE(0x0b05, 0x1726) },
|
||||
{ USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM) },
|
||||
/* Asus G50V (and possibly others - G70? G71?)*/
|
||||
{ USB_DEVICE(0x0b05, 0x175b) },
|
||||
{ USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2) },
|
||||
{ },
|
||||
};
|
||||
|
||||
/* parameters of specific devices */
|
||||
static struct oled_dev_desc_str oled_dev_desc_table[] = {
|
||||
{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
|
||||
{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
|
||||
{ USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, 128, PACK_MODE_G1,
|
||||
"G1/G2" },
|
||||
{ USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2, 256, PACK_MODE_G50,
|
||||
"G50" },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -424,6 +430,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev,
|
|||
|
||||
kfree(odev->buf);
|
||||
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
|
||||
if (odev->buf == NULL) {
|
||||
odev->buf_size = 0;
|
||||
printk(ASUS_OLED_ERROR "Out of memory!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(odev->buf, 0xff, odev->buf_size);
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
config B3DFG
|
||||
tristate "Brontes 3d Frame Framegrabber"
|
||||
depends on PCI
|
||||
default n
|
||||
---help---
|
||||
This driver provides support for the Brontes 3d Framegrabber
|
||||
PCI card.
|
||||
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called b3dfg.
|
|
@ -1 +0,0 @@
|
|||
obj-$(CONFIG_B3DFG) += b3dfg.o
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
- queue/wait buffer presents filltime results for each frame?
|
||||
- counting of dropped frames
|
||||
- review endianness
|
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@
|
|||
|
||||
config BATMAN_ADV
|
||||
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
|
||||
depends on PROC_FS && PACKET
|
||||
depends on PROC_FS && NET
|
||||
default n
|
||||
---help---
|
||||
|
||||
|
@ -14,10 +14,10 @@ config BATMAN_ADV
|
|||
http://www.open-mesh.org/ for more information and user space
|
||||
tools.
|
||||
|
||||
config BATMAN_DEBUG
|
||||
config BATMAN_ADV_DEBUG
|
||||
bool "B.A.T.M.A.N. debugging"
|
||||
depends on BATMAN_ADV != n
|
||||
help
|
||||
---help---
|
||||
|
||||
This is an option for use by developers; most people should
|
||||
say N here. This enables compilation of support for
|
||||
|
|
|
@ -19,4 +19,4 @@
|
|||
#
|
||||
|
||||
obj-m += batman-adv.o
|
||||
batman-adv-objs := main.o proc.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 log.o
|
||||
batman-adv-objs := main.o proc.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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[state: 07-11-2009]
|
||||
[state: 06-01-2010]
|
||||
|
||||
BATMAN-ADV
|
||||
----------
|
||||
|
@ -15,19 +15,6 @@ above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX.
|
|||
This is batman-advanced implemented as Linux kernel driver. It does not depend
|
||||
on any network (other) driver, and can be used on wifi as well as ethernet,
|
||||
vpn, etc ... (anything with ethernet-style layer 2).
|
||||
It compiles against and should work with Linux 2.6.20 - 2.6.31. Supporting older
|
||||
versions is not planned, but it's probably easy to backport it. If you work on a
|
||||
backport, feel free to contact us. :-)
|
||||
|
||||
COMPILE
|
||||
-------
|
||||
To compile against your currently installed kernel, just type:
|
||||
|
||||
# make
|
||||
|
||||
if you want to compile against some other kernel, use:
|
||||
|
||||
# make KERNELPATH=/path/to/kernel
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
@ -73,16 +60,9 @@ When configured as server, you can get a topology snapshot of your mesh:
|
|||
|
||||
# cat /proc/net/batman-adv/vis
|
||||
|
||||
This output format is a graphviz formatted text file which can be
|
||||
processed with graphviz-tools like dot.
|
||||
The labels are similar/compatible to the ETX metric, 1.0 means perfect
|
||||
connection (100%), 2.0 means 50%, 3.0 means 33% and so on.
|
||||
|
||||
Alternatively, a JSON output format is available. The format can be set
|
||||
using by writing either "dot_draw" or "json" into the vis_format file.
|
||||
"dot_draw" is selected by default.
|
||||
|
||||
echo "json" > /proc/net/batman-adv/vis_format
|
||||
The output is in a generic raw format. Use the batctl tool (See below)
|
||||
to convert this to other formats more suitable for graphing, eg
|
||||
graphviz dot, or JSON data-interchange format.
|
||||
|
||||
In very mobile scenarios, you might want to adjust the originator
|
||||
interval to a lower value. This will make the mesh more responsive to
|
||||
|
@ -96,15 +76,59 @@ To deactivate batman, do:
|
|||
|
||||
# echo "" > /proc/net/batman-adv/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 commands: 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 sometimes
|
||||
necessary to see more detail debug messages. This must be enabled when
|
||||
compiling the batman-adv module. Use "make menuconfig" and enable the
|
||||
option "B.A.T.M.A.N. debugging".
|
||||
|
||||
The additional debug output is by default disabled. It can be enabled
|
||||
either at kernel module load time or during run time. To enable debug
|
||||
output at module load time, add the module parameter debug=<value>.
|
||||
<value> can take one of four values.
|
||||
|
||||
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
|
||||
|
||||
e.g.
|
||||
|
||||
modprobe batman-adv debug=2
|
||||
|
||||
will load the module and enable debug messages for when routes or HNAs
|
||||
change.
|
||||
|
||||
The debug output can also be changed at runtime using the file
|
||||
/sys/module/batman-adv/parameters/debug. e.g.
|
||||
|
||||
echo 2 > /sys/module/batman-adv/parameters/debug
|
||||
|
||||
enables debug messages for when routes or HNAs
|
||||
|
||||
The debug output is sent to the kernel logs. So try dmesg, logread etc
|
||||
to see the debug messages.
|
||||
|
||||
BATCTL
|
||||
------
|
||||
|
||||
B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts partici-
|
||||
pating in the virtual switch are completely transparent for all proto-
|
||||
cols 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.
|
||||
B.A.T.M.A.N. advanced operates on layer 2 and thus 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).
|
||||
|
||||
|
|
|
@ -17,30 +17,6 @@
|
|||
-> transtable_global (read-only) [outputs the global translation table]
|
||||
-> transtable_local (read-only) [outputs the local translation table]
|
||||
|
||||
=> vis "raw" data output
|
||||
* the raw format shall replace dot draw / json to offer a neutral that can
|
||||
* be converted
|
||||
* the format (comma seperated entries):
|
||||
-> "mac" -> mac address of an originator (each line begins with it)
|
||||
-> "TQ mac value" -> src mac's link quality towards mac address
|
||||
-> "HNA mac" -> HNA announced by source mac
|
||||
-> "PRIMARY" -> this is a primary interface
|
||||
-> "SEC mac" -> secondary mac address of source (requires preceeding
|
||||
-> PRIMARY)
|
||||
|
||||
=> logging
|
||||
* the log level LOG_TYPE_CRIT, LOG_TYPE_WARN & LOG_TYPE_NOTICE will be
|
||||
* unified to use printk
|
||||
* LOG_TYPE_BATMAN & LOG_TYPE_ROUTES will also use printk but only after the
|
||||
* internal debug level has been raised
|
||||
* the internal debug level can be modified using a module parameter (debug)
|
||||
* or at run time via /sys/module/batman-adv/parameters/debug
|
||||
* make use of printk %pM support instead of converting mac addresses
|
||||
* manually
|
||||
|
||||
=> strip out all backward compatibility support to older kernels
|
||||
(only found in compat.h)
|
||||
|
||||
=> fix checkpatch.pl errors
|
||||
|
||||
Please send all patches to:
|
||||
|
|
|
@ -96,6 +96,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
|
|||
int own_packet)
|
||||
{
|
||||
struct forw_packet *forw_packet_aggr;
|
||||
unsigned long flags;
|
||||
|
||||
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
|
||||
if (!forw_packet_aggr)
|
||||
|
@ -115,6 +116,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
|
|||
packet_buff,
|
||||
forw_packet_aggr->packet_len);
|
||||
|
||||
forw_packet_aggr->skb = NULL;
|
||||
forw_packet_aggr->own = own_packet;
|
||||
forw_packet_aggr->if_incoming = if_incoming;
|
||||
forw_packet_aggr->num_packets = 0;
|
||||
|
@ -126,9 +128,9 @@ static void new_aggregated_packet(unsigned char *packet_buff,
|
|||
forw_packet_aggr->direct_link_flags |= 1;
|
||||
|
||||
/* add new packet to packet list */
|
||||
spin_lock(&forw_bat_list_lock);
|
||||
spin_lock_irqsave(&forw_bat_list_lock, flags);
|
||||
hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
|
||||
spin_unlock(&forw_bat_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
|
||||
|
||||
/* start timer for this packet */
|
||||
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
|
||||
|
@ -168,9 +170,10 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
|
|||
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(&forw_bat_list_lock);
|
||||
spin_lock_irqsave(&forw_bat_list_lock, flags);
|
||||
/* own packets are not to be aggregated */
|
||||
if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
|
||||
hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
|
||||
|
@ -191,7 +194,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
|
|||
* suitable aggregation packet found */
|
||||
if (forw_packet_aggr == NULL) {
|
||||
/* the following section can run without the lock */
|
||||
spin_unlock(&forw_bat_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
|
||||
new_aggregated_packet(packet_buff, packet_len,
|
||||
send_time, direct_link,
|
||||
if_incoming, own_packet);
|
||||
|
@ -199,7 +202,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
|
|||
aggregate(forw_packet_aggr,
|
||||
packet_buff, packet_len,
|
||||
direct_link);
|
||||
spin_unlock(&forw_bat_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "main.h"
|
||||
#include "bitarray.h"
|
||||
#include "log.h"
|
||||
|
||||
/* returns true if the corresponding bit in the given seq_bits indicates true
|
||||
* and curr_seqno is within range of last_seqno */
|
||||
|
@ -80,8 +79,8 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
|
|||
* from.
|
||||
*
|
||||
* left is high, right is low: FEDC BA98 7654 3210
|
||||
* ^^ ^^
|
||||
* vvvv
|
||||
* ^^ ^^
|
||||
* vvvv
|
||||
* ^^^^ = from, vvvvv =to, we'd have word_num==1 and
|
||||
* word_offset==WORD_BIT_SIZE/2 ????? in this example.
|
||||
* (=24 bits)
|
||||
|
@ -133,13 +132,13 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
|
|||
(seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) {
|
||||
|
||||
if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
|
||||
debug_log(LOG_TYPE_BATMAN,
|
||||
"We missed a lot of packets (%i) !\n",
|
||||
seq_num_diff-1);
|
||||
bat_dbg(DBG_BATMAN,
|
||||
"We missed a lot of packets (%i) !\n",
|
||||
seq_num_diff-1);
|
||||
|
||||
if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
|
||||
debug_log(LOG_TYPE_BATMAN,
|
||||
"Other host probably restarted !\n");
|
||||
bat_dbg(DBG_BATMAN,
|
||||
"Other host probably restarted !\n");
|
||||
|
||||
for (i = 0; i < NUM_WORDS; i++)
|
||||
seq_bits[i] = 0;
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 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
|
||||
*
|
||||
*
|
||||
* This file contains macros for maintaining compatibility with older versions
|
||||
* of the Linux kernel.
|
||||
*/
|
||||
|
||||
#include <linux/version.h> /* LINUX_VERSION_CODE */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
|
||||
|
||||
#define skb_set_network_header(_skb, _offset) \
|
||||
do { (_skb)->nh.raw = (_skb)->data + (_offset); } while (0)
|
||||
|
||||
#define skb_reset_mac_header(_skb) \
|
||||
do { (_skb)->mac.raw = (_skb)->data; } while (0)
|
||||
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
|
||||
|
||||
#define device_create(_cls, _parent, _devt, _device, _fmt) \
|
||||
class_device_create(_cls, _parent, _devt, _device, _fmt)
|
||||
|
||||
#define device_destroy(_cls, _device) \
|
||||
class_device_destroy(_cls, _device)
|
||||
|
||||
#else
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
|
||||
|
||||
#define device_create(_cls, _parent, _devt, _device, _fmt) \
|
||||
device_create_drvdata(_cls, _parent, _devt, _device, _fmt)
|
||||
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */
|
||||
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
|
||||
|
||||
#define cancel_delayed_work_sync(wq) cancel_rearming_delayed_work(wq)
|
||||
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
|
||||
#define strict_strtoul(cp, base, res) \
|
||||
({ \
|
||||
int ret = 0; \
|
||||
char *endp; \
|
||||
*res = simple_strtoul(cp, &endp, base); \
|
||||
if (cp == endp) \
|
||||
ret = -EINVAL; \
|
||||
ret; \
|
||||
})
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
|
|
@ -19,14 +19,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include "main.h"
|
||||
#include "device.h"
|
||||
#include "log.h"
|
||||
#include "send.h"
|
||||
#include "types.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "hard-interface.h"
|
||||
|
||||
static struct class *batman_class;
|
||||
|
||||
|
@ -60,7 +59,7 @@ int bat_device_setup(void)
|
|||
/* register our device - kernel assigns a free major number */
|
||||
tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
|
||||
if (tmp_major < 0) {
|
||||
debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n",
|
||||
printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n",
|
||||
tmp_major);
|
||||
return 0;
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ int bat_device_setup(void)
|
|||
batman_class = class_create(THIS_MODULE, "batman-adv");
|
||||
|
||||
if (IS_ERR(batman_class)) {
|
||||
debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n");
|
||||
printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -111,7 +110,7 @@ int bat_device_open(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
if (device_client_hash[i] != device_client) {
|
||||
debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n");
|
||||
printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n");
|
||||
kfree(device_client);
|
||||
return -EXFULL;
|
||||
}
|
||||
|
@ -119,7 +118,7 @@ int bat_device_open(struct inode *inode, struct file *file)
|
|||
INIT_LIST_HEAD(&device_client->queue_list);
|
||||
device_client->queue_len = 0;
|
||||
device_client->index = i;
|
||||
device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock);
|
||||
spin_lock_init(&device_client->lock);
|
||||
init_waitqueue_head(&device_client->queue_wait);
|
||||
|
||||
file->private_data = device_client;
|
||||
|
@ -134,8 +133,9 @@ int bat_device_release(struct inode *inode, struct file *file)
|
|||
(struct device_client *)file->private_data;
|
||||
struct device_packet *device_packet;
|
||||
struct list_head *list_pos, *list_pos_tmp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&device_client->lock);
|
||||
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) {
|
||||
|
@ -147,7 +147,7 @@ int bat_device_release(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
device_client_hash[device_client->index] = NULL;
|
||||
spin_unlock(&device_client->lock);
|
||||
spin_unlock_irqrestore(&device_client->lock, flags);
|
||||
|
||||
kfree(device_client);
|
||||
dec_module_count();
|
||||
|
@ -162,6 +162,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
|
|||
(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;
|
||||
|
@ -178,14 +179,14 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
spin_lock(&device_client->lock);
|
||||
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(&device_client->lock);
|
||||
spin_unlock_irqrestore(&device_client->lock, flags);
|
||||
|
||||
error = __copy_to_user(buf, &device_packet->icmp_packet,
|
||||
sizeof(struct icmp_packet));
|
||||
|
@ -206,9 +207,11 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
|
|||
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)) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n");
|
||||
bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -219,12 +222,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
|
|||
return -EFAULT;
|
||||
|
||||
if (icmp_packet.packet_type != BAT_ICMP) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
|
||||
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) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
|
||||
bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -240,7 +243,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
|
|||
if (atomic_read(&module_state) != MODULE_ACTIVE)
|
||||
goto dst_unreach;
|
||||
|
||||
spin_lock(&orig_hash_lock);
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
|
||||
|
||||
if (!orig_node)
|
||||
|
@ -250,9 +253,15 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
|
|||
goto unlock;
|
||||
|
||||
batman_if = orig_node->batman_if;
|
||||
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
|
||||
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
|
||||
if (!batman_if)
|
||||
goto unlock;
|
||||
goto dst_unreach;
|
||||
|
||||
if (batman_if->if_active != IF_ACTIVE)
|
||||
goto dst_unreach;
|
||||
|
||||
memcpy(icmp_packet.orig,
|
||||
batman_if->net_dev->dev_addr,
|
||||
|
@ -260,13 +269,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
|
|||
|
||||
send_raw_packet((unsigned char *)&icmp_packet,
|
||||
sizeof(struct icmp_packet),
|
||||
batman_if, orig_node->router->addr);
|
||||
batman_if, dstaddr);
|
||||
|
||||
spin_unlock(&orig_hash_lock);
|
||||
goto out;
|
||||
|
||||
unlock:
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
dst_unreach:
|
||||
icmp_packet.msg_type = DESTINATION_UNREACHABLE;
|
||||
bat_device_add_packet(device_client, &icmp_packet);
|
||||
|
@ -291,6 +299,7 @@ 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_KERNEL);
|
||||
|
||||
|
@ -301,12 +310,12 @@ void bat_device_add_packet(struct device_client *device_client,
|
|||
memcpy(&device_packet->icmp_packet, icmp_packet,
|
||||
sizeof(struct icmp_packet));
|
||||
|
||||
spin_lock(&device_client->lock);
|
||||
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(&device_client->lock);
|
||||
spin_unlock_irqrestore(&device_client->lock, flags);
|
||||
kfree(device_packet);
|
||||
return;
|
||||
}
|
||||
|
@ -323,7 +332,7 @@ void bat_device_add_packet(struct device_client *device_client,
|
|||
device_client->queue_len--;
|
||||
}
|
||||
|
||||
spin_unlock(&device_client->lock);
|
||||
spin_unlock_irqrestore(&device_client->lock, flags);
|
||||
|
||||
wake_up(&device_client->queue_wait);
|
||||
}
|
||||
|
|
|
@ -21,13 +21,11 @@
|
|||
|
||||
#include "main.h"
|
||||
#include "hard-interface.h"
|
||||
#include "log.h"
|
||||
#include "soft-interface.h"
|
||||
#include "send.h"
|
||||
#include "translation-table.h"
|
||||
#include "routing.h"
|
||||
#include "hash.h"
|
||||
#include "compat.h"
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
|
@ -75,7 +73,6 @@ int hardif_min_mtu(void)
|
|||
static void check_known_mac_addr(uint8_t *addr)
|
||||
{
|
||||
struct batman_if *batman_if;
|
||||
char mac_string[ETH_STR_LEN];
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
||||
|
@ -86,10 +83,9 @@ static void check_known_mac_addr(uint8_t *addr)
|
|||
if (!compare_orig(batman_if->net_dev->dev_addr, addr))
|
||||
continue;
|
||||
|
||||
addr_to_string(mac_string, addr);
|
||||
debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n",
|
||||
mac_string, batman_if->dev);
|
||||
debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n");
|
||||
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");
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -154,9 +150,6 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
|
|||
if (batman_if->if_active != IF_ACTIVE)
|
||||
return;
|
||||
|
||||
if (batman_if->raw_sock)
|
||||
sock_release(batman_if->raw_sock);
|
||||
|
||||
/**
|
||||
* batman_if->net_dev has been acquired by dev_get_by_name() in
|
||||
* proc_interfaces_write() and has to be unreferenced.
|
||||
|
@ -165,22 +158,16 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
|
|||
if (batman_if->net_dev)
|
||||
dev_put(batman_if->net_dev);
|
||||
|
||||
batman_if->raw_sock = NULL;
|
||||
batman_if->net_dev = NULL;
|
||||
|
||||
batman_if->if_active = IF_INACTIVE;
|
||||
active_ifs--;
|
||||
|
||||
debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n",
|
||||
batman_if->dev);
|
||||
printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
|
||||
batman_if->dev);
|
||||
}
|
||||
|
||||
/* (re)activate given interface. */
|
||||
static void hardif_activate_interface(struct batman_if *batman_if)
|
||||
{
|
||||
struct sockaddr_ll bind_addr;
|
||||
int retval;
|
||||
|
||||
if (batman_if->if_active != IF_INACTIVE)
|
||||
return;
|
||||
|
||||
|
@ -192,35 +179,8 @@ static void hardif_activate_interface(struct batman_if *batman_if)
|
|||
if (!batman_if->net_dev)
|
||||
goto dev_err;
|
||||
|
||||
retval = sock_create_kern(PF_PACKET, SOCK_RAW,
|
||||
__constant_htons(ETH_P_BATMAN),
|
||||
&batman_if->raw_sock);
|
||||
|
||||
if (retval < 0) {
|
||||
debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n",
|
||||
retval);
|
||||
goto sock_err;
|
||||
}
|
||||
|
||||
bind_addr.sll_family = AF_PACKET;
|
||||
bind_addr.sll_ifindex = batman_if->net_dev->ifindex;
|
||||
bind_addr.sll_protocol = 0; /* is set by the kernel */
|
||||
|
||||
retval = kernel_bind(batman_if->raw_sock,
|
||||
(struct sockaddr *)&bind_addr, sizeof(bind_addr));
|
||||
|
||||
if (retval < 0) {
|
||||
debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n",
|
||||
retval);
|
||||
goto bind_err;
|
||||
}
|
||||
|
||||
check_known_mac_addr(batman_if->net_dev->dev_addr);
|
||||
|
||||
batman_if->raw_sock->sk->sk_user_data =
|
||||
batman_if->raw_sock->sk->sk_data_ready;
|
||||
batman_if->raw_sock->sk->sk_data_ready = batman_data_ready;
|
||||
|
||||
addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
|
||||
|
||||
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
|
||||
|
@ -235,17 +195,12 @@ static void hardif_activate_interface(struct batman_if *batman_if)
|
|||
if (batman_if->if_num == 0)
|
||||
set_main_if_addr(batman_if->net_dev->dev_addr);
|
||||
|
||||
debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n",
|
||||
batman_if->dev);
|
||||
printk(KERN_INFO "batman-adv:Interface activated: %s\n",
|
||||
batman_if->dev);
|
||||
|
||||
return;
|
||||
|
||||
bind_err:
|
||||
sock_release(batman_if->raw_sock);
|
||||
sock_err:
|
||||
dev_put(batman_if->net_dev);
|
||||
dev_err:
|
||||
batman_if->raw_sock = NULL;
|
||||
batman_if->net_dev = NULL;
|
||||
}
|
||||
|
||||
|
@ -290,7 +245,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num)
|
|||
data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
|
||||
GFP_ATOMIC);
|
||||
if (!data_ptr) {
|
||||
debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
|
||||
printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -301,7 +256,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num)
|
|||
|
||||
data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
|
||||
if (!data_ptr) {
|
||||
debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
|
||||
printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -319,16 +274,16 @@ int hardif_add_interface(char *dev, int if_num)
|
|||
struct batman_if *batman_if;
|
||||
struct batman_packet *batman_packet;
|
||||
struct orig_node *orig_node;
|
||||
struct hash_it_t *hashit = NULL;
|
||||
unsigned long flags;
|
||||
HASHIT(hashit);
|
||||
|
||||
batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
|
||||
|
||||
if (!batman_if) {
|
||||
debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev);
|
||||
printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
batman_if->raw_sock = NULL;
|
||||
batman_if->net_dev = NULL;
|
||||
|
||||
if ((if_num == 0) && (num_hna > 0))
|
||||
|
@ -339,7 +294,7 @@ int hardif_add_interface(char *dev, int if_num)
|
|||
batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
|
||||
|
||||
if (!batman_if->packet_buff) {
|
||||
debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev);
|
||||
printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -348,7 +303,7 @@ int hardif_add_interface(char *dev, int if_num)
|
|||
batman_if->if_active = IF_INACTIVE;
|
||||
INIT_RCU_HEAD(&batman_if->rcu);
|
||||
|
||||
debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev);
|
||||
printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev);
|
||||
avail_ifs++;
|
||||
|
||||
INIT_LIST_HEAD(&batman_if->list);
|
||||
|
@ -376,20 +331,20 @@ int hardif_add_interface(char *dev, int if_num)
|
|||
|
||||
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
|
||||
* if_num */
|
||||
spin_lock(&orig_hash_lock);
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
|
||||
while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
|
||||
orig_node = hashit->bucket->data;
|
||||
while (hash_iterate(orig_hash, &hashit)) {
|
||||
orig_node = hashit.bucket->data;
|
||||
if (resize_orig(orig_node, if_num) == -1) {
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
|
||||
if (!hardif_is_interface_up(batman_if->dev))
|
||||
debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev);
|
||||
printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
|
||||
else
|
||||
hardif_activate_interface(batman_if);
|
||||
|
||||
|
@ -400,8 +355,7 @@ int hardif_add_interface(char *dev, int if_num)
|
|||
return 1;
|
||||
|
||||
out:
|
||||
if (batman_if->packet_buff)
|
||||
kfree(batman_if->packet_buff);
|
||||
kfree(batman_if->packet_buff);
|
||||
kfree(batman_if);
|
||||
kfree(dev);
|
||||
return -1;
|
||||
|
@ -413,7 +367,7 @@ char hardif_get_active_if_num(void)
|
|||
}
|
||||
|
||||
static int hard_if_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)ptr;
|
||||
struct batman_if *batman_if = get_batman_if_by_name(dev->name);
|
||||
|
@ -436,7 +390,6 @@ static int hard_if_event(struct notifier_block *this,
|
|||
break;
|
||||
/* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
|
||||
default:
|
||||
/* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */
|
||||
break;
|
||||
};
|
||||
|
||||
|
@ -446,6 +399,122 @@ out:
|
|||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/* find batman interface by netdev. assumes rcu_read_lock on */
|
||||
static struct batman_if *find_batman_if(struct net_device *dev)
|
||||
{
|
||||
struct batman_if *batman_if;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
||||
if (batman_if->net_dev == dev) {
|
||||
rcu_read_unlock();
|
||||
return batman_if;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct batman_packet *batman_packet;
|
||||
struct batman_if *batman_if;
|
||||
struct net_device_stats *stats;
|
||||
int ret;
|
||||
|
||||
skb = skb_share_check(skb, GFP_ATOMIC);
|
||||
|
||||
/* skb was released by skb_share_check() */
|
||||
if (!skb)
|
||||
goto err_out;
|
||||
|
||||
if (atomic_read(&module_state) != MODULE_ACTIVE)
|
||||
goto err_free;
|
||||
|
||||
/* packet should hold at least type and version */
|
||||
if (unlikely(skb_headlen(skb) < 2))
|
||||
goto err_free;
|
||||
|
||||
/* expect a valid ethernet header here. */
|
||||
if (unlikely(skb->mac_len != sizeof(struct ethhdr)
|
||||
|| !skb_mac_header(skb)))
|
||||
goto err_free;
|
||||
|
||||
batman_if = find_batman_if(skb->dev);
|
||||
if (!batman_if)
|
||||
goto err_free;
|
||||
|
||||
/* discard frames on not active interfaces */
|
||||
if (batman_if->if_active != IF_ACTIVE)
|
||||
goto err_free;
|
||||
|
||||
stats = (struct net_device_stats *)dev_get_stats(skb->dev);
|
||||
if (stats) {
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += skb->len;
|
||||
}
|
||||
|
||||
batman_packet = (struct batman_packet *)skb->data;
|
||||
|
||||
if (batman_packet->version != COMPAT_VERSION) {
|
||||
bat_dbg(DBG_BATMAN,
|
||||
"Drop packet: incompatible batman version (%i)\n",
|
||||
batman_packet->version);
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
/* all receive handlers return whether they received or reused
|
||||
* the supplied skb. if not, we have to free the skb. */
|
||||
|
||||
switch (batman_packet->packet_type) {
|
||||
/* batman originator packet */
|
||||
case BAT_PACKET:
|
||||
ret = recv_bat_packet(skb, batman_if);
|
||||
break;
|
||||
|
||||
/* batman icmp packet */
|
||||
case BAT_ICMP:
|
||||
ret = recv_icmp_packet(skb);
|
||||
break;
|
||||
|
||||
/* unicast packet */
|
||||
case BAT_UNICAST:
|
||||
ret = recv_unicast_packet(skb);
|
||||
break;
|
||||
|
||||
/* broadcast packet */
|
||||
case BAT_BCAST:
|
||||
ret = recv_bcast_packet(skb);
|
||||
break;
|
||||
|
||||
/* vis packet */
|
||||
case BAT_VIS:
|
||||
ret = recv_vis_packet(skb);
|
||||
break;
|
||||
default:
|
||||
ret = NET_RX_DROP;
|
||||
}
|
||||
|
||||
if (ret == NET_RX_DROP)
|
||||
kfree_skb(skb);
|
||||
|
||||
/* return NET_RX_SUCCESS in any case as we
|
||||
* most probably dropped the packet for
|
||||
* routing-logical reasons. */
|
||||
|
||||
return NET_RX_SUCCESS;
|
||||
|
||||
err_free:
|
||||
kfree_skb(skb);
|
||||
err_out:
|
||||
return NET_RX_DROP;
|
||||
}
|
||||
|
||||
|
||||
struct notifier_block hard_if_notifier = {
|
||||
.notifier_call = hard_if_event,
|
||||
.notifier_call = hard_if_event,
|
||||
};
|
||||
|
|
|
@ -32,5 +32,9 @@ void hardif_deactivate_interface(struct batman_if *batman_if);
|
|||
char hardif_get_active_if_num(void);
|
||||
void hardif_check_interfaces_status(void);
|
||||
void hardif_check_interfaces_status_wq(struct work_struct *work);
|
||||
int batman_skb_recv(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
struct packet_type *ptype,
|
||||
struct net_device *orig_dev);
|
||||
int hardif_min_mtu(void);
|
||||
void update_min_mtu(void);
|
||||
|
|
|
@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *hash)
|
|||
kfree(hash);
|
||||
}
|
||||
|
||||
/* iterate though the hash. first element is selected with iter_in NULL. use
|
||||
* the returned iterator to access the elements until hash_it_t returns NULL. */
|
||||
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
|
||||
struct hash_it_t *iter_in)
|
||||
{
|
||||
struct hash_it_t *iter;
|
||||
/* iterate though the hash. First element is selected if an iterator
|
||||
* initialized with HASHIT() is supplied as iter. Use the returned
|
||||
* (or supplied) iterator to access the elements until hash_iterate returns
|
||||
* NULL. */
|
||||
|
||||
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
|
||||
struct hash_it_t *iter)
|
||||
{
|
||||
if (!hash)
|
||||
return NULL;
|
||||
|
||||
if (iter_in == NULL) {
|
||||
iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
|
||||
iter->index = -1;
|
||||
iter->bucket = NULL;
|
||||
iter->prev_bucket = NULL;
|
||||
} else {
|
||||
iter = iter_in;
|
||||
}
|
||||
if (!iter)
|
||||
return NULL;
|
||||
|
||||
/* sanity checks first (if our bucket got deleted in the last
|
||||
* iteration): */
|
||||
|
@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash,
|
|||
}
|
||||
|
||||
/* nothing to iterate over anymore */
|
||||
kfree(iter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
|
||||
#ifndef _BATMAN_HASH_H
|
||||
#define _BATMAN_HASH_H
|
||||
#define HASHIT(name) struct hash_it_t name = { \
|
||||
.index = -1, .bucket = NULL, \
|
||||
.prev_bucket = NULL, \
|
||||
.first_bucket = NULL }
|
||||
|
||||
|
||||
typedef int (*hashdata_compare_cb)(void *, void *);
|
||||
typedef int (*hashdata_choose_cb)(void *, int);
|
||||
|
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 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 "log.h"
|
||||
|
||||
#define LOG_BUF_MASK (log_buf_len-1)
|
||||
#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
|
||||
|
||||
static char log_buf[LOG_BUF_LEN];
|
||||
static int log_buf_len = LOG_BUF_LEN;
|
||||
static unsigned long log_start;
|
||||
static unsigned long log_end;
|
||||
uint8_t log_level;
|
||||
|
||||
static DEFINE_SPINLOCK(logbuf_lock);
|
||||
|
||||
const struct file_operations proc_log_operations = {
|
||||
.open = log_open,
|
||||
.release = log_release,
|
||||
.read = log_read,
|
||||
.write = log_write,
|
||||
.poll = log_poll,
|
||||
};
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(log_wait);
|
||||
|
||||
static void emit_log_char(char c)
|
||||
{
|
||||
LOG_BUF(log_end) = c;
|
||||
log_end++;
|
||||
|
||||
if (log_end - log_start > log_buf_len)
|
||||
log_start = log_end - log_buf_len;
|
||||
}
|
||||
|
||||
static int fdebug_log(char *fmt, ...)
|
||||
{
|
||||
int printed_len;
|
||||
char *p;
|
||||
va_list args;
|
||||
static char debug_log_buf[256];
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&logbuf_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(*p);
|
||||
|
||||
spin_unlock_irqrestore(&logbuf_lock, flags);
|
||||
|
||||
wake_up(&log_wait);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int debug_log(int type, char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval = 0;
|
||||
char tmp_log_buf[256];
|
||||
|
||||
/* only critical information get into the official kernel log */
|
||||
if (type == LOG_TYPE_CRIT) {
|
||||
va_start(args, fmt);
|
||||
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
|
||||
printk(KERN_ERR "batman-adv: %s", tmp_log_buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
if ((type == LOG_TYPE_CRIT) || (log_level & type)) {
|
||||
va_start(args, fmt);
|
||||
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
|
||||
fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int log_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
inc_module_count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int log_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
dec_module_count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t log_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
int error, i = 0;
|
||||
char c;
|
||||
unsigned long flags;
|
||||
|
||||
if ((file->f_flags & O_NONBLOCK) && !(log_end - 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(log_wait, (log_start - log_end));
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
spin_lock_irqsave(&logbuf_lock, flags);
|
||||
|
||||
while ((!error) && (log_start != log_end) && (i < count)) {
|
||||
c = LOG_BUF(log_start);
|
||||
|
||||
log_start++;
|
||||
|
||||
spin_unlock_irqrestore(&logbuf_lock, flags);
|
||||
|
||||
error = __put_user(c, buf);
|
||||
|
||||
spin_lock_irqsave(&logbuf_lock, flags);
|
||||
|
||||
buf++;
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&logbuf_lock, flags);
|
||||
|
||||
if (!error)
|
||||
return i;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ssize_t log_write(struct file *file, const char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned int log_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
poll_wait(file, &log_wait, wait);
|
||||
|
||||
if (log_end - log_start)
|
||||
return POLLIN | POLLRDNORM;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include "main.h"
|
||||
#include "proc.h"
|
||||
#include "log.h"
|
||||
#include "routing.h"
|
||||
#include "send.h"
|
||||
#include "originator.h"
|
||||
#include "soft-interface.h"
|
||||
#include "device.h"
|
||||
#include "translation-table.h"
|
||||
|
@ -31,7 +31,6 @@
|
|||
#include "types.h"
|
||||
#include "vis.h"
|
||||
#include "hash.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct list_head if_list;
|
||||
struct hlist_head forw_bat_list;
|
||||
|
@ -44,19 +43,34 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
|
|||
|
||||
atomic_t originator_interval;
|
||||
atomic_t vis_interval;
|
||||
atomic_t vis_mode;
|
||||
atomic_t aggregation_enabled;
|
||||
int16_t num_hna;
|
||||
int16_t num_ifs;
|
||||
|
||||
struct net_device *soft_device;
|
||||
|
||||
static struct task_struct *kthread_task;
|
||||
|
||||
unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
atomic_t module_state;
|
||||
|
||||
static struct packet_type batman_adv_packet_type __read_mostly = {
|
||||
.type = __constant_htons(ETH_P_BATMAN),
|
||||
.func = batman_skb_recv,
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
int retval;
|
||||
|
@ -70,6 +84,7 @@ int init_module(void)
|
|||
atomic_set(&originator_interval, 1000);
|
||||
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
|
||||
* for debugging now. */
|
||||
atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
|
||||
atomic_set(&aggregation_enabled, 1);
|
||||
|
||||
/* the name should not be longer than 10 chars - see
|
||||
|
@ -90,21 +105,22 @@ int init_module(void)
|
|||
interface_setup);
|
||||
|
||||
if (!soft_device) {
|
||||
debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n");
|
||||
printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
retval = register_netdev(soft_device);
|
||||
|
||||
if (retval < 0) {
|
||||
debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval);
|
||||
printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval);
|
||||
goto free_soft_device;
|
||||
}
|
||||
|
||||
register_netdevice_notifier(&hard_if_notifier);
|
||||
dev_add_pack(&batman_adv_packet_type);
|
||||
|
||||
debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
|
||||
SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -124,6 +140,8 @@ void cleanup_module(void)
|
|||
soft_device = NULL;
|
||||
}
|
||||
|
||||
dev_remove_pack(&batman_adv_packet_type);
|
||||
|
||||
unregister_netdevice_notifier(&hard_if_notifier);
|
||||
cleanup_procfs();
|
||||
|
||||
|
@ -151,22 +169,12 @@ void activate_module(void)
|
|||
if (vis_init() < 1)
|
||||
goto err;
|
||||
|
||||
/* (re)start kernel thread for packet processing */
|
||||
if (!kthread_task) {
|
||||
kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv");
|
||||
|
||||
if (IS_ERR(kthread_task)) {
|
||||
debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n");
|
||||
kthread_task = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
update_min_mtu();
|
||||
atomic_set(&module_state, MODULE_ACTIVE);
|
||||
goto end;
|
||||
|
||||
err:
|
||||
debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n");
|
||||
printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n");
|
||||
shutdown_module();
|
||||
end:
|
||||
return;
|
||||
|
@ -182,14 +190,7 @@ void shutdown_module(void)
|
|||
|
||||
vis_quit();
|
||||
|
||||
/* deactivate kernel thread for packet processing (if running) */
|
||||
if (kthread_task) {
|
||||
atomic_set(&exit_cond, 1);
|
||||
wake_up_interruptible(&thread_wait);
|
||||
kthread_stop(kthread_task);
|
||||
|
||||
kthread_task = NULL;
|
||||
}
|
||||
/* TODO: unregister BATMAN pack */
|
||||
|
||||
originator_free();
|
||||
|
||||
|
|
|
@ -33,16 +33,16 @@
|
|||
|
||||
#define TQ_MAX_VALUE 255
|
||||
#define JITTER 20
|
||||
#define TTL 50 /* Time To Live of broadcast messages */
|
||||
#define MAX_ADDR 16 /* number of interfaces which can be added to
|
||||
#define TTL 50 /* Time To Live of broadcast messages */
|
||||
#define MAX_ADDR 16 /* number of interfaces which can be added to
|
||||
* batman. */
|
||||
|
||||
#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no
|
||||
#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no
|
||||
* valid packet comes in -> TODO: check
|
||||
* influence on TQ_LOCAL_WINDOW_SIZE */
|
||||
#define LOCAL_HNA_TIMEOUT 3600000
|
||||
|
||||
#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
|
||||
#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
|
||||
* messages in squence numbers (should be a
|
||||
* multiple of our word size) */
|
||||
#define TQ_GLOBAL_WINDOW_SIZE 5
|
||||
|
@ -69,24 +69,27 @@
|
|||
|
||||
|
||||
/*
|
||||
* Logging
|
||||
* Debug Messages
|
||||
*/
|
||||
|
||||
#define LOG_TYPE_CRIT 0 /* highest priority for fatal errors such as
|
||||
* blocked sockets / failed packet delivery /
|
||||
* programming errors */
|
||||
#define LOG_TYPE_WARN 1 /* warnings for small errors like wrong user
|
||||
* input / damaged packets / etc */
|
||||
#define LOG_TYPE_NOTICE 2 /* notice information for new interfaces /
|
||||
* changed settings / new originators / etc */
|
||||
#define LOG_TYPE_BATMAN 4 /* all messages related to routing / flooding /
|
||||
* broadcasting / etc */
|
||||
#define LOG_TYPE_ROUTES 8 /* route or hna added / changed / deleted */
|
||||
#define LOG_TYPE_CRIT_NAME "critical"
|
||||
#define LOG_TYPE_WARN_NAME "warnings"
|
||||
#define LOG_TYPE_NOTICE_NAME "notices"
|
||||
#define LOG_TYPE_BATMAN_NAME "batman"
|
||||
#define LOG_TYPE_ROUTES_NAME "routes"
|
||||
#define DBG_BATMAN 1 /* all messages related to routing / flooding /
|
||||
* broadcasting / etc */
|
||||
#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||
extern int debug;
|
||||
|
||||
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
|
||||
|
@ -127,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock;
|
|||
|
||||
extern atomic_t originator_interval;
|
||||
extern atomic_t vis_interval;
|
||||
extern atomic_t vis_mode;
|
||||
extern atomic_t aggregation_enabled;
|
||||
extern int16_t num_hna;
|
||||
extern int16_t num_ifs;
|
||||
|
@ -147,5 +151,3 @@ 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);
|
||||
|
||||
|
||||
|
|
252
drivers/staging/batman-adv/originator.c
Normal file
252
drivers/staging/batman-adv/originator.c
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (C) 2009 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* increase the reference counter for this originator */
|
||||
|
||||
#include "main.h"
|
||||
#include "originator.h"
|
||||
#include "hash.h"
|
||||
#include "translation-table.h"
|
||||
#include "routing.h"
|
||||
|
||||
static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
|
||||
|
||||
static void start_purge_timer(void)
|
||||
{
|
||||
queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
|
||||
}
|
||||
|
||||
int originator_init(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
if (orig_hash)
|
||||
return 1;
|
||||
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
orig_hash = hash_new(128, compare_orig, choose_orig);
|
||||
|
||||
if (!orig_hash)
|
||||
goto err;
|
||||
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
start_purge_timer();
|
||||
return 1;
|
||||
|
||||
err:
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
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)
|
||||
{
|
||||
struct neigh_node *neigh_node;
|
||||
|
||||
bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
|
||||
|
||||
neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
|
||||
if (!neigh_node)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&neigh_node->list);
|
||||
|
||||
memcpy(neigh_node->addr, neigh, ETH_ALEN);
|
||||
neigh_node->orig_node = orig_neigh_node;
|
||||
neigh_node->if_incoming = if_incoming;
|
||||
|
||||
list_add_tail(&neigh_node->list, &orig_node->neigh_list);
|
||||
return neigh_node;
|
||||
}
|
||||
|
||||
void free_orig_node(void *data)
|
||||
{
|
||||
struct list_head *list_pos, *list_pos_tmp;
|
||||
struct neigh_node *neigh_node;
|
||||
struct orig_node *orig_node = (struct orig_node *)data;
|
||||
|
||||
/* for all neighbors towards this originator ... */
|
||||
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
|
||||
neigh_node = list_entry(list_pos, struct neigh_node, list);
|
||||
|
||||
list_del(list_pos);
|
||||
kfree(neigh_node);
|
||||
}
|
||||
|
||||
hna_global_del_orig(orig_node, "originator timed out");
|
||||
|
||||
kfree(orig_node->bcast_own);
|
||||
kfree(orig_node->bcast_own_sum);
|
||||
kfree(orig_node);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct orig_node *orig_node;
|
||||
struct hashtable_t *swaphash;
|
||||
int size;
|
||||
|
||||
orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
|
||||
|
||||
if (orig_node != NULL)
|
||||
return orig_node;
|
||||
|
||||
bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr);
|
||||
|
||||
orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
|
||||
if (!orig_node)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&orig_node->neigh_list);
|
||||
|
||||
memcpy(orig_node->orig, addr, ETH_ALEN);
|
||||
orig_node->router = NULL;
|
||||
orig_node->batman_if = NULL;
|
||||
orig_node->hna_buff = NULL;
|
||||
|
||||
size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
|
||||
|
||||
orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
|
||||
if (!orig_node->bcast_own)
|
||||
goto free_orig_node;
|
||||
|
||||
size = num_ifs * sizeof(uint8_t);
|
||||
orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
|
||||
if (!orig_node->bcast_own_sum)
|
||||
goto free_bcast_own;
|
||||
|
||||
if (hash_add(orig_hash, orig_node) < 0)
|
||||
goto free_bcast_own_sum;
|
||||
|
||||
if (orig_hash->elements * 4 > orig_hash->size) {
|
||||
swaphash = hash_resize(orig_hash, orig_hash->size * 2);
|
||||
|
||||
if (swaphash == NULL)
|
||||
printk(KERN_ERR
|
||||
"batman-adv:Couldn't resize orig hash table \n");
|
||||
else
|
||||
orig_hash = swaphash;
|
||||
}
|
||||
|
||||
return orig_node;
|
||||
free_bcast_own_sum:
|
||||
kfree(orig_node->bcast_own_sum);
|
||||
free_bcast_own:
|
||||
kfree(orig_node->bcast_own);
|
||||
free_orig_node:
|
||||
kfree(orig_node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool purge_orig_neighbors(struct orig_node *orig_node,
|
||||
struct neigh_node **best_neigh_node)
|
||||
{
|
||||
struct list_head *list_pos, *list_pos_tmp;
|
||||
struct neigh_node *neigh_node;
|
||||
bool neigh_purged = false;
|
||||
|
||||
*best_neigh_node = NULL;
|
||||
|
||||
|
||||
/* for all neighbors towards this originator ... */
|
||||
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
|
||||
neigh_node = list_entry(list_pos, struct neigh_node, list);
|
||||
|
||||
if (time_after(jiffies,
|
||||
(neigh_node->last_valid +
|
||||
((PURGE_TIMEOUT * HZ) / 1000)))) {
|
||||
|
||||
bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ));
|
||||
|
||||
neigh_purged = true;
|
||||
list_del(list_pos);
|
||||
kfree(neigh_node);
|
||||
} else {
|
||||
if ((*best_neigh_node == NULL) ||
|
||||
(neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
|
||||
*best_neigh_node = neigh_node;
|
||||
}
|
||||
}
|
||||
return neigh_purged;
|
||||
}
|
||||
|
||||
|
||||
static bool purge_orig_node(struct orig_node *orig_node)
|
||||
{
|
||||
struct neigh_node *best_neigh_node;
|
||||
|
||||
if (time_after(jiffies,
|
||||
(orig_node->last_valid +
|
||||
((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
|
||||
|
||||
bat_dbg(DBG_BATMAN,
|
||||
"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))
|
||||
update_routes(orig_node, best_neigh_node,
|
||||
orig_node->hna_buff,
|
||||
orig_node->hna_buff_len);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void purge_orig(struct work_struct *work)
|
||||
{
|
||||
HASHIT(hashit);
|
||||
struct orig_node *orig_node;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
|
||||
/* for all origins... */
|
||||
while (hash_iterate(orig_hash, &hashit)) {
|
||||
orig_node = hashit.bucket->data;
|
||||
if (purge_orig_node(orig_node)) {
|
||||
hash_remove_bucket(orig_hash, &hashit);
|
||||
free_orig_node(orig_node);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
|
||||
start_purge_timer();
|
||||
}
|
||||
|
||||
|
|
@ -19,14 +19,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
extern const struct file_operations proc_log_operations;
|
||||
extern uint8_t log_level;
|
||||
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);
|
||||
|
||||
int debug_log(int type, char *fmt, ...);
|
||||
int log_open(struct inode *inode, struct file *file);
|
||||
int log_release(struct inode *inode, struct file *file);
|
||||
ssize_t log_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos);
|
||||
ssize_t log_write(struct file *file, const char __user *buf, size_t count,
|
||||
loff_t *ppos);
|
||||
unsigned int log_poll(struct file *file, poll_table *wait);
|
|
@ -90,7 +90,7 @@ struct vis_packet {
|
|||
uint8_t entries; /* number of entries behind this struct */
|
||||
uint8_t ttl; /* TTL */
|
||||
uint8_t vis_orig[6]; /* originator that informs about its
|
||||
* neighbours */
|
||||
* neighbors */
|
||||
uint8_t target_orig[6]; /* who should receive this packet */
|
||||
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
|
||||
} __attribute__((packed));
|
||||
|
|
|
@ -21,23 +21,18 @@
|
|||
|
||||
#include "main.h"
|
||||
#include "proc.h"
|
||||
#include "log.h"
|
||||
#include "routing.h"
|
||||
#include "translation-table.h"
|
||||
#include "hard-interface.h"
|
||||
#include "types.h"
|
||||
#include "hash.h"
|
||||
#include "vis.h"
|
||||
#include "compat.h"
|
||||
|
||||
static uint8_t vis_format = DOT_DRAW;
|
||||
|
||||
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
|
||||
static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
|
||||
static struct proc_dir_entry *proc_log_file, *proc_log_level_file;
|
||||
static struct proc_dir_entry *proc_transt_local_file;
|
||||
static struct proc_dir_entry *proc_transt_global_file;
|
||||
static struct proc_dir_entry *proc_vis_file, *proc_vis_format_file;
|
||||
static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
|
||||
static struct proc_dir_entry *proc_aggr_file;
|
||||
|
||||
static int proc_interfaces_read(struct seq_file *seq, void *offset)
|
||||
|
@ -68,7 +63,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
|
|||
size_t count, loff_t *data)
|
||||
{
|
||||
char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
|
||||
int not_copied = 0, if_num = 0;
|
||||
int not_copied = 0, if_num = 0, add_success;
|
||||
struct batman_if *batman_if = NULL;
|
||||
|
||||
if_string = kmalloc(count, GFP_KERNEL);
|
||||
|
@ -77,8 +72,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
|
|||
return -ENOMEM;
|
||||
|
||||
if (count > IFNAMSIZ - 1) {
|
||||
debug_log(LOG_TYPE_WARN,
|
||||
"Can't add interface: device name is too long\n");
|
||||
printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -105,7 +99,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
|
|||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
||||
if (strncmp(batman_if->dev, if_string, count) == 0) {
|
||||
debug_log(LOG_TYPE_WARN, "Given interface is already active: %s\n", if_string);
|
||||
printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string);
|
||||
rcu_read_unlock();
|
||||
goto end;
|
||||
|
||||
|
@ -115,22 +109,17 @@ static ssize_t proc_interfaces_write(struct file *instance,
|
|||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
hardif_add_interface(if_string, if_num);
|
||||
add_success = hardif_add_interface(if_string, if_num);
|
||||
if (add_success < 0)
|
||||
goto end;
|
||||
|
||||
num_ifs = if_num + 1;
|
||||
|
||||
if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
|
||||
(hardif_get_active_if_num() > 0))
|
||||
activate_module();
|
||||
|
||||
rcu_read_lock();
|
||||
if (list_empty(&if_list)) {
|
||||
rcu_read_unlock();
|
||||
goto end;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
num_ifs = if_num + 1;
|
||||
return count;
|
||||
|
||||
end:
|
||||
kfree(if_string);
|
||||
return count;
|
||||
|
@ -162,20 +151,18 @@ static ssize_t proc_orig_interval_write(struct file *file,
|
|||
|
||||
retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
|
||||
if (retval) {
|
||||
debug_log(LOG_TYPE_WARN, "New originator interval invalid\n");
|
||||
printk(KERN_ERR "batman-adv:New originator interval invalid\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (originator_interval_tmp <= JITTER * 2) {
|
||||
debug_log(LOG_TYPE_WARN,
|
||||
"New originator interval too small: %i (min: %i)\n",
|
||||
originator_interval_tmp, JITTER * 2);
|
||||
printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n",
|
||||
originator_interval_tmp, JITTER * 2);
|
||||
goto end;
|
||||
}
|
||||
|
||||
debug_log(LOG_TYPE_NOTICE,
|
||||
"Changing originator interval from: %i to: %i\n",
|
||||
atomic_read(&originator_interval), originator_interval_tmp);
|
||||
printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n",
|
||||
atomic_read(&originator_interval), originator_interval_tmp);
|
||||
|
||||
atomic_set(&originator_interval, originator_interval_tmp);
|
||||
|
||||
|
@ -191,11 +178,12 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file)
|
|||
|
||||
static int proc_originators_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
struct orig_node *orig_node;
|
||||
struct neigh_node *neigh_node;
|
||||
int batman_count = 0;
|
||||
char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
|
||||
unsigned long flags;
|
||||
|
||||
rcu_read_lock();
|
||||
if (list_empty(&if_list)) {
|
||||
|
@ -218,11 +206,11 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
|
|||
((struct batman_if *)if_list.next)->addr_str);
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_lock(&orig_hash_lock);
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
|
||||
while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
|
||||
while (hash_iterate(orig_hash, &hashit)) {
|
||||
|
||||
orig_node = hashit->bucket->data;
|
||||
orig_node = hashit.bucket->data;
|
||||
|
||||
if (!orig_node->router)
|
||||
continue;
|
||||
|
@ -249,7 +237,7 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
|
|||
|
||||
}
|
||||
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
|
||||
if (batman_count == 0)
|
||||
seq_printf(seq, "No batman nodes in range ... \n");
|
||||
|
@ -263,84 +251,6 @@ static int proc_originators_open(struct inode *inode, struct file *file)
|
|||
return single_open(file, proc_originators_read, NULL);
|
||||
}
|
||||
|
||||
static int proc_log_level_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
|
||||
seq_printf(seq, "[x] %s (%d)\n", LOG_TYPE_CRIT_NAME, LOG_TYPE_CRIT);
|
||||
seq_printf(seq, "[%c] %s (%d)\n",
|
||||
(LOG_TYPE_WARN & log_level) ? 'x' : ' ',
|
||||
LOG_TYPE_WARN_NAME, LOG_TYPE_WARN);
|
||||
seq_printf(seq, "[%c] %s (%d)\n",
|
||||
(LOG_TYPE_NOTICE & log_level) ? 'x' : ' ',
|
||||
LOG_TYPE_NOTICE_NAME, LOG_TYPE_NOTICE);
|
||||
seq_printf(seq, "[%c] %s (%d)\n",
|
||||
(LOG_TYPE_BATMAN & log_level) ? 'x' : ' ',
|
||||
LOG_TYPE_BATMAN_NAME, LOG_TYPE_BATMAN);
|
||||
seq_printf(seq, "[%c] %s (%d)\n",
|
||||
(LOG_TYPE_ROUTES & log_level) ? 'x' : ' ',
|
||||
LOG_TYPE_ROUTES_NAME, LOG_TYPE_ROUTES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_log_level_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, proc_log_level_read, NULL);
|
||||
}
|
||||
|
||||
static ssize_t proc_log_level_write(struct file *instance,
|
||||
const char __user *userbuffer,
|
||||
size_t count, loff_t *data)
|
||||
{
|
||||
char *log_level_string, *tokptr, *cp;
|
||||
int finished, not_copied = 0;
|
||||
unsigned long log_level_tmp = 0;
|
||||
|
||||
log_level_string = kmalloc(count, GFP_KERNEL);
|
||||
|
||||
if (!log_level_string)
|
||||
return -ENOMEM;
|
||||
|
||||
not_copied = copy_from_user(log_level_string, userbuffer, count);
|
||||
log_level_string[count - not_copied - 1] = 0;
|
||||
|
||||
if (strict_strtoul(log_level_string, 10, &log_level_tmp) < 0) {
|
||||
/* was not a number, doing textual parsing */
|
||||
log_level_tmp = 0;
|
||||
tokptr = log_level_string;
|
||||
|
||||
for (cp = log_level_string, finished = 0; !finished; cp++) {
|
||||
switch (*cp) {
|
||||
case 0:
|
||||
finished = 1;
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\t':
|
||||
*cp = 0;
|
||||
/* compare */
|
||||
if (strcmp(tokptr, LOG_TYPE_WARN_NAME) == 0)
|
||||
log_level_tmp |= LOG_TYPE_WARN;
|
||||
if (strcmp(tokptr, LOG_TYPE_NOTICE_NAME) == 0)
|
||||
log_level_tmp |= LOG_TYPE_NOTICE;
|
||||
if (strcmp(tokptr, LOG_TYPE_BATMAN_NAME) == 0)
|
||||
log_level_tmp |= LOG_TYPE_BATMAN;
|
||||
if (strcmp(tokptr, LOG_TYPE_ROUTES_NAME) == 0)
|
||||
log_level_tmp |= LOG_TYPE_ROUTES;
|
||||
tokptr = cp + 1;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_log(LOG_TYPE_CRIT, "Changing log_level from: %i to: %i\n",
|
||||
log_level, log_level_tmp);
|
||||
log_level = log_level_tmp;
|
||||
|
||||
kfree(log_level_string);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int proc_transt_local_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
char *buf;
|
||||
|
@ -405,172 +315,8 @@ static int proc_transt_global_open(struct inode *inode, struct file *file)
|
|||
return single_open(file, proc_transt_global_read, NULL);
|
||||
}
|
||||
|
||||
/* insert interface to the list of interfaces of one originator */
|
||||
|
||||
static void proc_vis_insert_interface(const uint8_t *interface,
|
||||
struct vis_if_list **if_entry,
|
||||
bool primary)
|
||||
{
|
||||
/* Did we get an empty list? (then insert imediately) */
|
||||
if(*if_entry == NULL) {
|
||||
*if_entry = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
|
||||
if (*if_entry == NULL)
|
||||
return;
|
||||
|
||||
(*if_entry)->primary = primary;
|
||||
(*if_entry)->next = NULL;
|
||||
memcpy((*if_entry)->addr, interface, ETH_ALEN);
|
||||
} else {
|
||||
struct vis_if_list *head_if_entry = *if_entry;
|
||||
/* Do we already have this interface in our list? */
|
||||
while (!compare_orig((*if_entry)->addr, (void *)interface)) {
|
||||
|
||||
/* Or did we reach the end (then append the interface) */
|
||||
if ((*if_entry)->next == NULL) {
|
||||
(*if_entry)->next = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
|
||||
if ((*if_entry)->next == NULL)
|
||||
return;
|
||||
|
||||
memcpy((*if_entry)->next->addr, interface, ETH_ALEN);
|
||||
(*if_entry)->next->primary = primary;
|
||||
(*if_entry)->next->next = NULL;
|
||||
break;
|
||||
}
|
||||
*if_entry = (*if_entry)->next;
|
||||
}
|
||||
/* Rewind the list to its head */
|
||||
*if_entry = head_if_entry;
|
||||
}
|
||||
}
|
||||
/* read an entry */
|
||||
|
||||
static void proc_vis_read_entry(struct seq_file *seq,
|
||||
struct vis_info_entry *entry,
|
||||
struct vis_if_list **if_entry,
|
||||
uint8_t *vis_orig,
|
||||
uint8_t current_format,
|
||||
uint8_t first_line)
|
||||
{
|
||||
char from[40];
|
||||
char to[40];
|
||||
int int_part, frac_part;
|
||||
|
||||
addr_to_string(to, entry->dest);
|
||||
if (entry->quality == 0) {
|
||||
#ifndef VIS_SUBCLUSTERS_DISABLED
|
||||
proc_vis_insert_interface(vis_orig, if_entry, true);
|
||||
#endif /* VIS_SUBCLUSTERS_DISABLED */
|
||||
addr_to_string(from, vis_orig);
|
||||
if (current_format == DOT_DRAW) {
|
||||
seq_printf(seq, "\t\"%s\" -> \"%s\" [label=\"HNA\"]\n",
|
||||
from, to);
|
||||
} else {
|
||||
seq_printf(seq,
|
||||
"%s\t{ router : \"%s\", gateway : \"%s\", label : \"HNA\" }",
|
||||
(first_line ? "" : ",\n"), from, to);
|
||||
}
|
||||
} else {
|
||||
#ifndef VIS_SUBCLUSTERS_DISABLED
|
||||
proc_vis_insert_interface(entry->src, if_entry, compare_orig(entry->src, vis_orig));
|
||||
#endif /* VIS_SUBCLUSTERS_DISABLED */
|
||||
addr_to_string(from, entry->src);
|
||||
|
||||
/* kernel has no printf-support for %f? it'd be better to return
|
||||
* this in float. */
|
||||
|
||||
int_part = TQ_MAX_VALUE / entry->quality;
|
||||
frac_part = 1000 * TQ_MAX_VALUE / entry->quality - int_part * 1000;
|
||||
|
||||
if (current_format == DOT_DRAW) {
|
||||
seq_printf(seq,
|
||||
"\t\"%s\" -> \"%s\" [label=\"%d.%d\"]\n",
|
||||
from, to, int_part, frac_part);
|
||||
} else {
|
||||
seq_printf(seq,
|
||||
"%s\t{ router : \"%s\", neighbour : \"%s\", label : %d.%d }",
|
||||
(first_line ? "" : ",\n"), from, to, int_part, frac_part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int proc_vis_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct hash_it_t *hashit = NULL;
|
||||
struct vis_info *info;
|
||||
struct vis_info_entry *entries;
|
||||
struct vis_if_list *if_entries = NULL;
|
||||
int i;
|
||||
uint8_t current_format, first_line = 1;
|
||||
#ifndef VIS_SUBCLUSTERS_DISABLED
|
||||
char tmp_addr_str[ETH_STR_LEN];
|
||||
struct vis_if_list *tmp_if_next;
|
||||
#endif /* VIS_SUBCLUSTERS_DISABLED */
|
||||
|
||||
current_format = vis_format;
|
||||
|
||||
rcu_read_lock();
|
||||
if (list_empty(&if_list) || (!is_vis_server())) {
|
||||
rcu_read_unlock();
|
||||
if (current_format == DOT_DRAW)
|
||||
seq_printf(seq, "digraph {\n}\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (current_format == DOT_DRAW)
|
||||
seq_printf(seq, "digraph {\n");
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
|
||||
info = hashit->bucket->data;
|
||||
entries = (struct vis_info_entry *)
|
||||
((char *)info + sizeof(struct vis_info));
|
||||
|
||||
for (i = 0; i < info->packet.entries; i++) {
|
||||
proc_vis_read_entry(seq, &entries[i], &if_entries,
|
||||
info->packet.vis_orig,
|
||||
current_format, first_line);
|
||||
if (first_line)
|
||||
first_line = 0;
|
||||
}
|
||||
|
||||
#ifndef VIS_SUBCLUSTERS_DISABLED
|
||||
/* Generate subgraphs from the collected items */
|
||||
if (current_format == DOT_DRAW) {
|
||||
|
||||
addr_to_string(tmp_addr_str, info->packet.vis_orig);
|
||||
seq_printf(seq, "\tsubgraph \"cluster_%s\" {\n", tmp_addr_str);
|
||||
while (if_entries != NULL) {
|
||||
|
||||
addr_to_string(tmp_addr_str, if_entries->addr);
|
||||
if (if_entries->primary)
|
||||
seq_printf(seq, "\t\t\"%s\" [peripheries=2]\n", tmp_addr_str);
|
||||
else
|
||||
seq_printf(seq, "\t\t\"%s\"\n", tmp_addr_str);
|
||||
|
||||
/* ... and empty the list while doing this */
|
||||
tmp_if_next = if_entries->next;
|
||||
kfree(if_entries);
|
||||
if_entries = tmp_if_next;
|
||||
}
|
||||
seq_printf(seq, "\t}\n");
|
||||
}
|
||||
#endif /* VIS_SUBCLUSTERS_DISABLED */
|
||||
}
|
||||
spin_unlock(&vis_hash_lock);
|
||||
|
||||
if (current_format == DOT_DRAW)
|
||||
seq_printf(seq, "}\n");
|
||||
else
|
||||
seq_printf(seq, "\n");
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setting the mode of the vis server by the user */
|
||||
static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
|
||||
static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char *vis_mode_string;
|
||||
|
@ -584,72 +330,84 @@ static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
|
|||
not_copied = copy_from_user(vis_mode_string, buffer, count);
|
||||
vis_mode_string[count - not_copied - 1] = 0;
|
||||
|
||||
if (strcmp(vis_mode_string, "client") == 0) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n");
|
||||
vis_set_mode(VIS_TYPE_CLIENT_UPDATE);
|
||||
} else if (strcmp(vis_mode_string, "server") == 0) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n");
|
||||
vis_set_mode(VIS_TYPE_SERVER_SYNC);
|
||||
if ((strcmp(vis_mode_string, "client") == 0) ||
|
||||
(strcmp(vis_mode_string, "disabled") == 0)) {
|
||||
printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n");
|
||||
atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
|
||||
} else if ((strcmp(vis_mode_string, "server") == 0) ||
|
||||
(strcmp(vis_mode_string, "enabled") == 0)) {
|
||||
printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n");
|
||||
atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC);
|
||||
} else
|
||||
debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n",
|
||||
vis_mode_string);
|
||||
printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
|
||||
vis_mode_string);
|
||||
|
||||
kfree(vis_mode_string);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int proc_vis_open(struct inode *inode, struct file *file)
|
||||
static int proc_vis_srv_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
return single_open(file, proc_vis_read, NULL);
|
||||
}
|
||||
int vis_server = atomic_read(&vis_mode);
|
||||
|
||||
static int proc_vis_format_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
uint8_t current_format = vis_format;
|
||||
seq_printf(seq, "[%c] client mode (server disabled) \n",
|
||||
(vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
|
||||
seq_printf(seq, "[%c] server mode (server enabled) \n",
|
||||
(vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
|
||||
|
||||
seq_printf(seq, "[%c] %s\n",
|
||||
(current_format == DOT_DRAW) ? 'x' : ' ',
|
||||
VIS_FORMAT_DD_NAME);
|
||||
seq_printf(seq, "[%c] %s\n",
|
||||
(current_format == JSON) ? 'x' : ' ',
|
||||
VIS_FORMAT_JSON_NAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_vis_format_open(struct inode *inode, struct file *file)
|
||||
static int proc_vis_srv_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, proc_vis_format_read, NULL);
|
||||
return single_open(file, proc_vis_srv_read, NULL);
|
||||
}
|
||||
|
||||
static ssize_t proc_vis_format_write(struct file *file,
|
||||
const char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
static int proc_vis_data_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
char *vis_format_string;
|
||||
int not_copied = 0;
|
||||
HASHIT(hashit);
|
||||
struct vis_info *info;
|
||||
struct vis_info_entry *entries;
|
||||
HLIST_HEAD(vis_if_list);
|
||||
int i;
|
||||
char tmp_addr_str[ETH_STR_LEN];
|
||||
unsigned long flags;
|
||||
int vis_server = atomic_read(&vis_mode);
|
||||
|
||||
vis_format_string = kmalloc(count, GFP_KERNEL);
|
||||
rcu_read_lock();
|
||||
if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
|
||||
rcu_read_unlock();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!vis_format_string)
|
||||
return -ENOMEM;
|
||||
rcu_read_unlock();
|
||||
|
||||
not_copied = copy_from_user(vis_format_string, buffer, count);
|
||||
vis_format_string[count - not_copied - 1] = 0;
|
||||
spin_lock_irqsave(&vis_hash_lock, flags);
|
||||
while (hash_iterate(vis_hash, &hashit)) {
|
||||
info = hashit.bucket->data;
|
||||
entries = (struct vis_info_entry *)
|
||||
((char *)info + sizeof(struct vis_info));
|
||||
addr_to_string(tmp_addr_str, info->packet.vis_orig);
|
||||
seq_printf(seq, "%s,", tmp_addr_str);
|
||||
|
||||
if (strcmp(vis_format_string, VIS_FORMAT_DD_NAME) == 0) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
|
||||
VIS_FORMAT_DD_NAME);
|
||||
vis_format = DOT_DRAW;
|
||||
} else if (strcmp(vis_format_string, VIS_FORMAT_JSON_NAME) == 0) {
|
||||
debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
|
||||
VIS_FORMAT_JSON_NAME);
|
||||
vis_format = JSON;
|
||||
} else
|
||||
debug_log(LOG_TYPE_WARN, "Unknown VIS output format: %s\n",
|
||||
vis_format_string);
|
||||
for (i = 0; i < info->packet.entries; i++) {
|
||||
proc_vis_read_entry(seq, &entries[i], &vis_if_list,
|
||||
info->packet.vis_orig);
|
||||
}
|
||||
|
||||
kfree(vis_format_string);
|
||||
return count;
|
||||
/* add primary/secondary records */
|
||||
proc_vis_read_prim_sec(seq, &vis_if_list);
|
||||
seq_printf(seq, "\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_vis_data_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, proc_vis_data_read, NULL);
|
||||
}
|
||||
|
||||
static int proc_aggr_read(struct seq_file *seq, void *offset)
|
||||
|
@ -665,6 +423,7 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
|
|||
char *aggr_string;
|
||||
int not_copied = 0;
|
||||
unsigned long aggregation_enabled_tmp;
|
||||
int retval;
|
||||
|
||||
aggr_string = kmalloc(count, GFP_KERNEL);
|
||||
|
||||
|
@ -674,22 +433,21 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
|
|||
not_copied = copy_from_user(aggr_string, buffer, count);
|
||||
aggr_string[count - not_copied - 1] = 0;
|
||||
|
||||
strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
|
||||
retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
|
||||
|
||||
if ((aggregation_enabled_tmp != 0) && (aggregation_enabled_tmp != 1)) {
|
||||
debug_log(LOG_TYPE_WARN, "Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
|
||||
goto end;
|
||||
if (retval || aggregation_enabled_tmp > 1) {
|
||||
printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
|
||||
} else {
|
||||
printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n",
|
||||
(atomic_read(&aggregation_enabled) == 1 ?
|
||||
"enabled" : "disabled"),
|
||||
atomic_read(&aggregation_enabled),
|
||||
(aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
|
||||
aggregation_enabled_tmp);
|
||||
atomic_set(&aggregation_enabled,
|
||||
(unsigned)aggregation_enabled_tmp);
|
||||
}
|
||||
|
||||
debug_log(LOG_TYPE_NOTICE, "Changing aggregation from: %s (%i) to: %s (%li)\n",
|
||||
(atomic_read(&aggregation_enabled) == 1 ?
|
||||
"enabled" : "disabled"),
|
||||
atomic_read(&aggregation_enabled),
|
||||
(aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
|
||||
aggregation_enabled_tmp);
|
||||
|
||||
atomic_set(&aggregation_enabled, (unsigned)aggregation_enabled_tmp);
|
||||
end:
|
||||
kfree(aggr_string);
|
||||
return count;
|
||||
}
|
||||
|
@ -715,20 +473,20 @@ static const struct file_operations proc_aggr_fops = {
|
|||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_vis_format_fops = {
|
||||
static const struct file_operations proc_vis_srv_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = proc_vis_format_open,
|
||||
.open = proc_vis_srv_open,
|
||||
.read = seq_read,
|
||||
.write = proc_vis_format_write,
|
||||
.write = proc_vis_srv_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_vis_fops = {
|
||||
static const struct file_operations proc_vis_data_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = proc_vis_open,
|
||||
.open = proc_vis_data_open,
|
||||
.read = seq_read,
|
||||
.write = proc_vis_write,
|
||||
.write = proc_dummy_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
@ -760,15 +518,6 @@ static const struct file_operations proc_transt_global_fops = {
|
|||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_log_level_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = proc_log_level_open,
|
||||
.read = seq_read,
|
||||
.write = proc_log_level_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_interfaces_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = proc_interfaces_open,
|
||||
|
@ -795,12 +544,6 @@ void cleanup_procfs(void)
|
|||
if (proc_transt_local_file)
|
||||
remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir);
|
||||
|
||||
if (proc_log_file)
|
||||
remove_proc_entry(PROC_FILE_LOG, proc_batman_dir);
|
||||
|
||||
if (proc_log_level_file)
|
||||
remove_proc_entry(PROC_FILE_LOG_LEVEL, proc_batman_dir);
|
||||
|
||||
if (proc_originators_file)
|
||||
remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
|
||||
|
||||
|
@ -810,11 +553,11 @@ void cleanup_procfs(void)
|
|||
if (proc_interface_file)
|
||||
remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
|
||||
|
||||
if (proc_vis_file)
|
||||
remove_proc_entry(PROC_FILE_VIS, proc_batman_dir);
|
||||
if (proc_vis_data_file)
|
||||
remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir);
|
||||
|
||||
if (proc_vis_format_file)
|
||||
remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir);
|
||||
if (proc_vis_srv_file)
|
||||
remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
|
||||
|
||||
if (proc_aggr_file)
|
||||
remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
|
||||
|
@ -862,17 +605,6 @@ int setup_procfs(void)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
proc_log_level_file = create_proc_entry(PROC_FILE_LOG_LEVEL,
|
||||
S_IWUSR | S_IRUGO,
|
||||
proc_batman_dir);
|
||||
if (proc_log_level_file) {
|
||||
proc_log_level_file->proc_fops = &proc_log_level_fops;
|
||||
} else {
|
||||
printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_LOG_LEVEL);
|
||||
cleanup_procfs();
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
|
||||
S_IRUGO, proc_batman_dir);
|
||||
if (proc_originators_file) {
|
||||
|
@ -883,16 +615,6 @@ int setup_procfs(void)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
proc_log_file = create_proc_entry(PROC_FILE_LOG,
|
||||
S_IRUGO, proc_batman_dir);
|
||||
if (proc_log_file) {
|
||||
proc_log_file->proc_fops = &proc_log_operations;
|
||||
} else {
|
||||
printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_FILE_LOG, PROC_FILE_GATEWAYS);
|
||||
cleanup_procfs();
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
|
||||
S_IRUGO, proc_batman_dir);
|
||||
if (proc_transt_local_file) {
|
||||
|
@ -913,23 +635,23 @@ int setup_procfs(void)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO,
|
||||
proc_batman_dir);
|
||||
if (proc_vis_file) {
|
||||
proc_vis_file->proc_fops = &proc_vis_fops;
|
||||
proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
|
||||
S_IWUSR | S_IRUGO,
|
||||
proc_batman_dir);
|
||||
if (proc_vis_srv_file) {
|
||||
proc_vis_srv_file->proc_fops = &proc_vis_srv_fops;
|
||||
} else {
|
||||
printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS);
|
||||
printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV);
|
||||
cleanup_procfs();
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT,
|
||||
S_IWUSR | S_IRUGO,
|
||||
proc_batman_dir);
|
||||
if (proc_vis_format_file) {
|
||||
proc_vis_format_file->proc_fops = &proc_vis_format_fops;
|
||||
proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO,
|
||||
proc_batman_dir);
|
||||
if (proc_vis_data_file) {
|
||||
proc_vis_data_file->proc_fops = &proc_vis_data_fops;
|
||||
} else {
|
||||
printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_FORMAT);
|
||||
printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA);
|
||||
cleanup_procfs();
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -946,5 +668,3 @@ int setup_procfs(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,19 +31,10 @@
|
|||
#define PROC_FILE_LOG_LEVEL "log_level"
|
||||
#define PROC_FILE_TRANST_LOCAL "transtable_local"
|
||||
#define PROC_FILE_TRANST_GLOBAL "transtable_global"
|
||||
#define PROC_FILE_VIS "vis"
|
||||
#define PROC_FILE_VIS_FORMAT "vis_format"
|
||||
#define PROC_FILE_VIS_SRV "vis_server"
|
||||
#define PROC_FILE_VIS_DATA "vis_data"
|
||||
#define PROC_FILE_AGGR "aggregate_ogm"
|
||||
|
||||
void cleanup_procfs(void);
|
||||
int setup_procfs(void);
|
||||
|
||||
/* While scanning for vis-entries of a particular vis-originator
|
||||
* this list collects its interfaces to create a subgraph/cluster
|
||||
* out of them later
|
||||
*/
|
||||
struct vis_if_list {
|
||||
uint8_t addr[ETH_ALEN];
|
||||
bool primary;
|
||||
struct vis_if_list *next;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,13 +22,18 @@
|
|||
#include "types.h"
|
||||
|
||||
extern wait_queue_head_t thread_wait;
|
||||
extern atomic_t exit_cond;
|
||||
|
||||
int originator_init(void);
|
||||
void free_orig_node(void *data);
|
||||
void originator_free(void);
|
||||
void slide_own_bcast_window(struct batman_if *batman_if);
|
||||
void batman_data_ready(struct sock *sk, int len);
|
||||
void purge_orig(struct work_struct *work);
|
||||
int packet_recv_thread(void *data);
|
||||
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);
|
||||
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);
|
||||
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_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);
|
||||
|
|
|
@ -21,16 +21,14 @@
|
|||
|
||||
#include "main.h"
|
||||
#include "send.h"
|
||||
#include "log.h"
|
||||
#include "routing.h"
|
||||
#include "translation-table.h"
|
||||
#include "soft-interface.h"
|
||||
#include "hard-interface.h"
|
||||
#include "types.h"
|
||||
#include "vis.h"
|
||||
#include "aggregation.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
/* apply hop penalty for a normal link */
|
||||
static uint8_t hop_penalty(const uint8_t tq)
|
||||
{
|
||||
|
@ -59,51 +57,69 @@ static unsigned long forward_send_time(void)
|
|||
return send_time;
|
||||
}
|
||||
|
||||
/* sends a raw packet. */
|
||||
void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
|
||||
struct batman_if *batman_if, uint8_t *dst_addr)
|
||||
/* send out an already prepared packet to the given address via the
|
||||
* specified batman interface */
|
||||
int send_skb_packet(struct sk_buff *skb,
|
||||
struct batman_if *batman_if,
|
||||
uint8_t *dst_addr)
|
||||
{
|
||||
struct ethhdr *ethhdr;
|
||||
struct sk_buff *skb;
|
||||
int retval;
|
||||
char *data;
|
||||
|
||||
if (batman_if->if_active != IF_ACTIVE)
|
||||
return;
|
||||
goto send_skb_err;
|
||||
|
||||
if (unlikely(!batman_if->net_dev))
|
||||
goto send_skb_err;
|
||||
|
||||
if (!(batman_if->net_dev->flags & IFF_UP)) {
|
||||
debug_log(LOG_TYPE_WARN,
|
||||
"Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n",
|
||||
batman_if->dev);
|
||||
return;
|
||||
printk(KERN_WARNING
|
||||
"batman-adv:Interface %s is not up - can't send packet via that interface!\n",
|
||||
batman_if->dev);
|
||||
goto send_skb_err;
|
||||
}
|
||||
|
||||
skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
|
||||
if (!skb)
|
||||
return;
|
||||
data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
|
||||
/* push to the ethernet header. */
|
||||
if (my_skb_push(skb, sizeof(struct ethhdr)) < 0)
|
||||
goto send_skb_err;
|
||||
|
||||
memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
ethhdr = (struct ethhdr *) data;
|
||||
ethhdr = (struct ethhdr *) skb_mac_header(skb);
|
||||
memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN);
|
||||
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
|
||||
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
skb_set_network_header(skb, ETH_HLEN);
|
||||
skb->priority = TC_PRIO_CONTROL;
|
||||
skb->protocol = __constant_htons(ETH_P_BATMAN);
|
||||
|
||||
skb->dev = batman_if->net_dev;
|
||||
|
||||
/* 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. */
|
||||
retval = dev_queue_xmit(skb);
|
||||
if (retval < 0)
|
||||
debug_log(LOG_TYPE_CRIT,
|
||||
"Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n",
|
||||
retval);
|
||||
|
||||
return dev_queue_xmit(skb);
|
||||
send_skb_err:
|
||||
kfree_skb(skb);
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
|
||||
/* sends a raw packet. */
|
||||
void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
|
||||
struct batman_if *batman_if, uint8_t *dst_addr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
char *data;
|
||||
|
||||
skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
|
||||
if (!skb)
|
||||
return;
|
||||
data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
|
||||
memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
|
||||
/* pull back to the batman "network header" */
|
||||
skb_pull(skb, sizeof(struct ethhdr));
|
||||
send_skb_packet(skb, batman_if, dst_addr);
|
||||
}
|
||||
|
||||
/* Send a packet to a given interface */
|
||||
|
@ -114,7 +130,6 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
|
|||
uint8_t packet_num;
|
||||
int16_t buff_pos;
|
||||
struct batman_packet *batman_packet;
|
||||
char orig_str[ETH_STR_LEN];
|
||||
|
||||
if (batman_if->if_active != IF_ACTIVE)
|
||||
return;
|
||||
|
@ -136,19 +151,18 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
|
|||
else
|
||||
batman_packet->flags &= ~DIRECTLINK;
|
||||
|
||||
addr_to_string(orig_str, batman_packet->orig);
|
||||
fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
|
||||
"Sending own" :
|
||||
"Forwarding"));
|
||||
debug_log(LOG_TYPE_BATMAN,
|
||||
"%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
|
||||
fwd_str,
|
||||
(packet_num > 0 ? "aggregated " : ""),
|
||||
orig_str, ntohs(batman_packet->seqno),
|
||||
batman_packet->tq, batman_packet->ttl,
|
||||
(batman_packet->flags & DIRECTLINK ?
|
||||
"on" : "off"),
|
||||
batman_if->dev, batman_if->addr_str);
|
||||
bat_dbg(DBG_BATMAN,
|
||||
"%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->tq, batman_packet->ttl,
|
||||
(batman_packet->flags & DIRECTLINK ?
|
||||
"on" : "off"),
|
||||
batman_if->dev, batman_if->addr_str);
|
||||
|
||||
buff_pos += sizeof(struct batman_packet) +
|
||||
(batman_packet->num_hna * ETH_ALEN);
|
||||
|
@ -168,32 +182,28 @@ static void send_packet(struct forw_packet *forw_packet)
|
|||
struct batman_if *batman_if;
|
||||
struct batman_packet *batman_packet =
|
||||
(struct batman_packet *)(forw_packet->packet_buff);
|
||||
char orig_str[ETH_STR_LEN];
|
||||
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
|
||||
|
||||
if (!forw_packet->if_incoming) {
|
||||
debug_log(LOG_TYPE_CRIT,
|
||||
"Error - can't forward packet: incoming iface not specified\n");
|
||||
printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (forw_packet->if_incoming->if_active != IF_ACTIVE)
|
||||
return;
|
||||
|
||||
addr_to_string(orig_str, batman_packet->orig);
|
||||
|
||||
/* multihomed peer assumed */
|
||||
/* non-primary OGMs are only broadcasted on their interface */
|
||||
if ((directlink && (batman_packet->ttl == 1)) ||
|
||||
(forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
|
||||
|
||||
/* FIXME: what about aggregated packets ? */
|
||||
debug_log(LOG_TYPE_BATMAN,
|
||||
"%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n",
|
||||
(forw_packet->own ? "Sending own" : "Forwarding"),
|
||||
orig_str, ntohs(batman_packet->seqno),
|
||||
batman_packet->ttl, forw_packet->if_incoming->dev,
|
||||
forw_packet->if_incoming->addr_str);
|
||||
bat_dbg(DBG_BATMAN,
|
||||
"%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->ttl, forw_packet->if_incoming->dev,
|
||||
forw_packet->if_incoming->addr_str);
|
||||
|
||||
send_raw_packet(forw_packet->packet_buff,
|
||||
forw_packet->packet_len,
|
||||
|
@ -238,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if)
|
|||
{
|
||||
unsigned long send_time;
|
||||
struct batman_packet *batman_packet;
|
||||
int vis_server = atomic_read(&vis_mode);
|
||||
|
||||
/**
|
||||
* the interface gets activated here to avoid race conditions between
|
||||
|
@ -262,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if)
|
|||
/* change sequence number to network order */
|
||||
batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
|
||||
|
||||
if (is_vis_server())
|
||||
if (vis_server == VIS_TYPE_SERVER_SYNC)
|
||||
batman_packet->flags = VIS_SERVER;
|
||||
else
|
||||
batman_packet->flags = 0;
|
||||
|
@ -286,7 +297,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
|
|||
unsigned long send_time;
|
||||
|
||||
if (batman_packet->ttl <= 1) {
|
||||
debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n");
|
||||
bat_dbg(DBG_BATMAN, "ttl exceeded \n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -314,9 +325,9 @@ void schedule_forward_packet(struct orig_node *orig_node,
|
|||
/* apply hop penalty */
|
||||
batman_packet->tq = hop_penalty(batman_packet->tq);
|
||||
|
||||
debug_log(LOG_TYPE_BATMAN, "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);
|
||||
bat_dbg(DBG_BATMAN, "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);
|
||||
|
||||
|
@ -333,6 +344,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
|
|||
|
||||
static void forw_packet_free(struct forw_packet *forw_packet)
|
||||
{
|
||||
if (forw_packet->skb)
|
||||
kfree_skb(forw_packet->skb);
|
||||
kfree(forw_packet->packet_buff);
|
||||
kfree(forw_packet);
|
||||
}
|
||||
|
@ -340,12 +353,13 @@ static void forw_packet_free(struct forw_packet *forw_packet)
|
|||
static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
|
||||
unsigned long send_time)
|
||||
{
|
||||
unsigned long flags;
|
||||
INIT_HLIST_NODE(&forw_packet->list);
|
||||
|
||||
/* add new packet to packet list */
|
||||
spin_lock(&forw_bcast_list_lock);
|
||||
spin_lock_irqsave(&forw_bcast_list_lock, flags);
|
||||
hlist_add_head(&forw_packet->list, &forw_bcast_list);
|
||||
spin_unlock(&forw_bcast_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
|
||||
|
||||
/* start timer for this packet */
|
||||
INIT_DELAYED_WORK(&forw_packet->delayed_work,
|
||||
|
@ -354,7 +368,7 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
|
|||
send_time);
|
||||
}
|
||||
|
||||
void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
|
||||
void add_bcast_packet_to_list(struct sk_buff *skb)
|
||||
{
|
||||
struct forw_packet *forw_packet;
|
||||
|
||||
|
@ -362,14 +376,16 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
|
|||
if (!forw_packet)
|
||||
return;
|
||||
|
||||
forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC);
|
||||
if (!forw_packet->packet_buff) {
|
||||
skb = skb_copy(skb, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
kfree(forw_packet);
|
||||
return;
|
||||
}
|
||||
|
||||
forw_packet->packet_len = packet_len;
|
||||
memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
forw_packet->skb = skb;
|
||||
forw_packet->packet_buff = NULL;
|
||||
|
||||
/* how often did we send the bcast packet ? */
|
||||
forw_packet->num_packets = 0;
|
||||
|
@ -384,16 +400,20 @@ void send_outstanding_bcast_packet(struct work_struct *work)
|
|||
container_of(work, struct delayed_work, work);
|
||||
struct forw_packet *forw_packet =
|
||||
container_of(delayed_work, struct forw_packet, delayed_work);
|
||||
unsigned long flags;
|
||||
struct sk_buff *skb1;
|
||||
|
||||
spin_lock(&forw_bcast_list_lock);
|
||||
spin_lock_irqsave(&forw_bcast_list_lock, flags);
|
||||
hlist_del(&forw_packet->list);
|
||||
spin_unlock(&forw_bcast_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
|
||||
|
||||
/* rebroadcast packet */
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
||||
send_raw_packet(forw_packet->packet_buff,
|
||||
forw_packet->packet_len,
|
||||
/* send a copy of the saved skb */
|
||||
skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
|
||||
if (skb1)
|
||||
send_skb_packet(skb1,
|
||||
batman_if, broadcastAddr);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
@ -415,10 +435,11 @@ void send_outstanding_bat_packet(struct work_struct *work)
|
|||
container_of(work, struct delayed_work, work);
|
||||
struct forw_packet *forw_packet =
|
||||
container_of(delayed_work, struct forw_packet, delayed_work);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&forw_bat_list_lock);
|
||||
spin_lock_irqsave(&forw_bat_list_lock, flags);
|
||||
hlist_del(&forw_packet->list);
|
||||
spin_unlock(&forw_bat_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
|
||||
|
||||
send_packet(forw_packet);
|
||||
|
||||
|
@ -438,38 +459,39 @@ void purge_outstanding_packets(void)
|
|||
{
|
||||
struct forw_packet *forw_packet;
|
||||
struct hlist_node *tmp_node, *safe_tmp_node;
|
||||
unsigned long flags;
|
||||
|
||||
debug_log(LOG_TYPE_BATMAN, "purge_outstanding_packets()\n");
|
||||
bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
|
||||
|
||||
/* free bcast list */
|
||||
spin_lock(&forw_bcast_list_lock);
|
||||
spin_lock_irqsave(&forw_bcast_list_lock, flags);
|
||||
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
|
||||
&forw_bcast_list, list) {
|
||||
|
||||
spin_unlock(&forw_bcast_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
|
||||
|
||||
/**
|
||||
* send_outstanding_bcast_packet() will lock the list to
|
||||
* delete the item from the list
|
||||
*/
|
||||
cancel_delayed_work_sync(&forw_packet->delayed_work);
|
||||
spin_lock(&forw_bcast_list_lock);
|
||||
spin_lock_irqsave(&forw_bcast_list_lock, flags);
|
||||
}
|
||||
spin_unlock(&forw_bcast_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
|
||||
|
||||
/* free batman packet list */
|
||||
spin_lock(&forw_bat_list_lock);
|
||||
spin_lock_irqsave(&forw_bat_list_lock, flags);
|
||||
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
|
||||
&forw_bat_list, list) {
|
||||
|
||||
spin_unlock(&forw_bat_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
|
||||
|
||||
/**
|
||||
* send_outstanding_bat_packet() will lock the list to
|
||||
* delete the item from the list
|
||||
*/
|
||||
cancel_delayed_work_sync(&forw_packet->delayed_work);
|
||||
spin_lock(&forw_bat_list_lock);
|
||||
spin_lock_irqsave(&forw_bat_list_lock, flags);
|
||||
}
|
||||
spin_unlock(&forw_bat_list_lock);
|
||||
spin_unlock_irqrestore(&forw_bat_list_lock, flags);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#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);
|
||||
void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
|
||||
struct batman_if *batman_if, uint8_t *dst_addr);
|
||||
void schedule_own_packet(struct batman_if *batman_if);
|
||||
|
@ -30,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
|
|||
struct batman_packet *batman_packet,
|
||||
uint8_t directlink, int hna_buff_len,
|
||||
struct batman_if *if_outgoing);
|
||||
void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len);
|
||||
void 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(void);
|
||||
|
|
|
@ -24,18 +24,15 @@
|
|||
#include "hard-interface.h"
|
||||
#include "send.h"
|
||||
#include "translation-table.h"
|
||||
#include "log.h"
|
||||
#include "types.h"
|
||||
#include "hash.h"
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include "compat.h"
|
||||
|
||||
static uint16_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;
|
||||
static int32_t lock_dropped;
|
||||
|
||||
unsigned char mainIfAddr[ETH_ALEN];
|
||||
static unsigned char mainIfAddr_default[ETH_ALEN];
|
||||
|
@ -68,12 +65,12 @@ int main_if_was_up(void)
|
|||
return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
static int my_skb_push(struct sk_buff *skb, unsigned int len)
|
||||
int my_skb_push(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
skb_packets++;
|
||||
if (skb->data - len < skb->head) {
|
||||
if (skb_headroom(skb) < len) {
|
||||
skb_bad_packets++;
|
||||
result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
|
||||
|
||||
|
@ -122,7 +119,7 @@ void interface_setup(struct net_device *dev)
|
|||
|
||||
/* generate random address */
|
||||
random_ether_addr(dev_addr);
|
||||
memcpy(dev->dev_addr, dev_addr, sizeof(dev->dev_addr));
|
||||
memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
|
||||
|
||||
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
|
||||
|
||||
|
@ -147,9 +144,18 @@ struct net_device_stats *interface_stats(struct net_device *dev)
|
|||
return &priv->stats;
|
||||
}
|
||||
|
||||
int interface_set_mac_addr(struct net_device *dev, void *addr)
|
||||
int interface_set_mac_addr(struct net_device *dev, void *p)
|
||||
{
|
||||
return -EBUSY;
|
||||
struct sockaddr *addr = p;
|
||||
|
||||
if (!is_valid_ether_addr(addr->sa_data))
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
hna_local_remove(dev->dev_addr, "mac address changed");
|
||||
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
||||
hna_local_add(dev->dev_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int interface_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
@ -170,7 +176,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
struct orig_node *orig_node;
|
||||
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
|
||||
struct bat_priv *priv = netdev_priv(dev);
|
||||
struct batman_if *batman_if;
|
||||
uint8_t dstaddr[6];
|
||||
int data_len = skb->len;
|
||||
unsigned long flags;
|
||||
|
||||
if (atomic_read(&module_state) != MODULE_ACTIVE)
|
||||
goto dropped;
|
||||
|
@ -186,7 +195,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
goto dropped;
|
||||
|
||||
bcast_packet = (struct bcast_packet *)skb->data;
|
||||
|
||||
bcast_packet->version = COMPAT_VERSION;
|
||||
|
||||
/* batman packet type: broadcast */
|
||||
|
@ -195,27 +203,21 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
/* 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);
|
||||
|
||||
/* set broadcast sequence number */
|
||||
bcast_packet->seqno = htons(bcast_seqno);
|
||||
|
||||
bcast_seqno++;
|
||||
|
||||
/* broadcast packet */
|
||||
add_bcast_packet_to_list(skb->data, skb->len);
|
||||
add_bcast_packet_to_list(skb);
|
||||
/* a copy is stored in the bcast list, therefore removing
|
||||
* the original skb. */
|
||||
kfree_skb(skb);
|
||||
|
||||
/* unicast packet */
|
||||
} else {
|
||||
|
||||
/* simply spin_lock()ing can deadlock when the lock is already
|
||||
* hold. */
|
||||
/* TODO: defer the work in a working queue instead of
|
||||
* dropping */
|
||||
if (!spin_trylock(&orig_hash_lock)) {
|
||||
lock_dropped++;
|
||||
debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped);
|
||||
goto dropped;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
/* get routing information */
|
||||
orig_node = ((struct orig_node *)hash_find(orig_hash,
|
||||
ethhdr->h_dest));
|
||||
|
@ -244,14 +246,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
if (orig_node->batman_if->if_active != IF_ACTIVE)
|
||||
goto unlock;
|
||||
|
||||
send_raw_packet(skb->data, skb->len,
|
||||
orig_node->batman_if,
|
||||
orig_node->router->addr);
|
||||
/* don't lock while sending the packets ... we therefore
|
||||
* copy the required data before sending */
|
||||
|
||||
batman_if = orig_node->batman_if;
|
||||
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
|
||||
send_skb_packet(skb, batman_if, dstaddr);
|
||||
} else {
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
spin_unlock(&orig_hash_lock);
|
||||
}
|
||||
|
||||
priv->stats.tx_packets++;
|
||||
|
@ -259,42 +264,44 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
goto end;
|
||||
|
||||
unlock:
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
dropped:
|
||||
priv->stats.tx_dropped++;
|
||||
end:
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
void interface_rx(struct net_device *dev, void *packet, int packet_len)
|
||||
void interface_rx(struct sk_buff *skb, int hdr_size)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct net_device *dev = soft_device;
|
||||
struct bat_priv *priv = netdev_priv(dev);
|
||||
|
||||
skb = dev_alloc_skb(packet_len);
|
||||
|
||||
if (!skb) {
|
||||
priv->stats.rx_dropped++;
|
||||
goto out;
|
||||
/* check if enough space is available for pulling, and pull */
|
||||
if (!pskb_may_pull(skb, hdr_size)) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
skb_pull_rcsum(skb, hdr_size);
|
||||
/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
|
||||
|
||||
memcpy(skb_put(skb, packet_len), packet, packet_len);
|
||||
|
||||
/* Write metadata, and then pass to the receive level */
|
||||
skb->dev = dev;
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
/* should not be neccesary anymore as we use skb_pull_rcsum()
|
||||
* TODO: please verify this and remove this TODO
|
||||
* -- Dec 21st 2009, Simon Wunderlich */
|
||||
|
||||
/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
|
||||
|
||||
/* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST,
|
||||
* PACKET_OTHERHOST or PACKET_HOST */
|
||||
|
||||
priv->stats.rx_packets++;
|
||||
priv->stats.rx_bytes += packet_len;
|
||||
priv->stats.rx_bytes += skb->len;
|
||||
|
||||
dev->last_rx = jiffies;
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
/* ethtool */
|
||||
|
@ -330,7 +337,6 @@ static u32 bat_get_msglevel(struct net_device *dev)
|
|||
|
||||
static void bat_set_msglevel(struct net_device *dev, u32 value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static u32 bat_get_link(struct net_device *dev)
|
||||
|
|
|
@ -28,6 +28,7 @@ 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 net_device *dev, void *packet, int packet_len);
|
||||
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[];
|
||||
|
|
|
@ -21,11 +21,9 @@
|
|||
|
||||
#include "main.h"
|
||||
#include "translation-table.h"
|
||||
#include "log.h"
|
||||
#include "soft-interface.h"
|
||||
#include "types.h"
|
||||
#include "hash.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct hashtable_t *hna_local_hash;
|
||||
static struct hashtable_t *hna_global_hash;
|
||||
|
@ -62,7 +60,6 @@ void hna_local_add(uint8_t *addr)
|
|||
struct hna_local_entry *hna_local_entry;
|
||||
struct hna_global_entry *hna_global_entry;
|
||||
struct hashtable_t *swaphash;
|
||||
char hna_str[ETH_STR_LEN];
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hna_local_hash_lock, flags);
|
||||
|
@ -75,19 +72,17 @@ void hna_local_add(uint8_t *addr)
|
|||
return;
|
||||
}
|
||||
|
||||
addr_to_string(hna_str, addr);
|
||||
|
||||
/* only announce as many hosts as possible in the batman-packet and
|
||||
space in batman_packet->num_hna That also should give a limit to
|
||||
MAC-flooding. */
|
||||
if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
|
||||
(num_hna + 1 > 255)) {
|
||||
debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str);
|
||||
bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n",
|
||||
hna_str);
|
||||
bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n",
|
||||
addr);
|
||||
|
||||
hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
|
||||
if (!hna_local_entry)
|
||||
|
@ -113,7 +108,7 @@ void hna_local_add(uint8_t *addr)
|
|||
hna_local_hash->size * 2);
|
||||
|
||||
if (swaphash == NULL)
|
||||
debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n");
|
||||
printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n");
|
||||
else
|
||||
hna_local_hash = swaphash;
|
||||
}
|
||||
|
@ -135,18 +130,18 @@ void hna_local_add(uint8_t *addr)
|
|||
int hna_local_fill_buffer(unsigned char *buff, int buff_len)
|
||||
{
|
||||
struct hna_local_entry *hna_local_entry;
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
int i = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hna_local_hash_lock, flags);
|
||||
|
||||
while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
|
||||
while (hash_iterate(hna_local_hash, &hashit)) {
|
||||
|
||||
if (buff_len < (i + 1) * ETH_ALEN)
|
||||
break;
|
||||
|
||||
hna_local_entry = hashit->bucket->data;
|
||||
hna_local_entry = hashit.bucket->data;
|
||||
memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
|
||||
|
||||
i++;
|
||||
|
@ -164,18 +159,18 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
|
|||
int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
|
||||
{
|
||||
struct hna_local_entry *hna_local_entry;
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
int bytes_written = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hna_local_hash_lock, flags);
|
||||
|
||||
while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
|
||||
while (hash_iterate(hna_local_hash, &hashit)) {
|
||||
|
||||
if (buff_len < bytes_written + ETH_STR_LEN + 4)
|
||||
break;
|
||||
|
||||
hna_local_entry = hashit->bucket->data;
|
||||
hna_local_entry = hashit.bucket->data;
|
||||
|
||||
bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
|
||||
" * %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
|
@ -202,27 +197,39 @@ static void _hna_local_del(void *data)
|
|||
static void hna_local_del(struct hna_local_entry *hna_local_entry,
|
||||
char *message)
|
||||
{
|
||||
char hna_str[ETH_STR_LEN];
|
||||
|
||||
addr_to_string(hna_str, hna_local_entry->addr);
|
||||
debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
|
||||
hna_str, message);
|
||||
bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n",
|
||||
hna_local_entry->addr, message);
|
||||
|
||||
hash_remove(hna_local_hash, hna_local_entry->addr);
|
||||
_hna_local_del(hna_local_entry);
|
||||
}
|
||||
|
||||
void hna_local_remove(uint8_t *addr, char *message)
|
||||
{
|
||||
struct hna_local_entry *hna_local_entry;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hna_local_hash_lock, flags);
|
||||
|
||||
hna_local_entry = (struct hna_local_entry *)
|
||||
hash_find(hna_local_hash, addr);
|
||||
if (hna_local_entry)
|
||||
hna_local_del(hna_local_entry, message);
|
||||
|
||||
spin_unlock_irqrestore(&hna_local_hash_lock, flags);
|
||||
}
|
||||
|
||||
void hna_local_purge(struct work_struct *work)
|
||||
{
|
||||
struct hna_local_entry *hna_local_entry;
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
unsigned long flags;
|
||||
unsigned long timeout;
|
||||
|
||||
spin_lock_irqsave(&hna_local_hash_lock, flags);
|
||||
|
||||
while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
|
||||
hna_local_entry = hashit->bucket->data;
|
||||
while (hash_iterate(hna_local_hash, &hashit)) {
|
||||
hna_local_entry = hashit.bucket->data;
|
||||
|
||||
timeout = hna_local_entry->last_seen +
|
||||
((LOCAL_HNA_TIMEOUT / 1000) * HZ);
|
||||
|
@ -264,13 +271,10 @@ void hna_global_add_orig(struct orig_node *orig_node,
|
|||
struct hna_global_entry *hna_global_entry;
|
||||
struct hna_local_entry *hna_local_entry;
|
||||
struct hashtable_t *swaphash;
|
||||
char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
|
||||
int hna_buff_count = 0;
|
||||
unsigned long flags;
|
||||
unsigned char *hna_ptr;
|
||||
|
||||
addr_to_string(orig_str, orig_node->orig);
|
||||
|
||||
while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
|
||||
spin_lock_irqsave(&hna_global_hash_lock, flags);
|
||||
|
||||
|
@ -290,8 +294,9 @@ void hna_global_add_orig(struct orig_node *orig_node,
|
|||
|
||||
memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
|
||||
|
||||
addr_to_string(hna_str, hna_global_entry->addr);
|
||||
debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str);
|
||||
bat_dbg(DBG_ROUTES,
|
||||
"Creating new global hna entry: %pM (via %pM)\n",
|
||||
hna_global_entry->addr, orig_node->orig);
|
||||
|
||||
spin_lock_irqsave(&hna_global_hash_lock, flags);
|
||||
hash_add(hna_global_hash, hna_global_entry);
|
||||
|
@ -316,14 +321,16 @@ void hna_global_add_orig(struct orig_node *orig_node,
|
|||
hna_buff_count++;
|
||||
}
|
||||
|
||||
orig_node->hna_buff_len = hna_buff_len;
|
||||
/* initialize, and overwrite if malloc succeeds */
|
||||
orig_node->hna_buff = NULL;
|
||||
orig_node->hna_buff_len = 0;
|
||||
|
||||
if (orig_node->hna_buff_len > 0) {
|
||||
orig_node->hna_buff = kmalloc(orig_node->hna_buff_len,
|
||||
GFP_ATOMIC);
|
||||
memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len);
|
||||
} else {
|
||||
orig_node->hna_buff = NULL;
|
||||
if (hna_buff_len > 0) {
|
||||
orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
|
||||
if (orig_node->hna_buff) {
|
||||
memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
|
||||
orig_node->hna_buff_len = hna_buff_len;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&hna_global_hash_lock, flags);
|
||||
|
@ -333,7 +340,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
|
|||
hna_global_hash->size * 2);
|
||||
|
||||
if (swaphash == NULL)
|
||||
debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n");
|
||||
printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n");
|
||||
else
|
||||
hna_global_hash = swaphash;
|
||||
}
|
||||
|
@ -344,17 +351,17 @@ void hna_global_add_orig(struct orig_node *orig_node,
|
|||
int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
|
||||
{
|
||||
struct hna_global_entry *hna_global_entry;
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
int bytes_written = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hna_global_hash_lock, flags);
|
||||
|
||||
while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) {
|
||||
while (hash_iterate(hna_global_hash, &hashit)) {
|
||||
if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
|
||||
break;
|
||||
|
||||
hna_global_entry = hashit->bucket->data;
|
||||
hna_global_entry = hashit.bucket->data;
|
||||
|
||||
bytes_written += snprintf(buff + bytes_written,
|
||||
(2 * ETH_STR_LEN) + 10,
|
||||
|
@ -381,12 +388,9 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
|
|||
void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
|
||||
char *message)
|
||||
{
|
||||
char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
|
||||
|
||||
addr_to_string(orig_str, hna_global_entry->orig_node->orig);
|
||||
addr_to_string(hna_str, hna_global_entry->addr);
|
||||
|
||||
debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message);
|
||||
bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n",
|
||||
hna_global_entry->addr, hna_global_entry->orig_node->orig,
|
||||
message);
|
||||
|
||||
hash_remove(hna_global_hash, hna_global_entry->addr);
|
||||
kfree(hna_global_entry);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
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(unsigned char *buff, int buff_len);
|
||||
void hna_local_purge(struct work_struct *work);
|
||||
|
|
|
@ -39,7 +39,6 @@ struct batman_if {
|
|||
char if_active;
|
||||
char addr_str[ETH_STR_LEN];
|
||||
struct net_device *net_dev;
|
||||
struct socket *raw_sock;
|
||||
atomic_t seqno;
|
||||
unsigned char *packet_buff;
|
||||
int packet_len;
|
||||
|
@ -75,7 +74,7 @@ struct neigh_node {
|
|||
uint8_t tq_index;
|
||||
uint8_t tq_avg;
|
||||
uint8_t last_ttl;
|
||||
unsigned long last_valid; /* when last packet via this neighbour was received */
|
||||
unsigned long last_valid; /* when last packet via this neighbor was received */
|
||||
TYPE_OF_WORD real_bits[NUM_WORDS];
|
||||
struct orig_node *orig_node;
|
||||
struct batman_if *if_incoming;
|
||||
|
@ -113,6 +112,7 @@ struct forw_packet { /* structure for forw_list maintaining packet
|
|||
struct hlist_node list;
|
||||
unsigned long send_time;
|
||||
uint8_t own;
|
||||
struct sk_buff *skb;
|
||||
unsigned char *packet_buff;
|
||||
uint16_t packet_len;
|
||||
uint32_t direct_link_flags;
|
||||
|
@ -121,4 +121,14 @@ struct forw_packet { /* structure for forw_list maintaining packet
|
|||
struct batman_if *if_incoming;
|
||||
};
|
||||
|
||||
/* While scanning for vis-entries of a particular vis-originator
|
||||
* this list collects its interfaces to create a subgraph/cluster
|
||||
* out of them later
|
||||
*/
|
||||
struct if_list_entry {
|
||||
uint8_t addr[ETH_ALEN];
|
||||
bool primary;
|
||||
struct hlist_node list;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,11 +23,9 @@
|
|||
#include "send.h"
|
||||
#include "translation-table.h"
|
||||
#include "vis.h"
|
||||
#include "log.h"
|
||||
#include "soft-interface.h"
|
||||
#include "hard-interface.h"
|
||||
#include "hash.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct hashtable_t *vis_hash;
|
||||
DEFINE_SPINLOCK(vis_hash_lock);
|
||||
|
@ -50,39 +48,6 @@ static void free_info(void *data)
|
|||
kfree(info);
|
||||
}
|
||||
|
||||
/* set the mode of the visualization to client or server */
|
||||
void vis_set_mode(int mode)
|
||||
{
|
||||
spin_lock(&vis_hash_lock);
|
||||
|
||||
if (my_vis_info != NULL)
|
||||
my_vis_info->packet.vis_type = mode;
|
||||
|
||||
spin_unlock(&vis_hash_lock);
|
||||
}
|
||||
|
||||
/* is_vis_server(), locked outside */
|
||||
static int is_vis_server_locked(void)
|
||||
{
|
||||
if (my_vis_info != NULL)
|
||||
if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the current set mode */
|
||||
int is_vis_server(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
ret = is_vis_server_locked();
|
||||
spin_unlock(&vis_hash_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Compare two vis packets, used by the hashing algorithm */
|
||||
static int vis_info_cmp(void *data1, void *data2)
|
||||
{
|
||||
|
@ -115,6 +80,68 @@ static int vis_info_choose(void *data, int size)
|
|||
return hash % size;
|
||||
}
|
||||
|
||||
/* insert interface to the list of interfaces of one originator, if it
|
||||
* does not already exist in the list */
|
||||
static void proc_vis_insert_interface(const uint8_t *interface,
|
||||
struct hlist_head *if_list,
|
||||
bool primary)
|
||||
{
|
||||
struct if_list_entry *entry;
|
||||
struct hlist_node *pos;
|
||||
|
||||
hlist_for_each_entry(entry, pos, if_list, list) {
|
||||
if (compare_orig(entry->addr, (void *)interface))
|
||||
return;
|
||||
}
|
||||
|
||||
/* its a new address, add it to the list */
|
||||
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry)
|
||||
return;
|
||||
memcpy(entry->addr, interface, ETH_ALEN);
|
||||
entry->primary = primary;
|
||||
hlist_add_head(&entry->list, if_list);
|
||||
}
|
||||
|
||||
void proc_vis_read_prim_sec(struct seq_file *seq,
|
||||
struct hlist_head *if_list)
|
||||
{
|
||||
struct if_list_entry *entry;
|
||||
struct hlist_node *pos, *n;
|
||||
char tmp_addr_str[ETH_STR_LEN];
|
||||
|
||||
hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
|
||||
if (entry->primary) {
|
||||
seq_printf(seq, "PRIMARY, ");
|
||||
} else {
|
||||
addr_to_string(tmp_addr_str, entry->addr);
|
||||
seq_printf(seq, "SEC %s, ", tmp_addr_str);
|
||||
}
|
||||
|
||||
hlist_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/* read an entry */
|
||||
void proc_vis_read_entry(struct seq_file *seq,
|
||||
struct vis_info_entry *entry,
|
||||
struct hlist_head *if_list,
|
||||
uint8_t *vis_orig)
|
||||
{
|
||||
char to[40];
|
||||
|
||||
addr_to_string(to, entry->dest);
|
||||
if (entry->quality == 0) {
|
||||
proc_vis_insert_interface(vis_orig, if_list, true);
|
||||
seq_printf(seq, "HNA %s, ", to);
|
||||
} else {
|
||||
proc_vis_insert_interface(entry->src, if_list,
|
||||
compare_orig(entry->src, vis_orig));
|
||||
seq_printf(seq, "TQ %s %d, ", to, entry->quality);
|
||||
}
|
||||
}
|
||||
|
||||
/* tries to add one entry to the receive list. */
|
||||
static void recv_list_add(struct list_head *recv_list, char *mac)
|
||||
{
|
||||
|
@ -208,21 +235,23 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
|
|||
{
|
||||
struct vis_info *info;
|
||||
int is_new;
|
||||
unsigned long flags;
|
||||
int vis_server = atomic_read(&vis_mode);
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
spin_lock_irqsave(&vis_hash_lock, flags);
|
||||
info = add_packet(vis_packet, vis_info_len, &is_new);
|
||||
if (info == NULL)
|
||||
goto end;
|
||||
|
||||
/* only if we are server ourselves and packet is newer than the one in
|
||||
* hash.*/
|
||||
if (is_vis_server_locked() && is_new) {
|
||||
if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
|
||||
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
|
||||
if (list_empty(&info->send_list))
|
||||
list_add_tail(&info->send_list, &send_list);
|
||||
}
|
||||
end:
|
||||
spin_unlock(&vis_hash_lock);
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
}
|
||||
|
||||
/* handle an incoming client update packet and schedule forward if needed. */
|
||||
|
@ -231,12 +260,14 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
|
|||
{
|
||||
struct vis_info *info;
|
||||
int is_new;
|
||||
unsigned long flags;
|
||||
int vis_server = atomic_read(&vis_mode);
|
||||
|
||||
/* clients shall not broadcast. */
|
||||
if (is_bcast(vis_packet->target_orig))
|
||||
return;
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
spin_lock_irqsave(&vis_hash_lock, flags);
|
||||
info = add_packet(vis_packet, vis_info_len, &is_new);
|
||||
if (info == NULL)
|
||||
goto end;
|
||||
|
@ -244,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
|
|||
|
||||
|
||||
/* send only if we're the target server or ... */
|
||||
if (is_vis_server_locked() &&
|
||||
if (vis_server == VIS_TYPE_SERVER_SYNC &&
|
||||
is_my_mac(info->packet.target_orig) &&
|
||||
is_new) {
|
||||
info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
|
||||
|
@ -258,7 +289,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
|
|||
list_add_tail(&info->send_list, &send_list);
|
||||
}
|
||||
end:
|
||||
spin_unlock(&vis_hash_lock);
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
}
|
||||
|
||||
/* Walk the originators and find the VIS server with the best tq. Set the packet
|
||||
|
@ -267,12 +298,12 @@ end:
|
|||
* Must be called with the originator hash locked */
|
||||
static int find_best_vis_server(struct vis_info *info)
|
||||
{
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
struct orig_node *orig_node;
|
||||
int best_tq = -1;
|
||||
|
||||
while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
|
||||
orig_node = hashit->bucket->data;
|
||||
while (hash_iterate(orig_hash, &hashit)) {
|
||||
orig_node = hashit.bucket->data;
|
||||
if ((orig_node != NULL) &&
|
||||
(orig_node->router != NULL) &&
|
||||
(orig_node->flags & VIS_SERVER) &&
|
||||
|
@ -298,7 +329,8 @@ static bool vis_packet_full(struct vis_info *info)
|
|||
* returns 0 on success, -1 if no packet could be generated */
|
||||
static int generate_vis_packet(void)
|
||||
{
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit_local);
|
||||
HASHIT(hashit_global);
|
||||
struct orig_node *orig_node;
|
||||
struct vis_info *info = (struct vis_info *)my_vis_info;
|
||||
struct vis_info_entry *entry, *entry_array;
|
||||
|
@ -307,27 +339,27 @@ static int generate_vis_packet(void)
|
|||
unsigned long flags;
|
||||
|
||||
info->first_seen = jiffies;
|
||||
info->packet.vis_type = atomic_read(&vis_mode);
|
||||
|
||||
spin_lock(&orig_hash_lock);
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
|
||||
info->packet.ttl = TTL;
|
||||
info->packet.seqno++;
|
||||
info->packet.entries = 0;
|
||||
|
||||
if (!is_vis_server_locked()) {
|
||||
if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
|
||||
best_tq = find_best_vis_server(info);
|
||||
if (best_tq < 0) {
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
hashit = NULL;
|
||||
|
||||
entry_array = (struct vis_info_entry *)
|
||||
((char *)info + sizeof(struct vis_info));
|
||||
|
||||
while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
|
||||
orig_node = hashit->bucket->data;
|
||||
while (hash_iterate(orig_hash, &hashit_global)) {
|
||||
orig_node = hashit_global.bucket->data;
|
||||
if (orig_node->router != NULL
|
||||
&& compare_orig(orig_node->router->addr, orig_node->orig)
|
||||
&& orig_node->batman_if
|
||||
|
@ -342,18 +374,17 @@ static int generate_vis_packet(void)
|
|||
info->packet.entries++;
|
||||
|
||||
if (vis_packet_full(info)) {
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
|
||||
hashit = NULL;
|
||||
spin_lock_irqsave(&hna_local_hash_lock, flags);
|
||||
while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
|
||||
hna_local_entry = hashit->bucket->data;
|
||||
while (hash_iterate(hna_local_hash, &hashit_local)) {
|
||||
hna_local_entry = hashit_local.bucket->data;
|
||||
entry = &entry_array[info->packet.entries];
|
||||
memset(entry->src, 0, ETH_ALEN);
|
||||
memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
|
||||
|
@ -371,16 +402,16 @@ static int generate_vis_packet(void)
|
|||
|
||||
static void purge_vis_packets(void)
|
||||
{
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
struct vis_info *info;
|
||||
|
||||
while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
|
||||
info = hashit->bucket->data;
|
||||
while (hash_iterate(vis_hash, &hashit)) {
|
||||
info = hashit.bucket->data;
|
||||
if (info == my_vis_info) /* never purge own data. */
|
||||
continue;
|
||||
if (time_after(jiffies,
|
||||
info->first_seen + (VIS_TIMEOUT/1000)*HZ)) {
|
||||
hash_remove_bucket(vis_hash, hashit);
|
||||
info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
|
||||
hash_remove_bucket(vis_hash, &hashit);
|
||||
free_info(info);
|
||||
}
|
||||
}
|
||||
|
@ -388,14 +419,15 @@ static void purge_vis_packets(void)
|
|||
|
||||
static void broadcast_vis_packet(struct vis_info *info, int packet_length)
|
||||
{
|
||||
struct hash_it_t *hashit = NULL;
|
||||
HASHIT(hashit);
|
||||
struct orig_node *orig_node;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&orig_hash_lock);
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
|
||||
/* send to all routers in range. */
|
||||
while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
|
||||
orig_node = hashit->bucket->data;
|
||||
while (hash_iterate(orig_hash, &hashit)) {
|
||||
orig_node = hashit.bucket->data;
|
||||
|
||||
/* if it's a vis server and reachable, send it. */
|
||||
if (orig_node &&
|
||||
|
@ -418,14 +450,15 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
|
|||
}
|
||||
}
|
||||
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
}
|
||||
|
||||
static void unicast_vis_packet(struct vis_info *info, int packet_length)
|
||||
{
|
||||
struct orig_node *orig_node;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&orig_hash_lock);
|
||||
spin_lock_irqsave(&orig_hash_lock, flags);
|
||||
orig_node = ((struct orig_node *)
|
||||
hash_find(orig_hash, info->packet.target_orig));
|
||||
|
||||
|
@ -436,7 +469,7 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length)
|
|||
orig_node->batman_if,
|
||||
orig_node->router->addr);
|
||||
}
|
||||
spin_unlock(&orig_hash_lock);
|
||||
spin_unlock_irqrestore(&orig_hash_lock, flags);
|
||||
}
|
||||
|
||||
/* only send one vis packet. called from send_vis_packets() */
|
||||
|
@ -445,8 +478,7 @@ static void send_vis_packet(struct vis_info *info)
|
|||
int packet_length;
|
||||
|
||||
if (info->packet.ttl < 2) {
|
||||
debug_log(LOG_TYPE_NOTICE,
|
||||
"Error - can't send vis packet: ttl exceeded\n");
|
||||
printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -467,8 +499,9 @@ static void send_vis_packet(struct vis_info *info)
|
|||
static void send_vis_packets(struct work_struct *work)
|
||||
{
|
||||
struct vis_info *info, *temp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
spin_lock_irqsave(&vis_hash_lock, flags);
|
||||
purge_vis_packets();
|
||||
|
||||
if (generate_vis_packet() == 0)
|
||||
|
@ -479,7 +512,7 @@ static void send_vis_packets(struct work_struct *work)
|
|||
list_del_init(&info->send_list);
|
||||
send_vis_packet(info);
|
||||
}
|
||||
spin_unlock(&vis_hash_lock);
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
start_vis_timer();
|
||||
}
|
||||
static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
|
||||
|
@ -488,20 +521,21 @@ static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
|
|||
* initialized (e.g. bat0 is initialized, interfaces have been added) */
|
||||
int vis_init(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
if (vis_hash)
|
||||
return 1;
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
spin_lock_irqsave(&vis_hash_lock, flags);
|
||||
|
||||
vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
|
||||
if (!vis_hash) {
|
||||
debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n");
|
||||
printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
my_vis_info = kmalloc(1000, GFP_ATOMIC);
|
||||
if (!my_vis_info) {
|
||||
debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n");
|
||||
printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -511,7 +545,6 @@ int vis_init(void)
|
|||
INIT_LIST_HEAD(&my_vis_info->send_list);
|
||||
my_vis_info->packet.version = COMPAT_VERSION;
|
||||
my_vis_info->packet.packet_type = BAT_VIS;
|
||||
my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
|
||||
my_vis_info->packet.ttl = TTL;
|
||||
my_vis_info->packet.seqno = 0;
|
||||
my_vis_info->packet.entries = 0;
|
||||
|
@ -522,19 +555,19 @@ int vis_init(void)
|
|||
memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
|
||||
|
||||
if (hash_add(vis_hash, my_vis_info) < 0) {
|
||||
debug_log(LOG_TYPE_CRIT,
|
||||
"Can't add own vis packet into hash\n");
|
||||
printk(KERN_ERR
|
||||
"batman-adv:Can't add own vis packet into hash\n");
|
||||
free_info(my_vis_info); /* not in hash, need to remove it
|
||||
* manually. */
|
||||
goto err;
|
||||
}
|
||||
|
||||
spin_unlock(&vis_hash_lock);
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
start_vis_timer();
|
||||
return 1;
|
||||
|
||||
err:
|
||||
spin_unlock(&vis_hash_lock);
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
vis_quit();
|
||||
return 0;
|
||||
}
|
||||
|
@ -542,23 +575,23 @@ err:
|
|||
/* shutdown vis-server */
|
||||
void vis_quit(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
if (!vis_hash)
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&vis_timer_wq);
|
||||
|
||||
spin_lock(&vis_hash_lock);
|
||||
spin_lock_irqsave(&vis_hash_lock, flags);
|
||||
/* properly remove, kill timers ... */
|
||||
hash_delete(vis_hash, free_info);
|
||||
vis_hash = NULL;
|
||||
my_vis_info = NULL;
|
||||
spin_unlock(&vis_hash_lock);
|
||||
spin_unlock_irqrestore(&vis_hash_lock, flags);
|
||||
}
|
||||
|
||||
/* schedule packets for (re)transmission */
|
||||
static void start_vis_timer(void)
|
||||
{
|
||||
queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
|
||||
(atomic_read(&vis_interval)/1000) * HZ);
|
||||
(atomic_read(&vis_interval) * HZ) / 1000);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,16 +45,15 @@ struct recvlist_node {
|
|||
uint8_t mac[ETH_ALEN];
|
||||
};
|
||||
|
||||
enum vis_formats {
|
||||
DOT_DRAW,
|
||||
JSON,
|
||||
};
|
||||
|
||||
extern struct hashtable_t *vis_hash;
|
||||
extern spinlock_t vis_hash_lock;
|
||||
|
||||
void vis_set_mode(int mode);
|
||||
int is_vis_server(void);
|
||||
void proc_vis_read_entry(struct seq_file *seq,
|
||||
struct vis_info_entry *entry,
|
||||
struct hlist_head *if_list,
|
||||
uint8_t *vis_orig);
|
||||
void proc_vis_read_prim_sec(struct seq_file *seq,
|
||||
struct hlist_head *if_list);
|
||||
void receive_server_sync_packet(struct vis_packet *vis_packet,
|
||||
int vis_info_len);
|
||||
void receive_client_update_packet(struct vis_packet *vis_packet,
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#define __NO_VERSION__
|
||||
#include "comedi.h"
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include "comedi_compat32.h"
|
||||
|
|
|
@ -63,7 +63,7 @@ module_param(comedi_debug, int, 0644);
|
|||
int comedi_autoconfig = 1;
|
||||
module_param(comedi_autoconfig, bool, 0444);
|
||||
|
||||
int comedi_num_legacy_minors = 0;
|
||||
int comedi_num_legacy_minors;
|
||||
module_param(comedi_num_legacy_minors, int, 0444);
|
||||
|
||||
static DEFINE_SPINLOCK(comedi_file_info_table_lock);
|
||||
|
@ -1510,7 +1510,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
|
|||
}
|
||||
|
||||
static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
|
||||
loff_t * offset)
|
||||
loff_t *offset)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
|
@ -1612,7 +1612,7 @@ done:
|
|||
}
|
||||
|
||||
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
|
||||
loff_t * offset)
|
||||
loff_t *offset)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
|
@ -2004,12 +2004,10 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
|
|||
if (async->cb_mask & s->async->events) {
|
||||
if (comedi_get_subdevice_runflags(s) & SRF_USER) {
|
||||
wake_up_interruptible(&async->wait_head);
|
||||
if (s->subdev_flags & SDF_CMD_READ) {
|
||||
if (s->subdev_flags & SDF_CMD_READ)
|
||||
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
|
||||
}
|
||||
if (s->subdev_flags & SDF_CMD_WRITE) {
|
||||
if (s->subdev_flags & SDF_CMD_WRITE)
|
||||
kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
|
||||
}
|
||||
} else {
|
||||
if (async->cb_func)
|
||||
async->cb_func(s->async->events, async->cb_arg);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include <linux/cdev.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static int postconfig(struct comedi_device *dev);
|
||||
|
@ -99,11 +99,10 @@ static void cleanup_device(struct comedi_device *dev)
|
|||
static void __comedi_device_detach(struct comedi_device *dev)
|
||||
{
|
||||
dev->attached = 0;
|
||||
if (dev->driver) {
|
||||
if (dev->driver)
|
||||
dev->driver->detach(dev);
|
||||
} else {
|
||||
else
|
||||
printk("BUG: dev->driver=NULL in comedi_device_detach()\n");
|
||||
}
|
||||
cleanup_device(dev);
|
||||
}
|
||||
|
||||
|
@ -380,9 +379,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (insn->insn == INSN_READ) {
|
||||
if (insn->insn == INSN_READ)
|
||||
data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -429,9 +427,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
|
||||
/* if no change is required, do nothing */
|
||||
if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
|
||||
if (async->prealloc_buf && async->prealloc_bufsz == new_size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* deallocate old buffer */
|
||||
if (async->prealloc_buf) {
|
||||
vunmap(async->prealloc_buf);
|
||||
|
@ -494,9 +492,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
(void *)
|
||||
get_zeroed_page(GFP_KERNEL);
|
||||
}
|
||||
if (async->buf_page_list[i].virt_addr == NULL) {
|
||||
if (async->buf_page_list[i].virt_addr == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
mem_map_reserve(virt_to_page
|
||||
(async->buf_page_list[i].
|
||||
virt_addr));
|
||||
|
@ -619,9 +617,9 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async,
|
|||
{
|
||||
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
|
||||
|
||||
if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) {
|
||||
if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
|
||||
nbytes = free_end - async->buf_write_alloc_count;
|
||||
}
|
||||
|
||||
async->buf_write_alloc_count += nbytes;
|
||||
/* barrier insures the read of buf_read_count above occurs before
|
||||
we write data to the write-alloc'ed buffer space */
|
||||
|
@ -635,9 +633,9 @@ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
|
|||
{
|
||||
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
|
||||
|
||||
if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) {
|
||||
if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
|
||||
nbytes = 0;
|
||||
}
|
||||
|
||||
async->buf_write_alloc_count += nbytes;
|
||||
/* barrier insures the read of buf_read_count above occurs before
|
||||
we write data to the write-alloc'ed buffer space */
|
||||
|
@ -657,9 +655,9 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
|
|||
async->buf_write_count += nbytes;
|
||||
async->buf_write_ptr += nbytes;
|
||||
comedi_buf_munge(async, async->buf_write_count - async->munge_count);
|
||||
if (async->buf_write_ptr >= async->prealloc_bufsz) {
|
||||
if (async->buf_write_ptr >= async->prealloc_bufsz)
|
||||
async->buf_write_ptr %= async->prealloc_bufsz;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
@ -173,11 +173,10 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
|
|||
} while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
/* Select the upper address part */
|
||||
if (i_Counter == 0) {
|
||||
if (i_Counter == 0)
|
||||
b_ReadLowByte = pb_ReadByte[0];
|
||||
} else {
|
||||
else
|
||||
b_ReadHighByte = pb_ReadByte[0];
|
||||
}
|
||||
|
||||
/* Sleep */
|
||||
msleep(1);
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -77,8 +77,8 @@ struct addi_board {
|
|||
int i_NbrAoChannel; /* num of D/A chans */
|
||||
int i_AiMaxdata; /* resolution of A/D */
|
||||
int i_AoMaxdata; /* resolution of D/A */
|
||||
const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */
|
||||
const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */
|
||||
const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */
|
||||
const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */
|
||||
|
||||
int i_NbrDiChannel; /* Number of DI channels */
|
||||
int i_NbrDoChannel; /* Number of DO channels */
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
@ -54,7 +54,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
|
|||
#include "hwdrv_apci1032.h"
|
||||
#include <linux/delay.h>
|
||||
/* Global variables */
|
||||
unsigned int ui_InterruptStatus = 0;
|
||||
unsigned int ui_InterruptStatus;
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
|
@ -108,9 +108,9 @@ int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde
|
|||
ui_TmpValue =
|
||||
inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
} /* if (data[1] == ADDIDATA_OR) */
|
||||
else {
|
||||
else
|
||||
outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
} /* else if(data[1] == ADDIDATA_OR) */
|
||||
/* else if(data[1] == ADDIDATA_OR) */
|
||||
} /* if( data[0] == ADDIDATA_ENABLE) */
|
||||
else {
|
||||
ul_Command1 = ul_Command1 & 0xFFFF0000;
|
||||
|
@ -221,9 +221,9 @@ int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub
|
|||
} /* switch(ui_NoOfChannels) */
|
||||
} /* if(data[1]==0) */
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
if (data[1] == 1)
|
||||
*data = ui_InterruptStatus;
|
||||
} /* if(data[1]==1) */
|
||||
/* if(data[1]==1) */
|
||||
} /* else if(data[1]==0) */
|
||||
return insn->n;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
@ -45,7 +45,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
|
|||
*/
|
||||
|
||||
#include "hwdrv_apci3120.h"
|
||||
static unsigned int ui_Temp = 0;
|
||||
static unsigned int ui_Temp;
|
||||
|
||||
/* FUNCTION DEFINITIONS */
|
||||
|
||||
|
@ -98,25 +98,22 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
|
|||
|
||||
devpriv->b_InterruptMode = APCI3120_EOS_MODE;
|
||||
|
||||
if (data[1]) {
|
||||
if (data[1])
|
||||
devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
|
||||
} else
|
||||
else
|
||||
devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
|
||||
/* Copy channel list and Range List to devpriv */
|
||||
|
||||
devpriv->ui_AiNbrofChannels = data[3];
|
||||
for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
|
||||
for (i = 0; i < devpriv->ui_AiNbrofChannels; i++)
|
||||
devpriv->ui_AiChannelList[i] = data[4 + i];
|
||||
}
|
||||
|
||||
} else /* EOC */
|
||||
{
|
||||
} else { /* EOC */
|
||||
devpriv->b_InterruptMode = APCI3120_EOC_MODE;
|
||||
if (data[1]) {
|
||||
if (data[1])
|
||||
devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
|
||||
} else {
|
||||
else
|
||||
devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
return insn->n;
|
||||
|
@ -166,13 +163,9 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd
|
|||
devpriv->us_OutputRegister = 0;
|
||||
/* devpriv->b_DigitalOutputRegister=0; */
|
||||
|
||||
if (insn->unused[0] == 222) /* second insn read */
|
||||
{
|
||||
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
if (insn->unused[0] == 222) { /* second insn read */
|
||||
for (i = 0; i < insn->n; i++)
|
||||
data[i] = devpriv->ui_AiReadData[i];
|
||||
}
|
||||
|
||||
} else {
|
||||
devpriv->tsk_Current = current; /* Save the current process task structure */
|
||||
/*
|
||||
|
@ -519,9 +512,8 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
|
|||
|
||||
/* step 2: make sure trigger sources are unique and mutually compatible */
|
||||
|
||||
if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
|
||||
if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
|
||||
err++;
|
||||
}
|
||||
|
||||
if (cmd->scan_begin_src != TRIG_TIMER &&
|
||||
cmd->scan_begin_src != TRIG_FOLLOW)
|
||||
|
@ -548,16 +540,14 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
|
|||
err++;
|
||||
}
|
||||
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */
|
||||
{
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */
|
||||
if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
|
||||
cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd->convert_src == TRIG_TIMER) /* Test Acquisition timing */
|
||||
{
|
||||
if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
if ((cmd->convert_arg)
|
||||
&& (cmd->convert_arg <
|
||||
|
@ -653,11 +643,10 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde
|
|||
/* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
|
||||
devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT) {
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->ui_AiNbrofScans = cmd->stop_arg;
|
||||
} else {
|
||||
else
|
||||
devpriv->ui_AiNbrofScans = 0;
|
||||
}
|
||||
|
||||
devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
|
||||
devpriv->ui_AiTimer1 = 0;
|
||||
|
@ -849,9 +838,8 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
|
|||
}
|
||||
/*** EL241003 End ******************************************************************************/
|
||||
|
||||
if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
|
||||
if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
|
||||
i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */
|
||||
}
|
||||
switch (mode) {
|
||||
case 1:
|
||||
/* init timer0 in mode 2 */
|
||||
|
@ -1049,12 +1037,10 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
|
|||
dmalen1 = 4;
|
||||
}
|
||||
} else { /* isn't output buff smaller that our DMA buff? */
|
||||
if (dmalen0 > (devpriv->ui_AiDataLength)) {
|
||||
if (dmalen0 > (devpriv->ui_AiDataLength))
|
||||
dmalen0 = devpriv->ui_AiDataLength;
|
||||
}
|
||||
if (dmalen1 > (devpriv->ui_AiDataLength)) {
|
||||
if (dmalen1 > (devpriv->ui_AiDataLength))
|
||||
dmalen1 = devpriv->ui_AiDataLength;
|
||||
}
|
||||
}
|
||||
devpriv->ui_DmaBufferUsesize[0] = dmalen0;
|
||||
devpriv->ui_DmaBufferUsesize[1] = dmalen1;
|
||||
|
@ -1356,11 +1342,10 @@ int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevi
|
|||
/* store range list to card */
|
||||
us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */
|
||||
|
||||
if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) {
|
||||
if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES)
|
||||
us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */
|
||||
} else {
|
||||
else
|
||||
us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */
|
||||
}
|
||||
|
||||
gain = CR_RANGE(chanlist[i]); /* get gain number */
|
||||
us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
|
||||
|
@ -1514,8 +1499,7 @@ void v_APCI3120_Interrupt(int irq, void *d)
|
|||
/* Check If EOS interrupt */
|
||||
if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
|
||||
|
||||
if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) /* enable this in without DMA ??? */
|
||||
{
|
||||
if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */
|
||||
|
||||
if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
|
||||
ui_Check = 0;
|
||||
|
@ -1966,8 +1950,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
|
|||
APCI3120_DISABLE_EOS_INT;
|
||||
outb(devpriv->b_ModeSelectRegister,
|
||||
devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
|
||||
if (data[0] == APCI3120_TIMER) /* initialize timer */
|
||||
{
|
||||
if (data[0] == APCI3120_TIMER) { /* initialize timer */
|
||||
/* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister |
|
||||
* APCI3120_ENABLE_TIMER_INT; */
|
||||
|
||||
|
@ -2006,8 +1989,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
|
|||
/* timer2 in Timer mode enabled */
|
||||
devpriv->b_Timer2Mode = APCI3120_TIMER;
|
||||
|
||||
} else /* Initialize Watch dog */
|
||||
{
|
||||
} else { /* Initialize Watch dog */
|
||||
|
||||
/* Set the Timer 2 in mode 5(Watchdog) */
|
||||
|
||||
|
@ -2092,8 +2074,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data[0] == 2) /* write new value */
|
||||
{
|
||||
if (data[0] == 2) { /* write new value */
|
||||
if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
|
||||
comedi_error(dev,
|
||||
"write :timer2 not configured in TIMER MODE");
|
||||
|
@ -2113,13 +2094,11 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
|
|||
|
||||
/* Reset FC_TIMER BIT */
|
||||
inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
|
||||
if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */
|
||||
{
|
||||
if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */
|
||||
/* Enable Timer */
|
||||
devpriv->b_ModeSelectRegister =
|
||||
devpriv->b_ModeSelectRegister & 0x0B;
|
||||
} else /* start watch dog */
|
||||
{
|
||||
} else { /* start watch dog */
|
||||
/* Enable WatchDog */
|
||||
devpriv->b_ModeSelectRegister =
|
||||
(devpriv->
|
||||
|
@ -2146,8 +2125,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
|
|||
outb(devpriv->b_ModeSelectRegister,
|
||||
devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
|
||||
|
||||
if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */
|
||||
{
|
||||
if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */
|
||||
/* For Timer mode is Gate2 must be activated **timer started */
|
||||
devpriv->us_OutputRegister =
|
||||
devpriv->
|
||||
|
@ -2299,8 +2277,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice
|
|||
/* combining both words */
|
||||
data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16));
|
||||
|
||||
} else /* Read watch dog status */
|
||||
{
|
||||
} else { /* Read watch dog status */
|
||||
|
||||
us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
|
||||
us_StatusValue =
|
||||
|
@ -2441,10 +2418,9 @@ int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
|
|||
devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
|
||||
devpriv->b_DigitalOutputRegister = 0;
|
||||
}
|
||||
if (!devpriv->b_OutputMemoryStatus) {
|
||||
if (!devpriv->b_OutputMemoryStatus)
|
||||
ui_Temp = 0;
|
||||
|
||||
} /* if(!devpriv->b_OutputMemoryStatus ) */
|
||||
/* if(!devpriv->b_OutputMemoryStatus ) */
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
@ -2504,23 +2480,23 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev,
|
|||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
|
||||
|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
|
||||
| |
|
||||
| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
|
||||
|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Write digiatl output |
|
||||
| |
|
||||
| Task : Write digiatl output |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev |
|
||||
| struct comedi_subdevice *s |
|
||||
| struct comedi_insn *insn |
|
||||
| unsigned int *data |
|
||||
data[0] Value to be written
|
||||
data[1] :1 Set digital o/p ON
|
||||
data[1] 2 Set digital o/p OFF with memory ON
|
||||
| Input Parameters : struct comedi_device *dev |
|
||||
| struct comedi_subdevice *s |
|
||||
| struct comedi_insn *insn |
|
||||
| unsigned int *data |
|
||||
data[0] Value to be written
|
||||
data[1] :1 Set digital o/p ON
|
||||
data[1] 2 Set digital o/p OFF with memory ON
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -2615,8 +2591,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
|
|||
ui_Channel = CR_CHAN(insn->chanspec);
|
||||
|
||||
/* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */
|
||||
if (ui_Range) /* if 1 then unipolar */
|
||||
{
|
||||
if (ui_Range) { /* if 1 then unipolar */
|
||||
|
||||
if (data[0] != 0)
|
||||
data[0] =
|
||||
|
@ -2627,8 +2602,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
|
|||
((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
|
||||
13) | 8192);
|
||||
|
||||
} else /* if 0 then bipolar */
|
||||
{
|
||||
} else { /* if 0 then bipolar */
|
||||
data[0] =
|
||||
((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
|
||||
data[0]);
|
||||
|
@ -2639,8 +2613,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
|
|||
* out put n values at the given channel. printk("\nwaiting for
|
||||
* DA_READY BIT");
|
||||
*/
|
||||
do /* Waiting of DA_READY BIT */
|
||||
{
|
||||
do { /* Waiting of DA_READY BIT */
|
||||
us_TmpValue =
|
||||
((unsigned short) inw(devpriv->iobase +
|
||||
APCI3120_RD_STATUS)) & 0x0001;
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
|
||||
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
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
You should also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
@ -1206,7 +1206,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
|
|||
|
||||
if (b_Channel < 8) {
|
||||
/*****************************************************************************/
|
||||
/* Read port 0 (first digital output port) and set/reset the selcted channel */
|
||||
/* Read port 0 (first digital output port) and set/reset the selected channel */
|
||||
/*****************************************************************************/
|
||||
|
||||
dw_Status = inl(devpriv->iobase + 80);
|
||||
|
@ -1228,7 +1228,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
|
|||
if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
|
||||
== 0xFF) {
|
||||
/*****************************************************************************/
|
||||
/* Read port 2 (first digital output port) and set/reset the selcted channel */
|
||||
/* Read port 2 (first digital output port) and set/reset the selected channel */
|
||||
/*****************************************************************************/
|
||||
|
||||
dw_Status = inl(devpriv->iobase + 112);
|
||||
|
|
|
@ -88,9 +88,9 @@ Configuration options:
|
|||
#define IORANGE_9118 64 /* I hope */
|
||||
#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */
|
||||
|
||||
#define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */
|
||||
#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */
|
||||
#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */
|
||||
#define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
|
||||
#define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
|
||||
#define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
|
||||
#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
|
||||
#define PCI9118_AD_DATA 0x10 /* R: A/D data */
|
||||
#define PCI9118_DA1 0x10 /* W: D/A registers */
|
||||
|
|
|
@ -42,23 +42,23 @@ If you do not specify any options, they will default to
|
|||
option 1: I/O base address. The following table is provided as a help
|
||||
of the hardware jumpers.
|
||||
|
||||
address jumper JADR
|
||||
0x300 1 (factory default)
|
||||
0x320 2
|
||||
0x340 3
|
||||
0x360 4
|
||||
0x380 5
|
||||
0x3A0 6
|
||||
address jumper JADR
|
||||
0x300 1 (factory default)
|
||||
0x320 2
|
||||
0x340 3
|
||||
0x360 4
|
||||
0x380 5
|
||||
0x3A0 6
|
||||
|
||||
option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
|
||||
|
||||
selection comedi_config option JUB
|
||||
bipolar 0 2-3 (factory default)
|
||||
unipolar 1 1-2
|
||||
selection comedi_config option JUB
|
||||
bipolar 0 2-3 (factory default)
|
||||
unipolar 1 1-2
|
||||
|
||||
option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
|
||||
|
||||
selection comedi_config option JCHA JCHB
|
||||
selection comedi_config option JCHA JCHB
|
||||
single-ended 0 1-2 1-2 (factory default)
|
||||
differential 1 2-3 2-3
|
||||
|
||||
|
@ -140,7 +140,7 @@ static const struct adq12b_board adq12b_boards[] = {
|
|||
.ai_bits = 12,
|
||||
.di_chans = 8,
|
||||
.do_chans = 5
|
||||
}*/
|
||||
}*/
|
||||
};
|
||||
|
||||
#define thisboard ((const struct adq12b_board *)dev->board_ptr)
|
||||
|
@ -164,14 +164,15 @@ struct adq12b_private {
|
|||
static int adq12b_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int adq12b_detach(struct comedi_device *dev);
|
||||
|
||||
static struct comedi_driver driver_adq12b = {
|
||||
driver_name:"adq12b",
|
||||
module:THIS_MODULE,
|
||||
attach:adq12b_attach,
|
||||
detach:adq12b_detach,
|
||||
board_name:&adq12b_boards[0].name,
|
||||
offset:sizeof(struct adq12b_board),
|
||||
num_names:ARRAY_SIZE(adq12b_boards),
|
||||
.driver_name = "adq12b",
|
||||
.module = THIS_MODULE,
|
||||
.attach = adq12b_attach,
|
||||
.detach = adq12b_detach,
|
||||
.board_name = &adq12b_boards[0].name,
|
||||
.offset = sizeof(struct adq12b_board),
|
||||
.num_names = ARRAY_SIZE(adq12b_boards),
|
||||
};
|
||||
|
||||
static int adq12b_ai_rinsn(struct comedi_device *dev,
|
||||
|
@ -200,15 +201,16 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
unipolar = it->options[1];
|
||||
differential = it->options[2];
|
||||
|
||||
printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",
|
||||
dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar",
|
||||
printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, "
|
||||
"%s and %s\n", dev->minor, iobase,
|
||||
(unipolar == 1) ? "unipolar" : "bipolar",
|
||||
(differential == 1) ? "differential" : "single-ended");
|
||||
|
||||
/* if no address was specified, try the default 0x300 */
|
||||
if (iobase == 0) {
|
||||
printk
|
||||
("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n",
|
||||
dev->minor);
|
||||
printk(KERN_WARNING "comedi%d: adq12b warning: I/O base "
|
||||
"address not specified. Trying the default 0x300.\n",
|
||||
dev->minor);
|
||||
iobase = 0x300;
|
||||
}
|
||||
|
||||
|
@ -259,11 +261,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
s->n_chan = thisboard->ai_se_chans;
|
||||
}
|
||||
|
||||
if (unipolar) {
|
||||
if (unipolar)
|
||||
s->range_table = &range_adq12b_ai_unipolar;
|
||||
} else {
|
||||
else
|
||||
s->range_table = &range_adq12b_ai_bipolar;
|
||||
}
|
||||
|
||||
s->maxdata = (1 << thisboard->ai_bits) - 1;
|
||||
|
||||
|
@ -289,7 +290,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
s->range_table = &range_digital;
|
||||
s->insn_bits = adq12b_do_insn_bits;
|
||||
|
||||
printk("attached\n");
|
||||
printk(KERN_INFO "attached\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -309,7 +310,7 @@ static int adq12b_detach(struct comedi_device *dev)
|
|||
|
||||
kfree(devpriv);
|
||||
|
||||
printk("comedi%d: adq12b: removed\n", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -344,17 +345,18 @@ static int adq12b_ai_rinsn(struct comedi_device *dev,
|
|||
/* wait for end of convertion */
|
||||
i = 0;
|
||||
do {
|
||||
/* udelay(1); */
|
||||
/* udelay(1); */
|
||||
status = inb(dev->iobase + ADQ12B_STINR);
|
||||
status = status & ADQ12B_EOC;
|
||||
} while (status == 0 && ++i < TIMEOUT);
|
||||
/* } while (++i < 10); */
|
||||
/* } while (++i < 10); */
|
||||
|
||||
/* read data */
|
||||
hi = inb(dev->iobase + ADQ12B_ADHIG);
|
||||
lo = inb(dev->iobase + ADQ12B_ADLOW);
|
||||
|
||||
/* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo); */
|
||||
/* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n",
|
||||
channel, range, status, hi, lo); */
|
||||
data[n] = (hi << 8) | lo;
|
||||
|
||||
}
|
||||
|
|
|
@ -84,9 +84,9 @@ Configuration options:
|
|||
#define PCI171x_DAREF 14 /* W: D/A reference control */
|
||||
#define PCI171x_DI 16 /* R: digi inputs */
|
||||
#define PCI171x_DO 16 /* R: digi inputs */
|
||||
#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */
|
||||
#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */
|
||||
#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */
|
||||
#define PCI171x_CNT0 24 /* R/W: 8254 counter 0 */
|
||||
#define PCI171x_CNT1 26 /* R/W: 8254 counter 1 */
|
||||
#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) */
|
||||
|
@ -724,6 +724,7 @@ static int move_block_from_fifo(struct comedi_device *dev,
|
|||
devpriv->ai_act_scan++;
|
||||
}
|
||||
}
|
||||
s->async->cur_chan = j;
|
||||
DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1034,14 +1035,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
if (!cmd->chanlist_len) {
|
||||
cmd->chanlist_len = 1;
|
||||
err++;
|
||||
}
|
||||
if (cmd->chanlist_len > this_board->n_aichan) {
|
||||
cmd->chanlist_len = this_board->n_aichan;
|
||||
err++;
|
||||
}
|
||||
if (cmd->scan_end_arg != cmd->chanlist_len) {
|
||||
cmd->scan_end_arg = cmd->chanlist_len;
|
||||
err++;
|
||||
|
@ -1230,6 +1223,12 @@ static void setup_channel_list(struct comedi_device *dev,
|
|||
DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
|
||||
devpriv->act_chanlist[i]);
|
||||
}
|
||||
#ifdef PCI171x_PARANOIDCHECK
|
||||
for ( ; i < n_chan; i++) { /* store remainder of channel list */
|
||||
devpriv->act_chanlist[i] =
|
||||
(CR_CHAN(chanlist[i]) << 12) & 0xf000;
|
||||
}
|
||||
#endif
|
||||
|
||||
devpriv->ai_et_MuxVal =
|
||||
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
|
||||
|
|
|
@ -98,7 +98,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
|
|||
int iobase;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
printk("comedi%d: aio_iiro_16: ", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
|
||||
|
||||
dev->board_name = thisboard->name;
|
||||
|
||||
|
@ -140,7 +140,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
|
|||
|
||||
static int aio_iiro_16_detach(struct comedi_device *dev)
|
||||
{
|
||||
printk("comedi%d: aio_iiro_16: remove\n", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor);
|
||||
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, AIO_IIRO_16_SIZE);
|
||||
|
|
|
@ -48,8 +48,8 @@ Passing a zero for an option is the same as leaving it unspecified.
|
|||
|
||||
SUBDEVICES
|
||||
|
||||
PC218E PC212E PC215E/PCI215
|
||||
------------- ------------- -------------
|
||||
PC218E PC212E PC215E/PCI215
|
||||
------------- ------------- -------------
|
||||
Subdevices 7 6 5
|
||||
0 CTR-X1 PPI-X PPI-X
|
||||
1 CTR-X2 CTR-Y1 PPI-Y
|
||||
|
@ -59,8 +59,8 @@ SUBDEVICES
|
|||
5 CTR-Z2 INTERRUPT
|
||||
6 INTERRUPT
|
||||
|
||||
PC214E PC272E/PCI272
|
||||
------------- -------------
|
||||
PC214E PC272E/PCI272
|
||||
------------- -------------
|
||||
Subdevices 4 4
|
||||
0 PPI-X PPI-X
|
||||
1 PPI-Y PPI-Y
|
||||
|
@ -96,8 +96,8 @@ instructions are supported:
|
|||
0 to 7 as follows:
|
||||
|
||||
0. CLK n, the counter channel's dedicated CLK input from the SK1
|
||||
connector. (N.B. for other values, the counter channel's CLKn
|
||||
pin on the SK1 connector is an output!)
|
||||
connector. (N.B. for other values, the counter channel's CLKn
|
||||
pin on the SK1 connector is an output!)
|
||||
1. Internal 10 MHz clock.
|
||||
2. Internal 1 MHz clock.
|
||||
3. Internal 100 kHz clock.
|
||||
|
@ -105,8 +105,8 @@ instructions are supported:
|
|||
5. Internal 1 kHz clock.
|
||||
6. OUT n-1, the output of counter channel n-1 (see note 1 below).
|
||||
7. Ext Clock, the counter chip's dedicated Ext Clock input from
|
||||
the SK1 connector. This pin is shared by all three counter
|
||||
channels on the chip.
|
||||
the SK1 connector. This pin is shared by all three counter
|
||||
channels on the chip.
|
||||
|
||||
INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
|
||||
clock source in data[1]. For internal clock sources, data[2] is set
|
||||
|
@ -120,10 +120,10 @@ instructions are supported:
|
|||
0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
|
||||
1. GND (internal 0V d.c.), i.e. gate permanently disabled.
|
||||
2. GAT n, the counter channel's dedicated GAT input from the SK1
|
||||
connector. (N.B. for other values, the counter channel's GATn
|
||||
pin on the SK1 connector is an output!)
|
||||
connector. (N.B. for other values, the counter channel's GATn
|
||||
pin on the SK1 connector is an output!)
|
||||
3. /OUT n-2, the inverted output of counter channel n-2 (see note
|
||||
2 below).
|
||||
2 below).
|
||||
4. Reserved.
|
||||
5. Reserved.
|
||||
6. Reserved.
|
||||
|
@ -153,8 +153,8 @@ below.
|
|||
|
||||
INTERRUPT SOURCES
|
||||
|
||||
PC218E PC212E PC215E/PCI215
|
||||
------------- ------------- -------------
|
||||
PC218E PC212E PC215E/PCI215
|
||||
------------- ------------- -------------
|
||||
Sources 6 6 6
|
||||
0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
|
||||
1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
|
||||
|
@ -163,8 +163,8 @@ INTERRUPT SOURCES
|
|||
4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
|
||||
5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
|
||||
|
||||
PC214E PC272E/PCI272
|
||||
------------- -------------
|
||||
PC214E PC272E/PCI272
|
||||
------------- -------------
|
||||
Sources 1 6
|
||||
0 JUMPER-J5 PPI-X-C0
|
||||
1 PPI-X-C3
|
||||
|
@ -435,11 +435,13 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table);
|
|||
* Useful for shorthand access to the particular board structure
|
||||
*/
|
||||
#define thisboard ((const struct dio200_board *)dev->board_ptr)
|
||||
#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout])
|
||||
#define thislayout (&dio200_layouts[((struct dio200_board *) \
|
||||
dev->board_ptr)->layout])
|
||||
|
||||
/* this structure is for data unique to this hardware driver. If
|
||||
several hardware drivers keep similar information in this structure,
|
||||
feel free to suggest moving the variable to the struct comedi_device struct. */
|
||||
feel free to suggest moving the variable to the struct comedi_device struct.
|
||||
*/
|
||||
struct dio200_private {
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
struct pci_dev *pci_dev; /* PCI device */
|
||||
|
@ -603,9 +605,8 @@ static void dio200_stop_intr(struct comedi_device *dev,
|
|||
|
||||
subpriv->active = 0;
|
||||
subpriv->enabled_isns = 0;
|
||||
if (subpriv->has_int_sce) {
|
||||
if (subpriv->has_int_sce)
|
||||
outb(0, subpriv->iobase);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -629,16 +630,14 @@ static int dio200_start_intr(struct comedi_device *dev,
|
|||
/* Determine interrupt sources to enable. */
|
||||
isn_bits = 0;
|
||||
if (cmd->chanlist) {
|
||||
for (n = 0; n < cmd->chanlist_len; n++) {
|
||||
for (n = 0; n < cmd->chanlist_len; n++)
|
||||
isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
|
||||
}
|
||||
}
|
||||
isn_bits &= subpriv->valid_isns;
|
||||
/* Enable interrupt sources. */
|
||||
subpriv->enabled_isns = isn_bits;
|
||||
if (subpriv->has_int_sce) {
|
||||
if (subpriv->has_int_sce)
|
||||
outb(isn_bits, subpriv->iobase);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
@ -662,14 +661,13 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
|
||||
spin_lock_irqsave(&subpriv->spinlock, flags);
|
||||
s->async->inttrig = 0;
|
||||
if (subpriv->active) {
|
||||
if (subpriv->active)
|
||||
event = dio200_start_intr(dev, s);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&subpriv->spinlock, flags);
|
||||
|
||||
if (event) {
|
||||
if (event)
|
||||
comedi_event(dev, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -726,9 +724,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
|
|||
* Reenable them NOW to minimize the time they are disabled.
|
||||
*/
|
||||
cur_enabled = subpriv->enabled_isns;
|
||||
if (subpriv->has_int_sce) {
|
||||
if (subpriv->has_int_sce)
|
||||
outb(cur_enabled, subpriv->iobase);
|
||||
}
|
||||
|
||||
if (subpriv->active) {
|
||||
/*
|
||||
|
@ -747,9 +744,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
|
|||
len = s->async->cmd.chanlist_len;
|
||||
for (n = 0; n < len; n++) {
|
||||
ch = CR_CHAN(s->async->cmd.chanlist[n]);
|
||||
if (triggered & (1U << ch)) {
|
||||
if (triggered & (1U << ch))
|
||||
val |= (1U << n);
|
||||
}
|
||||
}
|
||||
/* Write the scan to the buffer. */
|
||||
if (comedi_buf_put(s->async, val)) {
|
||||
|
@ -781,9 +777,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
|
|||
}
|
||||
spin_unlock_irqrestore(&subpriv->spinlock, flags);
|
||||
|
||||
if (oldevents != s->async->events) {
|
||||
if (oldevents != s->async->events)
|
||||
comedi_event(dev, s);
|
||||
}
|
||||
|
||||
return (triggered != 0);
|
||||
}
|
||||
|
@ -798,9 +793,9 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev,
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&subpriv->spinlock, flags);
|
||||
if (subpriv->active) {
|
||||
if (subpriv->active)
|
||||
dio200_stop_intr(dev, s);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&subpriv->spinlock, flags);
|
||||
|
||||
return 0;
|
||||
|
@ -846,7 +841,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev,
|
|||
if (err)
|
||||
return 1;
|
||||
|
||||
/* step 2: make sure trigger sources are unique and mutually compatible */
|
||||
/* step 2: make sure trigger sources are unique and mutually
|
||||
compatible */
|
||||
|
||||
/* these tests are true if more than one _src bit is set */
|
||||
if ((cmd->start_src & (cmd->start_src - 1)) != 0)
|
||||
|
@ -952,9 +948,8 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev,
|
|||
}
|
||||
spin_unlock_irqrestore(&subpriv->spinlock, flags);
|
||||
|
||||
if (event) {
|
||||
if (event)
|
||||
comedi_event(dev, s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -980,9 +975,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
subpriv->valid_isns = valid_isns;
|
||||
spin_lock_init(&subpriv->spinlock);
|
||||
|
||||
if (has_int_sce) {
|
||||
if (has_int_sce)
|
||||
outb(0, subpriv->iobase); /* Disable interrupt sources. */
|
||||
}
|
||||
|
||||
s->private = subpriv;
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
|
@ -1013,10 +1007,7 @@ dio200_subdev_intr_cleanup(struct comedi_device *dev,
|
|||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
|
||||
if (subpriv) {
|
||||
kfree(subpriv);
|
||||
}
|
||||
kfree(subpriv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1027,9 +1018,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
|
|||
struct comedi_device *dev = d;
|
||||
int handled;
|
||||
|
||||
if (!dev->attached) {
|
||||
if (!dev->attached)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (devpriv->intr_sd >= 0) {
|
||||
handled = dio200_handle_read_intr(dev,
|
||||
|
@ -1266,10 +1256,7 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev,
|
|||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
|
||||
if (subpriv) {
|
||||
kfree(subpriv);
|
||||
}
|
||||
kfree(subpriv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1348,9 +1335,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
#endif
|
||||
{
|
||||
ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
dev->iobase = iobase;
|
||||
|
||||
|
@ -1371,17 +1357,17 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
ret = dio200_subdev_8254_init(dev, s, iobase,
|
||||
layout->sdinfo[n],
|
||||
layout->has_clk_gat_sce);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
case sd_8255:
|
||||
/* digital i/o subdevice (8255) */
|
||||
ret = subdev_8255_init(dev, s, 0,
|
||||
iobase + layout->sdinfo[n]);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
case sd_intr:
|
||||
/* 'INTERRUPT' subdevice */
|
||||
|
@ -1392,9 +1378,9 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
layout->sdinfo[n],
|
||||
layout->
|
||||
has_int_sce);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
devpriv->intr_sd = n;
|
||||
} else {
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
|
@ -1407,9 +1393,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
}
|
||||
|
||||
sdx = devpriv->intr_sd;
|
||||
if (sdx >= 0 && sdx < dev->n_subdevices) {
|
||||
if (sdx >= 0 && sdx < dev->n_subdevices)
|
||||
dev->read_subdev = &dev->subdevices[sdx];
|
||||
}
|
||||
|
||||
dev->board_name = thisboard->name;
|
||||
|
||||
|
@ -1434,11 +1419,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
printk("(pci %s) ", pci_name(pci_dev));
|
||||
#endif
|
||||
}
|
||||
if (irq) {
|
||||
if (irq)
|
||||
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
|
||||
} else {
|
||||
else
|
||||
printk("(no irq) ");
|
||||
}
|
||||
|
||||
printk("attached\n");
|
||||
|
||||
|
@ -1461,9 +1445,8 @@ static int dio200_detach(struct comedi_device *dev)
|
|||
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
|
||||
DIO200_DRIVER_NAME);
|
||||
|
||||
if (dev->irq) {
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
}
|
||||
if (dev->subdevices) {
|
||||
layout = thislayout;
|
||||
for (n = 0; n < dev->n_subdevices; n++) {
|
||||
|
@ -1486,22 +1469,19 @@ static int dio200_detach(struct comedi_device *dev)
|
|||
if (devpriv) {
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
if (devpriv->pci_dev) {
|
||||
if (dev->iobase) {
|
||||
if (dev->iobase)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (dev->iobase) {
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, DIO200_IO_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev->board_name) {
|
||||
if (dev->board_name)
|
||||
printk(KERN_INFO "comedi%d: %s removed\n",
|
||||
dev->minor, dev->board_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -78,18 +78,18 @@ unused.
|
|||
*/
|
||||
/* Disable interrupt, also clear any interrupt there */
|
||||
#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \
|
||||
| PLX9052_INTCSR_LI1POL_HIGH \
|
||||
| PLX9052_INTCSR_LI2POL_HIGH \
|
||||
| PLX9052_INTCSR_PCIENAB_DISABLED \
|
||||
| PLX9052_INTCSR_LI1SEL_EDGE \
|
||||
| PLX9052_INTCSR_LI1CLRINT_ASSERTED)
|
||||
| PLX9052_INTCSR_LI1POL_HIGH \
|
||||
| PLX9052_INTCSR_LI2POL_HIGH \
|
||||
| PLX9052_INTCSR_PCIENAB_DISABLED \
|
||||
| PLX9052_INTCSR_LI1SEL_EDGE \
|
||||
| PLX9052_INTCSR_LI1CLRINT_ASSERTED)
|
||||
/* Enable interrupt, also clear any interrupt there. */
|
||||
#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \
|
||||
| PLX9052_INTCSR_LI1POL_HIGH \
|
||||
| PLX9052_INTCSR_LI2POL_HIGH \
|
||||
| PLX9052_INTCSR_PCIENAB_ENABLED \
|
||||
| PLX9052_INTCSR_LI1SEL_EDGE \
|
||||
| PLX9052_INTCSR_LI1CLRINT_ASSERTED)
|
||||
| PLX9052_INTCSR_LI1POL_HIGH \
|
||||
| PLX9052_INTCSR_LI2POL_HIGH \
|
||||
| PLX9052_INTCSR_PCIENAB_ENABLED \
|
||||
| PLX9052_INTCSR_LI1SEL_EDGE \
|
||||
| PLX9052_INTCSR_LI1CLRINT_ASSERTED)
|
||||
|
||||
/*
|
||||
* Board descriptions for Amplicon PC36AT and PCI236.
|
||||
|
@ -150,12 +150,13 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table);
|
|||
|
||||
/* this structure is for data unique to this hardware driver. If
|
||||
several hardware drivers keep similar information in this structure,
|
||||
feel free to suggest moving the variable to the struct comedi_device struct. */
|
||||
feel free to suggest moving the variable to the struct comedi_device struct.
|
||||
*/
|
||||
struct pc236_private {
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
/* PCI device */
|
||||
struct pci_dev *pci_dev;
|
||||
unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
|
||||
unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
|
||||
#endif
|
||||
int enable_irq;
|
||||
};
|
||||
|
@ -345,9 +346,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
#endif
|
||||
{
|
||||
ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
dev->iobase = iobase;
|
||||
|
||||
|
@ -399,11 +399,10 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
printk("(pci %s) ", pci_name(pci_dev));
|
||||
#endif
|
||||
}
|
||||
if (irq) {
|
||||
if (irq)
|
||||
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
|
||||
} else {
|
||||
else
|
||||
printk("(no irq) ");
|
||||
}
|
||||
|
||||
printk("attached\n");
|
||||
|
||||
|
@ -422,27 +421,24 @@ static int pc236_detach(struct comedi_device *dev)
|
|||
{
|
||||
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
|
||||
PC236_DRIVER_NAME);
|
||||
if (devpriv) {
|
||||
if (devpriv)
|
||||
pc236_intr_disable(dev);
|
||||
}
|
||||
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
if (dev->subdevices) {
|
||||
if (dev->subdevices)
|
||||
subdev_8255_cleanup(dev, dev->subdevices + 0);
|
||||
}
|
||||
if (devpriv) {
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
if (devpriv->pci_dev) {
|
||||
if (dev->iobase) {
|
||||
if (dev->iobase)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (dev->iobase) {
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, PC236_IO_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev->board_name) {
|
||||
|
|
|
@ -1536,20 +1536,12 @@ static int pci224_detach(struct comedi_device *dev)
|
|||
|
||||
s = dev->subdevices + 0;
|
||||
/* AO subdevice */
|
||||
if (s->range_table_list) {
|
||||
kfree(s->range_table_list);
|
||||
}
|
||||
kfree(s->range_table_list);
|
||||
}
|
||||
if (devpriv) {
|
||||
if (devpriv->ao_readback) {
|
||||
kfree(devpriv->ao_readback);
|
||||
}
|
||||
if (devpriv->ao_scan_vals) {
|
||||
kfree(devpriv->ao_scan_vals);
|
||||
}
|
||||
if (devpriv->ao_scan_order) {
|
||||
kfree(devpriv->ao_scan_order);
|
||||
}
|
||||
kfree(devpriv->ao_readback);
|
||||
kfree(devpriv->ao_scan_vals);
|
||||
kfree(devpriv->ao_scan_order);
|
||||
if (devpriv->pci_dev) {
|
||||
if (dev->iobase) {
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
|
|
|
@ -45,7 +45,7 @@ http://robot0.ge.uiuc.edu/~spong/mecha/
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/timer.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pnp.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
@ -220,11 +220,11 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel)
|
|||
/* printk("Inside C6X_encInput\n"); */
|
||||
|
||||
enc.value = 0;
|
||||
if (channel == 0) {
|
||||
if (channel == 0)
|
||||
ppcmd = 0x48;
|
||||
} else {
|
||||
else
|
||||
ppcmd = 0x50;
|
||||
}
|
||||
|
||||
WriteByteToHwPort(baseAddr, ppcmd);
|
||||
tmp = ReadByteFromHwPort(baseAddr + 1);
|
||||
while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
|
@ -391,9 +391,8 @@ static int c6xdigio_ei_insn_read(struct comedi_device *dev,
|
|||
int n;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
for (n = 0; n < insn->n; n++)
|
||||
data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -420,9 +419,9 @@ static void board_init(struct comedi_device *dev)
|
|||
|
||||
static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
|
||||
/* Standard LPT Printer Port */
|
||||
{.id = "PNP0400",.driver_data = 0},
|
||||
{.id = "PNP0400", .driver_data = 0},
|
||||
/* ECP Printer Port */
|
||||
{.id = "PNP0401",.driver_data = 0},
|
||||
{.id = "PNP0401", .driver_data = 0},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -452,15 +451,14 @@ static int c6xdigio_attach(struct comedi_device *dev,
|
|||
if (result < 0)
|
||||
return result;
|
||||
|
||||
/* Make sure that PnP ports gets activated */
|
||||
/* Make sure that PnP ports get activated */
|
||||
pnp_register_driver(&c6xdigio_pnp_driver);
|
||||
|
||||
irq = it->options[1];
|
||||
if (irq > 0) {
|
||||
if (irq > 0)
|
||||
printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
|
||||
} else if (irq == 0) {
|
||||
else if (irq == 0)
|
||||
printk("comedi%d: no irq\n", dev->minor);
|
||||
}
|
||||
|
||||
s = dev->subdevices + 0;
|
||||
/* pwm output subdevice */
|
||||
|
@ -483,19 +481,19 @@ static int c6xdigio_attach(struct comedi_device *dev,
|
|||
s->maxdata = 0xffffff;
|
||||
s->range_table = &range_unknown;
|
||||
|
||||
/* s = dev->subdevices + 2; */
|
||||
/* s = dev->subdevices + 2; */
|
||||
/* pwm output subdevice */
|
||||
/* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
|
||||
/* s->subdev_flags = SDF_WRITEABLE; */
|
||||
/* s->n_chan = 1; */
|
||||
/* s->trig[0] = c6xdigio_ei_init; */
|
||||
/* s->insn_read = c6xdigio_ei_init_insn_read; */
|
||||
/* s->insn_write = c6xdigio_ei_init_insn_write; */
|
||||
/* s->maxdata = 0xFFFF; // Really just a don't care */
|
||||
/* s->range_table = &range_unknown; // Not sure what to put here */
|
||||
/* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
|
||||
/* s->subdev_flags = SDF_WRITEABLE; */
|
||||
/* s->n_chan = 1; */
|
||||
/* s->trig[0] = c6xdigio_ei_init; */
|
||||
/* s->insn_read = c6xdigio_ei_init_insn_read; */
|
||||
/* s->insn_write = c6xdigio_ei_init_insn_write; */
|
||||
/* s->maxdata = 0xFFFF; // Really just a don't care */
|
||||
/* s->range_table = &range_unknown; // Not sure what to put here */
|
||||
|
||||
/* I will call this init anyway but more than likely the DSP board will not be connect */
|
||||
/* when device driver is loaded. */
|
||||
/* I will call this init anyway but more than likely the DSP board */
|
||||
/* will not be connected when device driver is loaded. */
|
||||
board_init(dev);
|
||||
|
||||
return 0;
|
||||
|
@ -503,16 +501,17 @@ static int c6xdigio_attach(struct comedi_device *dev,
|
|||
|
||||
static int c6xdigio_detach(struct comedi_device *dev)
|
||||
{
|
||||
/* board_halt(dev); may not need this */
|
||||
/* board_halt(dev); may not need this */
|
||||
|
||||
printk("comedi%d: c6xdigio: remove\n", dev->minor);
|
||||
|
||||
if (dev->iobase) {
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, C6XDIGIO_SIZE);
|
||||
}
|
||||
if (dev->irq) {
|
||||
|
||||
/* Not using IRQ so I am not sure if I need this */
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
} /* Not using IRQ so I am not sure if I need this */
|
||||
|
||||
pnp_unregister_driver(&c6xdigio_pnp_driver);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -518,7 +518,7 @@ static int trimpot_7376_write(struct comedi_device *dev, uint8_t value);
|
|||
static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
|
||||
uint8_t value);
|
||||
static int nvram_read(struct comedi_device *dev, unsigned int address,
|
||||
uint8_t * data);
|
||||
uint8_t *data);
|
||||
|
||||
static inline unsigned int cal_enable_bits(struct comedi_device *dev)
|
||||
{
|
||||
|
@ -760,9 +760,8 @@ static int cb_pcidas_detach(struct comedi_device *dev)
|
|||
if (dev->subdevices)
|
||||
subdev_8255_cleanup(dev, dev->subdevices + 2);
|
||||
if (devpriv && devpriv->pci_dev) {
|
||||
if (devpriv->s5933_config) {
|
||||
if (devpriv->s5933_config)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
}
|
||||
|
||||
|
@ -1248,9 +1247,8 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev,
|
|||
cmd->flags & TRIG_ROUND_MASK);
|
||||
|
||||
/* set number of conversions */
|
||||
if (cmd->stop_src == TRIG_COUNT) {
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->count = cmd->chanlist_len * cmd->stop_arg;
|
||||
}
|
||||
/* enable interrupts */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
devpriv->adc_fifo_bits |= INTE;
|
||||
|
@ -1449,9 +1447,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
|
|||
devpriv->ao_divisor2, 2);
|
||||
}
|
||||
/* set number of conversions */
|
||||
if (cmd->stop_src == TRIG_COUNT) {
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
|
||||
}
|
||||
/* set pacer source */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
switch (cmd->scan_begin_src) {
|
||||
|
@ -1494,9 +1491,8 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
|
|||
num_points * sizeof(short));
|
||||
num_points = num_bytes / sizeof(short);
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT) {
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->ao_count -= num_points;
|
||||
}
|
||||
/* write data to board's fifo */
|
||||
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
|
||||
|
||||
|
@ -1534,9 +1530,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
|
|||
static const int timeout = 10000;
|
||||
unsigned long flags;
|
||||
|
||||
if (dev->attached == 0) {
|
||||
if (dev->attached == 0)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
async = s->async;
|
||||
async->events = 0;
|
||||
|
@ -1558,15 +1553,13 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
|
|||
|
||||
status = inw(devpriv->control_status + INT_ADCFIFO);
|
||||
#ifdef CB_PCIDAS_DEBUG
|
||||
if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
|
||||
if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0)
|
||||
comedi_error(dev, "spurious interrupt");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check for analog output interrupt */
|
||||
if (status & (DAHFI | DAEMI)) {
|
||||
if (status & (DAHFI | DAEMI))
|
||||
handle_ao_interrupt(dev, status);
|
||||
}
|
||||
/* check for analog input interrupts */
|
||||
/* if fifo half-full */
|
||||
if (status & ADHFI) {
|
||||
|
@ -1675,9 +1668,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
|
|||
num_points * sizeof(short));
|
||||
num_points = num_bytes / sizeof(short);
|
||||
|
||||
if (async->cmd.stop_src == TRIG_COUNT) {
|
||||
if (async->cmd.stop_src == TRIG_COUNT)
|
||||
devpriv->ao_count -= num_points;
|
||||
}
|
||||
/* write data to board's fifo */
|
||||
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
|
||||
num_points);
|
||||
|
@ -1852,7 +1844,7 @@ static int wait_for_nvram_ready(unsigned long s5933_base_addr)
|
|||
}
|
||||
|
||||
static int nvram_read(struct comedi_device *dev, unsigned int address,
|
||||
uint8_t * data)
|
||||
uint8_t *data)
|
||||
{
|
||||
unsigned long iobase = devpriv->s5933_config;
|
||||
|
||||
|
|
|
@ -410,9 +410,8 @@ static int cb_pcidda_detach(struct comedi_device *dev)
|
|||
*/
|
||||
if (devpriv) {
|
||||
if (devpriv->pci_dev) {
|
||||
if (devpriv->dac) {
|
||||
if (devpriv->dac)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
}
|
||||
}
|
||||
|
@ -677,9 +676,8 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
|
|||
|
||||
for (i = 1; i <= value_width; i++) {
|
||||
/* read bits most significant bit first */
|
||||
if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) {
|
||||
if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
|
||||
value |= 1 << (value_width - i);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
|
@ -716,9 +714,8 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
|
|||
/* send serial output stream to eeprom */
|
||||
cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
|
||||
/* deactivate caldacs (one caldac for every two channels) */
|
||||
for (i = 0; i < max_num_caldacs; i++) {
|
||||
for (i = 0; i < max_num_caldacs; i++)
|
||||
cal2_bits |= DESELECT_CALDAC_BIT(i);
|
||||
}
|
||||
outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
|
||||
|
||||
/* tell eeprom we want to read */
|
||||
|
@ -756,9 +753,8 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev,
|
|||
*/
|
||||
cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
|
||||
/* deactivate caldacs (one caldac for every two channels) */
|
||||
for (i = 0; i < max_num_caldacs; i++) {
|
||||
for (i = 0; i < max_num_caldacs; i++)
|
||||
cal2_bits |= DESELECT_CALDAC_BIT(i);
|
||||
}
|
||||
/* activate the caldac we want */
|
||||
cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
|
||||
outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
|
||||
|
|
|
@ -283,17 +283,15 @@ static int pcidio_detach(struct comedi_device *dev)
|
|||
printk("comedi%d: cb_pcidio: remove\n", dev->minor);
|
||||
if (devpriv) {
|
||||
if (devpriv->pci_dev) {
|
||||
if (devpriv->dio_reg_base) {
|
||||
if (devpriv->dio_reg_base)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
}
|
||||
}
|
||||
if (dev->subdevices) {
|
||||
int i;
|
||||
for (i = 0; i < thisboard->n_8255; i++) {
|
||||
for (i = 0; i < thisboard->n_8255; i++)
|
||||
subdev_8255_cleanup(dev, dev->subdevices + i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -330,11 +330,10 @@ found:
|
|||
|
||||
s = dev->subdevices + 2;
|
||||
/* digital i/o subdevice */
|
||||
if (thisboard->has_dio) {
|
||||
if (thisboard->has_dio)
|
||||
subdev_8255_init(dev, s, NULL, devpriv->BADR4);
|
||||
} else {
|
||||
else
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
}
|
||||
|
||||
printk("attached\n");
|
||||
|
||||
|
@ -365,9 +364,8 @@ static int cb_pcimdas_detach(struct comedi_device *dev)
|
|||
free_irq(dev->irq, dev);
|
||||
if (devpriv) {
|
||||
if (devpriv->pci_dev) {
|
||||
if (devpriv->BADR0) {
|
||||
if (devpriv->BADR0)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,11 +284,10 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
s->n_chan = thisboard->ao_chans;
|
||||
s->maxdata = figure_out_maxdata(thisboard->ao_bits);
|
||||
/* this is hard-coded here */
|
||||
if (it->options[2]) {
|
||||
if (it->options[2])
|
||||
s->range_table = &range_bipolar10;
|
||||
} else {
|
||||
else
|
||||
s->range_table = &range_bipolar5;
|
||||
}
|
||||
s->insn_write = &ao_winsn;
|
||||
s->insn_read = &ao_rinsn;
|
||||
|
||||
|
@ -337,9 +336,8 @@ static int detach(struct comedi_device *dev)
|
|||
}
|
||||
|
||||
if (devpriv->pci_dev) {
|
||||
if (devpriv->registers) {
|
||||
if (devpriv->registers)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -417,7 +417,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
int sdev = -1, nchans, tmp;
|
||||
struct BondedDevice *bdev = NULL;
|
||||
|
||||
if (minor < 0 || minor > COMEDI_NUM_BOARD_MINORS) {
|
||||
if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) {
|
||||
ERROR("Minor %d is invalid!\n", minor);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -173,9 +173,8 @@ static int contec_detach(struct comedi_device *dev)
|
|||
printk("comedi%d: contec: remove\n", dev->minor);
|
||||
|
||||
if (devpriv && devpriv->pci_dev) {
|
||||
if (dev->iobase) {
|
||||
if (dev->iobase)
|
||||
comedi_pci_disable(devpriv->pci_dev);
|
||||
}
|
||||
pci_dev_put(devpriv->pci_dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ This is the PCMCIA-specific support split off from the
|
|||
das08 driver.
|
||||
|
||||
Options (for pcm-das08):
|
||||
NONE
|
||||
NONE
|
||||
|
||||
Command support does not exist, but could be added for this board.
|
||||
*/
|
||||
|
@ -52,7 +52,7 @@ Command support does not exist, but could be added for this board.
|
|||
#include <pcmcia/cistpl.h>
|
||||
#include <pcmcia/ds.h>
|
||||
|
||||
static struct pcmcia_device *cur_dev = NULL;
|
||||
static struct pcmcia_device *cur_dev;
|
||||
|
||||
#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ This driver has suffered bitrot.
|
|||
|
||||
#define DAS6402_SIZE 16
|
||||
|
||||
#define N_WORDS 3000*64
|
||||
#define N_WORDS (3000*64)
|
||||
|
||||
#define STOP 0
|
||||
#define START 1
|
||||
|
|
|
@ -399,9 +399,8 @@ static irqreturn_t das800_interrupt(int irq, void *d)
|
|||
} else {
|
||||
fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */
|
||||
}
|
||||
if (fifo_empty) {
|
||||
if (fifo_empty)
|
||||
break;
|
||||
}
|
||||
/* strip off extraneous bits for 12 bit cards */
|
||||
if (thisboard->resolution == 12)
|
||||
dataPoint = (dataPoint >> 4) & 0xfff;
|
||||
|
@ -457,9 +456,8 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
int board;
|
||||
|
||||
printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
|
||||
if (irq) {
|
||||
if (irq)
|
||||
printk(", irq %u", irq);
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
/* allocate and initialize dev->private */
|
||||
|
|
|
@ -1048,11 +1048,10 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev,
|
|||
* value COMEDI_INPUT or COMEDI_OUTPUT. */
|
||||
|
||||
/* if output clear the bit, otherwise set it */
|
||||
if (data[0] == COMEDI_OUTPUT) {
|
||||
if (data[0] == COMEDI_OUTPUT)
|
||||
devpriv->dio_config &= ~chanbit;
|
||||
} else {
|
||||
else
|
||||
devpriv->dio_config |= chanbit;
|
||||
}
|
||||
/* get access to the DIO regs */
|
||||
dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
|
||||
/* set the DIO's to the new configuration setting */
|
||||
|
|
|
@ -18,10 +18,10 @@ Configuration options:
|
|||
[1] - unused
|
||||
[2] - A/D reference 0=differential, 1=single-ended
|
||||
[3] - A/D range
|
||||
0 = [-10,10]
|
||||
0 = [-10, 10]
|
||||
1 = [0,10]
|
||||
[4] - D/A 0 range
|
||||
0 = [-10,10]
|
||||
0 = [-10, 10]
|
||||
1 = [-5,5]
|
||||
2 = [-2.5,2.5]
|
||||
3 = [0,10]
|
||||
|
@ -279,9 +279,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data)
|
|||
|
||||
do {
|
||||
stat = inb_p(dev->iobase + DT2801_STATUS);
|
||||
if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) {
|
||||
if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY))
|
||||
return stat;
|
||||
}
|
||||
if (stat & DT_S_DATA_OUT_READY) {
|
||||
*data = inb_p(dev->iobase + DT2801_DATA);
|
||||
return 0;
|
||||
|
@ -315,9 +314,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
|
|||
do {
|
||||
stat = inb_p(dev->iobase + DT2801_STATUS);
|
||||
|
||||
if (stat & DT_S_COMPOSITE_ERROR) {
|
||||
if (stat & DT_S_COMPOSITE_ERROR)
|
||||
return stat;
|
||||
}
|
||||
if (!(stat & DT_S_DATA_IN_FULL)) {
|
||||
outb_p(data & 0xff, dev->iobase + DT2801_DATA);
|
||||
return 0;
|
||||
|
@ -354,18 +352,15 @@ static int dt2801_wait_for_ready(struct comedi_device *dev)
|
|||
int stat;
|
||||
|
||||
stat = inb_p(dev->iobase + DT2801_STATUS);
|
||||
if (stat & DT_S_READY) {
|
||||
if (stat & DT_S_READY)
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
stat = inb_p(dev->iobase + DT2801_STATUS);
|
||||
|
||||
if (stat & DT_S_COMPOSITE_ERROR) {
|
||||
if (stat & DT_S_COMPOSITE_ERROR)
|
||||
return stat;
|
||||
}
|
||||
if (stat & DT_S_READY) {
|
||||
if (stat & DT_S_READY)
|
||||
return 0;
|
||||
}
|
||||
} while (--timeout > 0);
|
||||
|
||||
return -ETIME;
|
||||
|
@ -382,9 +377,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command)
|
|||
printk
|
||||
("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
|
||||
}
|
||||
if (!(stat & DT_S_READY)) {
|
||||
if (!(stat & DT_S_READY))
|
||||
printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
|
||||
}
|
||||
outb_p(command, dev->iobase + DT2801_CMD);
|
||||
|
||||
return 0;
|
||||
|
@ -418,9 +412,8 @@ static int dt2801_reset(struct comedi_device *dev)
|
|||
if (stat & DT_S_READY)
|
||||
break;
|
||||
} while (timeout--);
|
||||
if (!timeout) {
|
||||
if (!timeout)
|
||||
printk("dt2801: timeout 1 status=0x%02x\n", stat);
|
||||
}
|
||||
|
||||
/* printk("dt2801: reading dummy\n"); */
|
||||
/* dt2801_readdata(dev,&board_code); */
|
||||
|
@ -436,9 +429,8 @@ static int dt2801_reset(struct comedi_device *dev)
|
|||
if (stat & DT_S_READY)
|
||||
break;
|
||||
} while (timeout--);
|
||||
if (!timeout) {
|
||||
if (!timeout)
|
||||
printk("dt2801: timeout 2 status=0x%02x\n", stat);
|
||||
}
|
||||
|
||||
DPRINTK("dt2801: reading code\n");
|
||||
dt2801_readdata(dev, &board_code);
|
||||
|
@ -623,11 +615,10 @@ static int dt2801_detach(struct comedi_device *dev)
|
|||
static int dt2801_error(struct comedi_device *dev, int stat)
|
||||
{
|
||||
if (stat < 0) {
|
||||
if (stat == -ETIME) {
|
||||
if (stat == -ETIME)
|
||||
printk("dt2801: timeout\n");
|
||||
} else {
|
||||
else
|
||||
printk("dt2801: error %d\n", stat);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
printk("dt2801: error status 0x%02x, resetting...\n", stat);
|
||||
|
|
|
@ -34,19 +34,19 @@ Configuration options:
|
|||
[0] - I/O port base base address
|
||||
[1] - IRQ (unused)
|
||||
[2] - Voltage unipolar/bipolar configuration
|
||||
0 == unipolar 5V (0V -- +5V)
|
||||
1 == bipolar 5V (-5V -- +5V)
|
||||
0 == unipolar 5V (0V -- +5V)
|
||||
1 == bipolar 5V (-5V -- +5V)
|
||||
[3] - Current offset configuration
|
||||
0 == disabled (0mA -- +32mAV)
|
||||
1 == enabled (+4mA -- +20mAV)
|
||||
0 == disabled (0mA -- +32mAV)
|
||||
1 == enabled (+4mA -- +20mAV)
|
||||
[4] - Firmware program configuration
|
||||
0 == program 1 (see manual table 5-4)
|
||||
1 == program 2 (see manual table 5-4)
|
||||
2 == program 3 (see manual table 5-4)
|
||||
3 == program 4 (see manual table 5-4)
|
||||
0 == program 1 (see manual table 5-4)
|
||||
1 == program 2 (see manual table 5-4)
|
||||
2 == program 3 (see manual table 5-4)
|
||||
3 == program 4 (see manual table 5-4)
|
||||
[5] - Analog output 0 range configuration
|
||||
0 == voltage
|
||||
1 == current
|
||||
0 == voltage
|
||||
1 == current
|
||||
[6] - Analog output 1 range configuration (same options)
|
||||
[7] - Analog output 2 range configuration (same options)
|
||||
[8] - Analog output 3 range configuration (same options)
|
||||
|
@ -61,17 +61,11 @@ Configuration options:
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
|
||||
RANGE_mA(0,
|
||||
32)
|
||||
}
|
||||
};
|
||||
static const struct comedi_lrange
|
||||
range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} };
|
||||
|
||||
static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
|
||||
RANGE_mA(4,
|
||||
20)
|
||||
}
|
||||
};
|
||||
static const struct comedi_lrange
|
||||
range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} };
|
||||
|
||||
#define DT2815_SIZE 2
|
||||
|
||||
|
@ -118,9 +112,8 @@ static int dt2815_ao_insn_read(struct comedi_device *dev,
|
|||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
for (i = 0; i < insn->n; i++)
|
||||
data[i] = devpriv->ao_readback[chan];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -139,9 +132,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
|
||||
status = dt2815_wait_for_status(dev, 0x00);
|
||||
if (status != 0) {
|
||||
printk
|
||||
("dt2815: failed to write low byte on %d reason %x\n",
|
||||
chan, status);
|
||||
printk(KERN_WARNING "dt2815: failed to write low byte "
|
||||
"on %d reason %x\n", chan, status);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -149,9 +141,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
|
||||
status = dt2815_wait_for_status(dev, 0x10);
|
||||
if (status != 0x10) {
|
||||
printk
|
||||
("dt2815: failed to write high byte on %d reason %x\n",
|
||||
chan, status);
|
||||
printk(KERN_WARNING "dt2815: failed to write high byte "
|
||||
"on %d reason %x\n", chan, status);
|
||||
return -EBUSY;
|
||||
}
|
||||
devpriv->ao_readback[chan] = data[i];
|
||||
|
@ -163,24 +154,24 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
|||
options[0] Board base address
|
||||
options[1] IRQ (not applicable)
|
||||
options[2] Voltage unipolar/bipolar configuration
|
||||
0 == unipolar 5V (0V -- +5V)
|
||||
1 == bipolar 5V (-5V -- +5V)
|
||||
0 == unipolar 5V (0V -- +5V)
|
||||
1 == bipolar 5V (-5V -- +5V)
|
||||
options[3] Current offset configuration
|
||||
0 == disabled (0mA -- +32mAV)
|
||||
1 == enabled (+4mA -- +20mAV)
|
||||
0 == disabled (0mA -- +32mAV)
|
||||
1 == enabled (+4mA -- +20mAV)
|
||||
options[4] Firmware program configuration
|
||||
0 == program 1 (see manual table 5-4)
|
||||
1 == program 2 (see manual table 5-4)
|
||||
2 == program 3 (see manual table 5-4)
|
||||
3 == program 4 (see manual table 5-4)
|
||||
0 == program 1 (see manual table 5-4)
|
||||
1 == program 2 (see manual table 5-4)
|
||||
2 == program 3 (see manual table 5-4)
|
||||
3 == program 4 (see manual table 5-4)
|
||||
options[5] Analog output 0 range configuration
|
||||
0 == voltage
|
||||
1 == current
|
||||
0 == voltage
|
||||
1 == current
|
||||
options[6] Analog output 1 range configuration
|
||||
...
|
||||
options[12] Analog output 7 range configuration
|
||||
0 == voltage
|
||||
1 == current
|
||||
0 == voltage
|
||||
1 == current
|
||||
*/
|
||||
|
||||
static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
@ -191,9 +182,9 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
unsigned long iobase;
|
||||
|
||||
iobase = it->options[0];
|
||||
printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
|
||||
printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
|
||||
if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
|
||||
printk("I/O port conflict\n");
|
||||
printk(KERN_WARNING "I/O port conflict\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -236,19 +227,17 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
unsigned int program;
|
||||
program = (it->options[4] & 0x3) << 3 | 0x7;
|
||||
outb(program, dev->iobase + DT2815_DATA);
|
||||
printk(", program: 0x%x (@t=%d)\n", program, i);
|
||||
printk(KERN_INFO ", program: 0x%x (@t=%d)\n",
|
||||
program, i);
|
||||
break;
|
||||
} else if (status != 0x00) {
|
||||
printk("dt2815: unexpected status 0x%x (@t=%d)\n",
|
||||
status, i);
|
||||
if (status & 0x60) {
|
||||
printk(KERN_WARNING "dt2815: unexpected status 0x%x "
|
||||
"(@t=%d)\n", status, i);
|
||||
if (status & 0x60)
|
||||
outb(0x00, dev->iobase + DT2815_STATUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -260,7 +249,7 @@ static void dt2815_free_resources(struct comedi_device *dev)
|
|||
|
||||
static int dt2815_detach(struct comedi_device *dev)
|
||||
{
|
||||
printk("comedi%d: dt2815: remove\n", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: dt2815: remove\n", dev->minor);
|
||||
|
||||
dt2815_free_resources(dev);
|
||||
|
||||
|
|
|
@ -264,7 +264,7 @@ struct dt9812_usb_cmd {
|
|||
|
||||
static DECLARE_MUTEX(dt9812_mutex);
|
||||
|
||||
static struct usb_device_id dt9812_table[] = {
|
||||
static const struct usb_device_id dt9812_table[] = {
|
||||
{USB_DEVICE(0x0867, 0x9812)},
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
|
|
|
@ -76,14 +76,14 @@ static int fl512_ai_insn(struct comedi_device *dev,
|
|||
unsigned long iobase = dev->iobase;
|
||||
|
||||
for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */
|
||||
/* XXX probably can move next step out of for() loop -- will make
|
||||
* AI a little bit faster. */
|
||||
/* XXX probably can move next step out of for() loop -- will
|
||||
* make AI a little bit faster. */
|
||||
outb(chan, iobase + 2); /* select chan */
|
||||
outb(0, iobase + 3); /* start conversion */
|
||||
/* XXX should test "done" flag instead of delay */
|
||||
udelay(30); /* sleep 30 usec */
|
||||
lo_byte = inb(iobase + 2); /* low 8 byte */
|
||||
hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
|
||||
hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
|
||||
data[n] = lo_byte + (hi_byte << 8);
|
||||
}
|
||||
return n;
|
||||
|
@ -101,8 +101,10 @@ static int fl512_ao_insn(struct comedi_device *dev,
|
|||
unsigned long iobase = dev->iobase; /* get base address */
|
||||
|
||||
for (n = 0; n < insn->n; n++) { /* write n data set */
|
||||
outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */
|
||||
outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high byte */
|
||||
/* write low byte */
|
||||
outb(data[n] & 0x0ff, iobase + 4 + 2 * chan);
|
||||
/* write high byte */
|
||||
outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan);
|
||||
inb(iobase + 4 + 2 * chan); /* trig */
|
||||
|
||||
devpriv->ao_readback[chan] = data[n];
|
||||
|
@ -121,9 +123,8 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
|
|||
int n;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
for (n = 0; n < insn->n; n++)
|
||||
data[n] = devpriv->ao_readback[chan];
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -134,13 +135,15 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
|
|||
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
unsigned long iobase;
|
||||
struct comedi_subdevice *s; /* pointer to the subdevice:
|
||||
Analog in, Analog out, ( not made ->and Digital IO) */
|
||||
|
||||
/* pointer to the subdevice: Analog in, Analog out,
|
||||
(not made ->and Digital IO) */
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
iobase = it->options[0];
|
||||
printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
|
||||
printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase);
|
||||
if (!request_region(iobase, FL512_SIZE, "fl512")) {
|
||||
printk(" I/O port conflict\n");
|
||||
printk(KERN_WARNING " I/O port conflict\n");
|
||||
return -EIO;
|
||||
}
|
||||
dev->iobase = iobase;
|
||||
|
@ -149,7 +152,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
return -ENOMEM;
|
||||
|
||||
#if DEBUG
|
||||
printk("malloc ok\n");
|
||||
printk(KERN_DEBUG "malloc ok\n");
|
||||
#endif
|
||||
|
||||
if (alloc_subdevices(dev, 2) < 0)
|
||||
|
@ -160,24 +163,37 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
|||
*/
|
||||
/* Analog indput */
|
||||
s = dev->subdevices + 0;
|
||||
s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */
|
||||
s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */
|
||||
s->n_chan = 16; /* Number of Analog input channels */
|
||||
s->maxdata = 0x0fff; /* accept only 12 bits of data */
|
||||
s->range_table = &range_fl512; /* device use one of the ranges */
|
||||
s->insn_read = fl512_ai_insn; /* function to call when read AD */
|
||||
printk("comedi: fl512: subdevice 0 initialized\n");
|
||||
/* define subdevice as Analog In */
|
||||
s->type = COMEDI_SUBD_AI;
|
||||
/* you can read it from userspace */
|
||||
s->subdev_flags = SDF_READABLE | SDF_GROUND;
|
||||
/* Number of Analog input channels */
|
||||
s->n_chan = 16;
|
||||
/* accept only 12 bits of data */
|
||||
s->maxdata = 0x0fff;
|
||||
/* device use one of the ranges */
|
||||
s->range_table = &range_fl512;
|
||||
/* function to call when read AD */
|
||||
s->insn_read = fl512_ai_insn;
|
||||
printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n");
|
||||
|
||||
/* Analog output */
|
||||
s = dev->subdevices + 1;
|
||||
s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */
|
||||
s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */
|
||||
s->n_chan = 2; /* Number of Analog output channels */
|
||||
s->maxdata = 0x0fff; /* accept only 12 bits of data */
|
||||
s->range_table = &range_fl512; /* device use one of the ranges */
|
||||
s->insn_write = fl512_ao_insn; /* function to call when write DA */
|
||||
s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */
|
||||
printk("comedi: fl512: subdevice 1 initialized\n");
|
||||
/* define subdevice as Analog OUT */
|
||||
s->type = COMEDI_SUBD_AO;
|
||||
/* you can write it from userspace */
|
||||
s->subdev_flags = SDF_WRITABLE;
|
||||
/* Number of Analog output channels */
|
||||
s->n_chan = 2;
|
||||
/* accept only 12 bits of data */
|
||||
s->maxdata = 0x0fff;
|
||||
/* device use one of the ranges */
|
||||
s->range_table = &range_fl512;
|
||||
/* function to call when write DA */
|
||||
s->insn_write = fl512_ao_insn;
|
||||
/* function to call when reading DA */
|
||||
s->insn_read = fl512_ao_insn_readback;
|
||||
printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -186,6 +202,6 @@ static int fl512_detach(struct comedi_device *dev)
|
|||
{
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, FL512_SIZE);
|
||||
printk("comedi%d: fl512: dummy i detach\n", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -954,6 +954,8 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE("comedi/jr3pci.idm");
|
||||
|
||||
static int jr3_pci_detach(struct comedi_device *dev)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -284,7 +284,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
|
|||
outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
|
||||
/* printk("Channel %d: \n", insn->chanspec); */
|
||||
if (!insn->n) {
|
||||
printk("MPC624: Warning, no data to aquire\n");
|
||||
printk("MPC624: Warning, no data to acquire\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,13 @@
|
|||
/*
|
||||
Driver: ni_65xx
|
||||
Description: National Instruments 65xx static dio boards
|
||||
Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net>
|
||||
Author: Jon Grierson <jd@renko.co.uk>,
|
||||
Frank Mori Hess <fmhess@users.sourceforge.net>
|
||||
Status: testing
|
||||
Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511,
|
||||
PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515,
|
||||
PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521,
|
||||
PCI-6528, PXI-6528
|
||||
Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
|
||||
PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
|
||||
PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
|
||||
PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
|
||||
Updated: Wed Oct 18 08:59:11 EDT 2006
|
||||
|
||||
Based on the PCI-6527 driver by ds.
|
||||
|
@ -418,9 +419,10 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
|
|||
return -EINVAL;
|
||||
base_bitfield_channel = CR_CHAN(insn->chanspec);
|
||||
for (j = 0; j < max_ports_per_bitfield; ++j) {
|
||||
const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j;
|
||||
const unsigned port_offset =
|
||||
ni_65xx_port_by_channel(base_bitfield_channel) + j;
|
||||
const unsigned port =
|
||||
sprivate(s)->base_port + port_offset;
|
||||
sprivate(s)->base_port + port_offset;
|
||||
unsigned base_port_channel;
|
||||
unsigned port_mask, port_data, port_read_bits;
|
||||
int bitshift;
|
||||
|
@ -463,11 +465,11 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
|
|||
* subdevice.) */
|
||||
port_read_bits ^= 0xFF;
|
||||
}
|
||||
if (bitshift > 0) {
|
||||
if (bitshift > 0)
|
||||
port_read_bits <<= bitshift;
|
||||
} else {
|
||||
else
|
||||
port_read_bits >>= -bitshift;
|
||||
}
|
||||
|
||||
read_bits |= port_read_bits;
|
||||
}
|
||||
data[1] = read_bits;
|
||||
|
@ -532,7 +534,8 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
|
|||
if (err)
|
||||
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 (err)
|
||||
return 2;
|
||||
|
@ -652,7 +655,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
|
|||
unsigned i;
|
||||
int ret;
|
||||
|
||||
printk("comedi%d: ni_65xx:", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: ni_65xx:", dev->minor);
|
||||
|
||||
ret = alloc_private(dev, sizeof(struct ni_65xx_private));
|
||||
if (ret < 0)
|
||||
|
@ -664,15 +667,15 @@ static int ni_65xx_attach(struct comedi_device *dev,
|
|||
|
||||
ret = mite_setup(private(dev)->mite);
|
||||
if (ret < 0) {
|
||||
printk("error setting up mite\n");
|
||||
printk(KERN_WARNING "error setting up mite\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev->board_name = board(dev)->name;
|
||||
dev->irq = mite_irq(private(dev)->mite);
|
||||
printk(" %s", dev->board_name);
|
||||
printk(KERN_INFO " %s", dev->board_name);
|
||||
|
||||
printk(" ID=0x%02x",
|
||||
printk(KERN_INFO " ID=0x%02x",
|
||||
readb(private(dev)->mite->daq_io_addr + ID_Register));
|
||||
|
||||
ret = alloc_subdevices(dev, 4);
|
||||
|
@ -773,7 +776,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
|
|||
"ni_65xx", dev);
|
||||
if (ret < 0) {
|
||||
dev->irq = 0;
|
||||
printk(" irq not available");
|
||||
printk(KERN_WARNING " irq not available");
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
|
@ -790,21 +793,17 @@ static int ni_65xx_detach(struct comedi_device *dev)
|
|||
Master_Interrupt_Control);
|
||||
}
|
||||
|
||||
if (dev->irq) {
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
}
|
||||
|
||||
if (private(dev)) {
|
||||
unsigned i;
|
||||
for (i = 0; i < dev->n_subdevices; ++i) {
|
||||
if (dev->subdevices[i].private) {
|
||||
kfree(dev->subdevices[i].private);
|
||||
dev->subdevices[i].private = NULL;
|
||||
}
|
||||
kfree(dev->subdevices[i].private);
|
||||
dev->subdevices[i].private = NULL;
|
||||
}
|
||||
if (private(dev)->mite) {
|
||||
if (private(dev)->mite)
|
||||
mite_unsetup(private(dev)->mite);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -830,7 +829,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot)
|
|||
}
|
||||
}
|
||||
}
|
||||
printk("no device found\n");
|
||||
printk(KERN_WARNING "no device found\n");
|
||||
mite_list_devices();
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ enum ni_660x_constants {
|
|||
};
|
||||
|
||||
#define NUM_PFI_CHANNELS 40
|
||||
/* really there are only up to 3 dma channels, but the register layout allows for 4 */
|
||||
/* really there are only up to 3 dma channels, but the register layout allows
|
||||
for 4 */
|
||||
#define MAX_DMA_CHANNEL 4
|
||||
|
||||
/* See Register-Level Programmer Manual page 3.1 */
|
||||
|
@ -198,7 +199,7 @@ struct NI_660xRegisterData {
|
|||
const char *name; /* Register Name */
|
||||
int offset; /* Offset from base address from GPCT chip */
|
||||
enum ni_660x_register_direction direction;
|
||||
enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
|
||||
enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
|
||||
};
|
||||
|
||||
static const struct NI_660xRegisterData registerData[NumRegisters] = {
|
||||
|
@ -382,8 +383,8 @@ enum global_interrupt_config_register_bits {
|
|||
};
|
||||
|
||||
/* Offset of the GPCT chips from the base-adress of the card */
|
||||
static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address +
|
||||
0x00, etc. */
|
||||
/* First chip is at base-address + 0x00, etc. */
|
||||
static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
|
||||
|
||||
/* Board description*/
|
||||
struct ni_660x_board {
|
||||
|
@ -691,13 +692,13 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
|
|||
ni_660x_register = G0StatusRegister;
|
||||
break;
|
||||
case NITIO_G1_Status_Reg:
|
||||
ni_660x_register = G0StatusRegister;
|
||||
ni_660x_register = G1StatusRegister;
|
||||
break;
|
||||
case NITIO_G2_Status_Reg:
|
||||
ni_660x_register = G0StatusRegister;
|
||||
ni_660x_register = G2StatusRegister;
|
||||
break;
|
||||
case NITIO_G3_Status_Reg:
|
||||
ni_660x_register = G0StatusRegister;
|
||||
ni_660x_register = G3StatusRegister;
|
||||
break;
|
||||
case NITIO_G0_Interrupt_Enable_Reg:
|
||||
ni_660x_register = G0InterruptEnable;
|
||||
|
@ -712,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
|
|||
ni_660x_register = G3InterruptEnable;
|
||||
break;
|
||||
default:
|
||||
printk("%s: unhandled register 0x%x in switch.\n",
|
||||
printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n",
|
||||
__func__, reg);
|
||||
BUG();
|
||||
return 0;
|
||||
|
@ -737,7 +738,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
|
|||
writel(bits, write_address);
|
||||
break;
|
||||
default:
|
||||
printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
|
||||
printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
|
||||
__FILE__, __func__, reg);
|
||||
BUG();
|
||||
break;
|
||||
|
@ -760,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
|
|||
return readl(read_address);
|
||||
break;
|
||||
default:
|
||||
printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
|
||||
printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
|
||||
__FILE__, __func__, reg);
|
||||
BUG();
|
||||
break;
|
||||
|
@ -993,9 +994,9 @@ static int ni_660x_allocate_private(struct comedi_device *dev)
|
|||
spin_lock_init(&private(dev)->mite_channel_lock);
|
||||
spin_lock_init(&private(dev)->interrupt_lock);
|
||||
spin_lock_init(&private(dev)->soft_reg_copy_lock);
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i)
|
||||
private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1008,9 +1009,8 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
|
|||
for (j = 0; j < counters_per_chip; ++j) {
|
||||
private(dev)->mite_rings[i][j] =
|
||||
mite_alloc_ring(private(dev)->mite);
|
||||
if (private(dev)->mite_rings[i][j] == NULL) {
|
||||
if (private(dev)->mite_rings[i][j] == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1022,9 +1022,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev)
|
|||
unsigned j;
|
||||
|
||||
for (i = 0; i < board(dev)->n_chips; ++i) {
|
||||
for (j = 0; j < counters_per_chip; ++j) {
|
||||
for (j = 0; j < counters_per_chip; ++j)
|
||||
mite_free_ring(private(dev)->mite_rings[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1035,7 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
unsigned i;
|
||||
unsigned global_interrupt_config_bits;
|
||||
|
||||
printk("comedi%d: ni_660x: ", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor);
|
||||
|
||||
ret = ni_660x_allocate_private(dev);
|
||||
if (ret < 0)
|
||||
|
@ -1049,7 +1048,7 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
|
||||
ret = mite_setup2(private(dev)->mite, 1);
|
||||
if (ret < 0) {
|
||||
printk("error setting up mite\n");
|
||||
printk(KERN_WARNING "error setting up mite\n");
|
||||
return ret;
|
||||
}
|
||||
comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
|
||||
|
@ -1057,7 +1056,7 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
printk(" %s ", dev->board_name);
|
||||
printk(KERN_INFO " %s ", dev->board_name);
|
||||
|
||||
dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
|
||||
|
||||
|
@ -1078,15 +1077,16 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
s->insn_bits = ni_660x_dio_insn_bits;
|
||||
s->insn_config = ni_660x_dio_insn_config;
|
||||
s->io_bits = 0; /* all bits default to input */
|
||||
/* we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */
|
||||
/* we use the ioconfig registers to control dio direction, so zero
|
||||
output enables in stc dio control reg */
|
||||
ni_660x_write_register(dev, 0, 0, STCDIOControl);
|
||||
|
||||
private(dev)->counter_dev = ni_gpct_device_construct(dev,
|
||||
&ni_gpct_write_register,
|
||||
&ni_gpct_read_register,
|
||||
ni_gpct_variant_660x,
|
||||
ni_660x_num_counters
|
||||
(dev));
|
||||
&ni_gpct_write_register,
|
||||
&ni_gpct_read_register,
|
||||
ni_gpct_variant_660x,
|
||||
ni_660x_num_counters
|
||||
(dev));
|
||||
if (private(dev)->counter_dev == NULL)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
|
||||
|
@ -1118,12 +1118,12 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
s->type = COMEDI_SUBD_UNUSED;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < board(dev)->n_chips; ++i) {
|
||||
for (i = 0; i < board(dev)->n_chips; ++i)
|
||||
init_tio_chip(dev, i);
|
||||
}
|
||||
for (i = 0; i < ni_660x_num_counters(dev); ++i) {
|
||||
|
||||
for (i = 0; i < ni_660x_num_counters(dev); ++i)
|
||||
ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
|
||||
if (i < min_counter_pfi_chan)
|
||||
ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
|
||||
|
@ -1134,13 +1134,13 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
}
|
||||
/* to be safe, set counterswap bits on tio chips after all the counter
|
||||
outputs have been set to high impedance mode */
|
||||
for (i = 0; i < board(dev)->n_chips; ++i) {
|
||||
for (i = 0; i < board(dev)->n_chips; ++i)
|
||||
set_tio_counterswap(dev, i);
|
||||
}
|
||||
|
||||
ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
|
||||
IRQF_SHARED, "ni_660x", dev);
|
||||
if (ret < 0) {
|
||||
printk(" irq not available\n");
|
||||
printk(KERN_WARNING " irq not available\n");
|
||||
return ret;
|
||||
}
|
||||
dev->irq = mite_irq(private(dev)->mite);
|
||||
|
@ -1149,13 +1149,13 @@ static int ni_660x_attach(struct comedi_device *dev,
|
|||
global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
|
||||
ni_660x_write_register(dev, 0, global_interrupt_config_bits,
|
||||
GlobalInterruptConfigRegister);
|
||||
printk("attached\n");
|
||||
printk(KERN_INFO "attached\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni_660x_detach(struct comedi_device *dev)
|
||||
{
|
||||
printk("comedi%d: ni_660x: remove\n", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor);
|
||||
|
||||
/* Free irq */
|
||||
if (dev->irq)
|
||||
|
@ -1193,9 +1193,8 @@ static void init_tio_chip(struct comedi_device *dev, int chipset)
|
|||
private(dev)->
|
||||
dma_configuration_soft_copies[chipset],
|
||||
DMAConfigRegister);
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i)
|
||||
ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1234,7 +1233,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
|
|||
}
|
||||
}
|
||||
}
|
||||
printk("no device found\n");
|
||||
printk(KERN_WARNING "no device found\n");
|
||||
mite_list_devices();
|
||||
return -EIO;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue