dect
/
linux-2.6
Archived
13
0
Fork 0

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

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (368 commits)
  Staging: winbond: fix up wireless api errors
  Staging: dream: camera: sk5k3e2fx: fix code style issues
  Staging: dream: camera: msm_camera: fix code style issues
  Staging: wlan-ng: More checkpatch.pl error cleanups
  Staging: wlan-ng - checkpatch.pl fixups
  Staging: comedi: comedi_fops.c: Checkpatch cleanup
  Staging: comedi: fix suspect code indent in ni_labpc.c
  Staging: comedi: fix yet another brace coding style issue in ni_labpc.c
  Staging: comedi: fix another brace coding style issues in ni_labpc.c
  Staging: comedi: fix brace coding style issue in ni_labpc.c
  Staging: comedi: poc: Adding some KERN_ facility level
  Staging: dream: camera: msm_camera: fix some code style issues
  Staging: wlan-ng: fix most of the style issues in hfa384x.h
  Staging: dream: camera: msm_camera: fix coding style issues
  Staging: comedi: fix bracing coding style and 80 character issues in ni_660x.c
  Staging: comedi: fix bracing coding style issue in ni_65xx.c
  Staging: comedi: pcmad: Checkpatch cleanups
  Staging: comedi: poc: fix coding style issues
  staging: dt3155: revert u_long to u64 usage
  Staging: comedi: drivers.c: Checkpatch cleanup
  ...
This commit is contained in:
Linus Torvalds 2010-03-07 15:49:12 -08:00
commit 8fe900b8c7
478 changed files with 29157 additions and 24477 deletions

View File

@ -71,8 +71,6 @@ source "drivers/staging/asus_oled/Kconfig"
source "drivers/staging/panel/Kconfig" source "drivers/staging/panel/Kconfig"
source "drivers/staging/altpciechdma/Kconfig"
source "drivers/staging/rtl8187se/Kconfig" source "drivers/staging/rtl8187se/Kconfig"
source "drivers/staging/rtl8192su/Kconfig" source "drivers/staging/rtl8192su/Kconfig"
@ -81,20 +79,14 @@ source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/rtl8192e/Kconfig"
source "drivers/staging/mimio/Kconfig"
source "drivers/staging/frontier/Kconfig" source "drivers/staging/frontier/Kconfig"
source "drivers/staging/dream/Kconfig" source "drivers/staging/dream/Kconfig"
source "drivers/staging/pohmelfs/Kconfig" source "drivers/staging/pohmelfs/Kconfig"
source "drivers/staging/b3dfg/Kconfig"
source "drivers/staging/phison/Kconfig" source "drivers/staging/phison/Kconfig"
source "drivers/staging/p9auth/Kconfig"
source "drivers/staging/line6/Kconfig" source "drivers/staging/line6/Kconfig"
source "drivers/gpu/drm/vmwgfx/Kconfig" source "drivers/gpu/drm/vmwgfx/Kconfig"
@ -117,7 +109,7 @@ source "drivers/staging/hv/Kconfig"
source "drivers/staging/vme/Kconfig" source "drivers/staging/vme/Kconfig"
source "drivers/staging/rar/Kconfig" source "drivers/staging/rar_register/Kconfig"
source "drivers/staging/sep/Kconfig" source "drivers/staging/sep/Kconfig"
@ -143,5 +135,9 @@ source "drivers/staging/netwave/Kconfig"
source "drivers/staging/sm7xx/Kconfig" source "drivers/staging/sm7xx/Kconfig"
source "drivers/staging/dt3155/Kconfig"
source "drivers/staging/crystalhd/Kconfig"
endif # !STAGING_EXCLUDE_BUILD endif # !STAGING_EXCLUDE_BUILD
endif # STAGING endif # STAGING

View File

@ -18,18 +18,14 @@ obj-$(CONFIG_RT2870) += rt2870/
obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/ obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/ obj-$(CONFIG_PANEL) += panel/
obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
obj-$(CONFIG_R8187SE) += rtl8187se/ obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192SU) += rtl8192su/ obj-$(CONFIG_RTL8192SU) += rtl8192su/
obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_INPUT_MIMIO) += mimio/
obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_DREAM) += dream/ obj-$(CONFIG_DREAM) += dream/
obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_POHMELFS) += pohmelfs/
obj-$(CONFIG_B3DFG) += b3dfg/
obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_IDE_PHISON) += phison/
obj-$(CONFIG_PLAN9AUTH) += p9auth/
obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/
@ -39,7 +35,7 @@ obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_FB_UDL) += udlfb/
obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_RAR_REGISTER) += rar/ obj-$(CONFIG_RAR_REGISTER) += rar_register/
obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_RAMZSWAP) += ramzswap/ obj-$(CONFIG_RAMZSWAP) += ramzswap/
@ -53,3 +49,5 @@ obj-$(CONFIG_WAVELAN) += wavelan/
obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/
obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_FB_SM7XX) += sm7xx/
obj-$(CONFIG_DT3155) += dt3155/
obj-$(CONFIG_CRYSTALHD) += crystalhd/

View File

@ -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.

View File

@ -1,2 +0,0 @@
obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma.o

View File

@ -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

View File

@ -1,3 +1,3 @@
obj-$(CONFIG_ARLAN) += arlan.o obj-$(CONFIG_ARLAN) += arlan.o
arlan-objs := arlan-main.o arlan-proc.o arlan-objs := arlan-main.o arlan-proc.o

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 1997 Cullen Jennings * 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 * GNU General Public License applies
*/ */
@ -20,14 +20,14 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <linux/io.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
//#define ARLAN_DEBUGGING 1 /* #define ARLAN_DEBUGGING 1 */
#define ARLAN_PROC_INTERFACE #define ARLAN_PROC_INTERFACE
#define MAX_ARLANS 4 /* not more than 4 ! */ #define MAX_ARLANS 4 /* not more than 4 ! */
@ -51,8 +51,8 @@ extern int arlan_debug;
extern int arlan_entry_debug; extern int arlan_entry_debug;
extern int arlan_exit_debug; extern int arlan_exit_debug;
extern int testMemory; 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 SIDUNKNOWN -1
#define radioNodeIdUNKNOWN -1 #define radioNodeIdUNKNOWN -1
#define irqUNKNOWN 0 #define irqUNKNOWN 0
@ -65,22 +65,21 @@ extern int arlan_command(struct net_device * dev, int command);
#define registrationModeUNKNOWN -1 #define registrationModeUNKNOWN -1
#define IFDEBUG( L ) if ( (L) & arlan_debug ) #define IFDEBUG(L) if ((L) & arlan_debug)
#define ARLAN_FAKE_HDR_LEN 12 #define ARLAN_FAKE_HDR_LEN 12
#ifdef ARLAN_DEBUGGING #ifdef ARLAN_DEBUGGING
#define DEBUG 1 #define DEBUG 1
#define ARLAN_ENTRY_EXIT_DEBUGGING 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 #else
#define ARLAN_DEBUG(a,b) #define ARLAN_DEBUG(a, b)
#endif #endif
#define ARLAN_SHMEM_SIZE 0x2000 #define ARLAN_SHMEM_SIZE 0x2000
struct arlan_shmem struct arlan_shmem {
{ /* Header Signature */
/* Header Signature */
volatile char textRegion[48]; volatile char textRegion[48];
volatile u_char resetFlag; volatile u_char resetFlag;
volatile u_char diagnosticInfo; volatile u_char diagnosticInfo;
@ -91,10 +90,10 @@ struct arlan_shmem
volatile u_char hardwareType; volatile u_char hardwareType;
volatile u_char majorHardwareVersion; volatile u_char majorHardwareVersion;
volatile u_char minorHardwareVersion; volatile u_char minorHardwareVersion;
volatile u_char radioModule;// shows EEPROM, can be overridden at 0x111 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 defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */
volatile u_char _2[47]; volatile u_char _2[47];
/* Control/Status Block - 0x0080 */ /* Control/Status Block - 0x0080 */
volatile u_char interruptInProgress; /* not used by lancpu */ volatile u_char interruptInProgress; /* not used by lancpu */
volatile u_char cntrlRegImage; /* 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 rxQuality;
volatile u_char scrambled; volatile u_char scrambled;
volatile u_char _4[1]; volatile u_char _4[1];
/* Transmit Status - 0x00b0 */ /* Transmit Status - 0x00b0 */
volatile u_char txStatus; volatile u_char txStatus;
volatile u_char txAckQuality; volatile u_char txAckQuality;
@ -151,7 +150,7 @@ struct arlan_shmem
volatile u_short routerId; volatile u_short routerId;
volatile u_char _10[9]; volatile u_char _10[9];
volatile u_char txAttenuation; volatile u_char txAttenuation;
volatile u_char systemId[4]; volatile u_char systemId[4];
volatile u_short globalChecksum; volatile u_short globalChecksum;
volatile u_char _11[4]; volatile u_char _11[4];
volatile u_short maxDatagramSize; volatile u_short maxDatagramSize;
@ -207,19 +206,19 @@ struct arlan_shmem
volatile u_char hostcpuLock; volatile u_char hostcpuLock;
volatile u_char lancpuLock; volatile u_char lancpuLock;
volatile u_char resetTime[18]; volatile u_char resetTime[18];
volatile u_char numDatagramsTransmitted[4]; volatile u_char numDatagramsTransmitted[4];
volatile u_char numReTransmissions[4]; volatile u_char numReTransmissions[4];
volatile u_char numFramesDiscarded[4]; volatile u_char numFramesDiscarded[4];
volatile u_char numDatagramsReceived[4]; volatile u_char numDatagramsReceived[4];
volatile u_char numDuplicateReceivedFrames[4]; volatile u_char numDuplicateReceivedFrames[4];
volatile u_char numDatagramsDiscarded[4]; volatile u_char numDatagramsDiscarded[4];
volatile u_short maxNumReTransmitDatagram; volatile u_short maxNumReTransmitDatagram;
volatile u_short maxNumReTransmitFrames; volatile u_short maxNumReTransmitFrames;
volatile u_short maxNumConsecutiveDuplicateFrames; volatile u_short maxNumConsecutiveDuplicateFrames;
/* misaligned here so we have to go to characters */ /* misaligned here so we have to go to characters */
volatile u_char numBytesTransmitted[4]; volatile u_char numBytesTransmitted[4];
volatile u_char numBytesReceived[4]; volatile u_char numBytesReceived[4];
volatile u_char numCRCErrors[4]; volatile u_char numCRCErrors[4];
@ -259,7 +258,7 @@ struct arlan_conf_stru {
int channelNumber; int channelNumber;
int scramblingDisable; int scramblingDisable;
int txAttenuation; int txAttenuation;
int systemId; int systemId;
int maxDatagramSize; int maxDatagramSize;
int maxFrameSize; int maxFrameSize;
int maxRetries; int maxRetries;
@ -316,8 +315,7 @@ struct arlan_conf_stru {
extern struct arlan_conf_stru arlan_conf[MAX_ARLANS]; extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
struct TxParam struct TxParam {
{
volatile short offset; volatile short offset;
volatile short length; volatile short length;
volatile u_char dest[6]; volatile u_char dest[6];
@ -330,12 +328,12 @@ struct TxParam
#define TX_RING_SIZE 2 #define TX_RING_SIZE 2
/* Information that need to be kept for each board. */ /* Information that need to be kept for each board. */
struct arlan_private { struct arlan_private {
struct arlan_shmem __iomem * card; struct arlan_shmem __iomem *card;
struct arlan_shmem * conf; struct arlan_shmem *conf;
struct arlan_conf_stru * Conf; struct arlan_conf_stru *Conf;
int bad; int bad;
int reset; int reset;
unsigned long lastReset; unsigned long lastReset;
struct timer_list timer; struct timer_list timer;
struct timer_list tx_delay_timer; struct timer_list tx_delay_timer;
@ -407,38 +405,38 @@ struct arlan_private {
#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer) #define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer) #define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
#define READSHM(to,from,atype) {\ #define READSHM(to, from, atype) {\
atype tmp;\ atype tmp;\
memcpy_fromio(&(tmp),&(from),sizeof(atype));\ memcpy_fromio(&(tmp), &(from), sizeof(atype));\
to = tmp;\ to = tmp;\
} }
#define READSHMEM(from,atype)\ #define READSHMEM(from, atype)\
atype from; \ atype from; \
READSHM(from, arlan->from, atype); READSHM(from, arlan->from, atype);
#define WRITESHM(to,from,atype) \ #define WRITESHM(to, from, atype) \
{ atype tmpSHM = from;\ { 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; \ { atype tmpSHM; \
memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\ memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\
IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\ IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\
} }
#define WRITESHMB(to, val) \ #define WRITESHMB(to, val) \
writeb(val,&(to)) writeb(val, &(to))
#define READSHMB(to) \ #define READSHMB(to) \
readb(&(to)) readb(&(to))
#define WRITESHMS(to, val) \ #define WRITESHMS(to, val) \
writew(val,&(to)) writew(val, &(to))
#define READSHMS(to) \ #define READSHMS(to) \
readw(&(to)) readw(&(to))
#define WRITESHMI(to, val) \ #define WRITESHMI(to, val) \
writel(val,&(to)) writel(val, &(to))
#define READSHMI(to) \ #define READSHMI(to) \
readl(&(to)) readl(&(to))
@ -447,51 +445,51 @@ struct arlan_private {
#define registrationBad(dev)\ #define registrationBad(dev)\
( ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ (( 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->registrationStatus) == 0))
#define readControlRegister(dev)\ #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){\ #define writeControlRegister(dev, v) {\
WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage ,((v) &0xF) );\ WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\
WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister ,(v) );} WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); }
#define arlan_interrupt_lancpu(dev) {\ #define arlan_interrupt_lancpu(dev) {\
int cr; \ int cr; \
\ \
cr = readControlRegister(dev);\ cr = readControlRegister(dev);\
if (cr & ARLAN_CHANNEL_ATTENTION){ \ if (cr & ARLAN_CHANNEL_ATTENTION) { \
writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\ writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
}else \ } else \
writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\ writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
} }
#define clearChannelAttention(dev){ \ #define clearChannelAttention(dev) { \
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);} writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); }
#define setHardwareReset(dev) {\ #define setHardwareReset(dev) {\
writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);} writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); }
#define clearHardwareReset(dev) {\ #define clearHardwareReset(dev) {\
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);} writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); }
#define setInterruptEnable(dev){\ #define setInterruptEnable(dev) {\
writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ;} writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ; }
#define clearInterruptEnable(dev){\ #define clearInterruptEnable(dev) {\
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ;} writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ; }
#define setClearInterrupt(dev){\ #define setClearInterrupt(dev) {\
writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ;} writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ; }
#define clearClearInterrupt(dev){\ #define clearClearInterrupt(dev) {\
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);} writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); }
#define setPowerOff(dev){\ #define setPowerOff(dev) {\
writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\ writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);} writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
#define setPowerOn(dev){\ #define setPowerOn(dev) {\
writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER)); } writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); }
#define arlan_lock_card_access(dev){\ #define arlan_lock_card_access(dev) {\
writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);} writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
#define arlan_unlock_card_access(dev){\ #define arlan_unlock_card_access(dev) {\
writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); } writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); }
@ -525,7 +523,6 @@ struct arlan_private {
| ARLAN_COMMAND_RESET) | ARLAN_COMMAND_RESET)
#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001 #define ARLAN_DEBUG_CHAIN_LOCKS 0x00001
#define ARLAN_DEBUG_RESET 0x00002 #define ARLAN_DEBUG_RESET 0x00002
#define ARLAN_DEBUG_TIMING 0x00004 #define ARLAN_DEBUG_TIMING 0x00004
@ -536,4 +533,3 @@ struct arlan_private {
#define ARLAN_DEBUG_INTERRUPT 0x00080 #define ARLAN_DEBUG_INTERRUPT 0x00080
#define ARLAN_DEBUG_STARTUP 0x00100 #define ARLAN_DEBUG_STARTUP 0x00100
#define ARLAN_DEBUG_SHUTDOWN 0x00200 #define ARLAN_DEBUG_SHUTDOWN 0x00200

View File

@ -52,6 +52,10 @@
#define ASUS_OLED_DISP_HEIGHT 32 #define ASUS_OLED_DISP_HEIGHT 32
#define ASUS_OLED_PACKET_BUF_SIZE 256 #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_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION); MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
@ -83,18 +87,20 @@ struct oled_dev_desc_str {
}; };
/* table of devices that work with this driver */ /* 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)*/ /* 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?)*/ /* 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 */ /* parameters of specific devices */
static struct oled_dev_desc_str oled_dev_desc_table[] = { static struct oled_dev_desc_str oled_dev_desc_table[] = {
{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" }, { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, 128, PACK_MODE_G1,
{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" }, "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); kfree(odev->buf);
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL); 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); memset(odev->buf, 0xff, odev->buf_size);

View File

@ -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.

View File

@ -1 +0,0 @@
obj-$(CONFIG_B3DFG) += b3dfg.o

View File

@ -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

View File

@ -4,7 +4,7 @@
config BATMAN_ADV config BATMAN_ADV
tristate "B.A.T.M.A.N. Advanced Meshing Protocol" tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
depends on PROC_FS && PACKET depends on PROC_FS && NET
default n default n
---help--- ---help---
@ -14,10 +14,10 @@ config BATMAN_ADV
http://www.open-mesh.org/ for more information and user space http://www.open-mesh.org/ for more information and user space
tools. tools.
config BATMAN_DEBUG config BATMAN_ADV_DEBUG
bool "B.A.T.M.A.N. debugging" bool "B.A.T.M.A.N. debugging"
depends on BATMAN_ADV != n depends on BATMAN_ADV != n
help ---help---
This is an option for use by developers; most people should This is an option for use by developers; most people should
say N here. This enables compilation of support for say N here. This enables compilation of support for

View File

@ -19,4 +19,4 @@
# #
obj-m += batman-adv.o 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

View File

@ -1,4 +1,4 @@
[state: 07-11-2009] [state: 06-01-2010]
BATMAN-ADV 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 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, on any network (other) driver, and can be used on wifi as well as ethernet,
vpn, etc ... (anything with ethernet-style layer 2). 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 USAGE
----- -----
@ -73,16 +60,9 @@ When configured as server, you can get a topology snapshot of your mesh:
# cat /proc/net/batman-adv/vis # cat /proc/net/batman-adv/vis
This output format is a graphviz formatted text file which can be The output is in a generic raw format. Use the batctl tool (See below)
processed with graphviz-tools like dot. to convert this to other formats more suitable for graphing, eg
The labels are similar/compatible to the ETX metric, 1.0 means perfect graphviz dot, or JSON data-interchange format.
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
In very mobile scenarios, you might want to adjust the originator In very mobile scenarios, you might want to adjust the originator
interval to a lower value. This will make the mesh more responsive to 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 # 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 BATCTL
------ ------
B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts partici- B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts
pating in the virtual switch are completely transparent for all proto- participating in the virtual switch are completely transparent for all
cols above layer 2. Therefore the common diagnosis tools do not work as protocols above layer 2. Therefore the common diagnosis tools do not
expected. To overcome these problems batctl was created. At the moment work as expected. To overcome these problems batctl was created. At
the batctl contains ping, traceroute, tcpdump and interfaces to the the moment the batctl contains ping, traceroute, tcpdump and
kernel module settings. interfaces to the kernel module settings.
For more information, please see the manpage (man batctl). For more information, please see the manpage (man batctl).

View File

@ -17,30 +17,6 @@
-> transtable_global (read-only) [outputs the global translation table] -> transtable_global (read-only) [outputs the global translation table]
-> transtable_local (read-only) [outputs the local 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 => fix checkpatch.pl errors
Please send all patches to: Please send all patches to:

View File

@ -96,6 +96,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
int own_packet) int own_packet)
{ {
struct forw_packet *forw_packet_aggr; struct forw_packet *forw_packet_aggr;
unsigned long flags;
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
if (!forw_packet_aggr) if (!forw_packet_aggr)
@ -115,6 +116,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
packet_buff, packet_buff,
forw_packet_aggr->packet_len); forw_packet_aggr->packet_len);
forw_packet_aggr->skb = NULL;
forw_packet_aggr->own = own_packet; forw_packet_aggr->own = own_packet;
forw_packet_aggr->if_incoming = if_incoming; forw_packet_aggr->if_incoming = if_incoming;
forw_packet_aggr->num_packets = 0; 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; forw_packet_aggr->direct_link_flags |= 1;
/* add new packet to packet list */ /* 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); 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 */ /* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, 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 *batman_packet =
(struct batman_packet *)packet_buff; (struct batman_packet *)packet_buff;
bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
unsigned long flags;
/* find position for the packet in the forward queue */ /* 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 */ /* own packets are not to be aggregated */
if ((atomic_read(&aggregation_enabled)) && (!own_packet)) { if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list, 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 */ * suitable aggregation packet found */
if (forw_packet_aggr == NULL) { if (forw_packet_aggr == NULL) {
/* the following section can run without the lock */ /* 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, new_aggregated_packet(packet_buff, packet_len,
send_time, direct_link, send_time, direct_link,
if_incoming, own_packet); 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, aggregate(forw_packet_aggr,
packet_buff, packet_len, packet_buff, packet_len,
direct_link); direct_link);
spin_unlock(&forw_bat_list_lock); spin_unlock_irqrestore(&forw_bat_list_lock, flags);
} }
} }

View File

@ -21,7 +21,6 @@
#include "main.h" #include "main.h"
#include "bitarray.h" #include "bitarray.h"
#include "log.h"
/* returns true if the corresponding bit in the given seq_bits indicates true /* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */ * 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. * from.
* *
* left is high, right is low: FEDC BA98 7654 3210 * left is high, right is low: FEDC BA98 7654 3210
* ^^ ^^ * ^^ ^^
* vvvv * vvvv
* ^^^^ = from, vvvvv =to, we'd have word_num==1 and * ^^^^ = from, vvvvv =to, we'd have word_num==1 and
* word_offset==WORD_BIT_SIZE/2 ????? in this example. * word_offset==WORD_BIT_SIZE/2 ????? in this example.
* (=24 bits) * (=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)) { (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) {
if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE) if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
debug_log(LOG_TYPE_BATMAN, bat_dbg(DBG_BATMAN,
"We missed a lot of packets (%i) !\n", "We missed a lot of packets (%i) !\n",
seq_num_diff-1); seq_num_diff-1);
if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE) if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
debug_log(LOG_TYPE_BATMAN, bat_dbg(DBG_BATMAN,
"Other host probably restarted !\n"); "Other host probably restarted !\n");
for (i = 0; i < NUM_WORDS; i++) for (i = 0; i < NUM_WORDS; i++)
seq_bits[i] = 0; seq_bits[i] = 0;

View File

@ -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) */

View File

@ -19,14 +19,13 @@
* *
*/ */
#include <linux/device.h>
#include "main.h" #include "main.h"
#include "device.h" #include "device.h"
#include "log.h"
#include "send.h" #include "send.h"
#include "types.h" #include "types.h"
#include "hash.h" #include "hash.h"
#include "hard-interface.h"
#include "compat.h"
static struct class *batman_class; static struct class *batman_class;
@ -60,7 +59,7 @@ int bat_device_setup(void)
/* register our device - kernel assigns a free major number */ /* register our device - kernel assigns a free major number */
tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
if (tmp_major < 0) { 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); tmp_major);
return 0; return 0;
} }
@ -68,7 +67,7 @@ int bat_device_setup(void)
batman_class = class_create(THIS_MODULE, "batman-adv"); batman_class = class_create(THIS_MODULE, "batman-adv");
if (IS_ERR(batman_class)) { 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; return 0;
} }
@ -111,7 +110,7 @@ int bat_device_open(struct inode *inode, struct file *file)
} }
if (device_client_hash[i] != device_client) { 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); kfree(device_client);
return -EXFULL; return -EXFULL;
} }
@ -119,7 +118,7 @@ int bat_device_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&device_client->queue_list); INIT_LIST_HEAD(&device_client->queue_list);
device_client->queue_len = 0; device_client->queue_len = 0;
device_client->index = i; 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); init_waitqueue_head(&device_client->queue_wait);
file->private_data = device_client; 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_client *)file->private_data;
struct device_packet *device_packet; struct device_packet *device_packet;
struct list_head *list_pos, *list_pos_tmp; 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 ... */ /* for all packets in the queue ... */
list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) { 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; device_client_hash[device_client->index] = NULL;
spin_unlock(&device_client->lock); spin_unlock_irqrestore(&device_client->lock, flags);
kfree(device_client); kfree(device_client);
dec_module_count(); 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_client *)file->private_data;
struct device_packet *device_packet; struct device_packet *device_packet;
int error; int error;
unsigned long flags;
if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0)) if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
return -EAGAIN; return -EAGAIN;
@ -178,14 +179,14 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
if (error) if (error)
return error; return error;
spin_lock(&device_client->lock); spin_lock_irqsave(&device_client->lock, flags);
device_packet = list_first_entry(&device_client->queue_list, device_packet = list_first_entry(&device_client->queue_list,
struct device_packet, list); struct device_packet, list);
list_del(&device_packet->list); list_del(&device_packet->list);
device_client->queue_len--; 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, error = __copy_to_user(buf, &device_packet->icmp_packet,
sizeof(struct 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 icmp_packet icmp_packet;
struct orig_node *orig_node; struct orig_node *orig_node;
struct batman_if *batman_if; struct batman_if *batman_if;
uint8_t dstaddr[ETH_ALEN];
unsigned long flags;
if (len < sizeof(struct icmp_packet)) { 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; return -EINVAL;
} }
@ -219,12 +222,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
return -EFAULT; return -EFAULT;
if (icmp_packet.packet_type != BAT_ICMP) { 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; return -EINVAL;
} }
if (icmp_packet.msg_type != ECHO_REQUEST) { 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; 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) if (atomic_read(&module_state) != MODULE_ACTIVE)
goto dst_unreach; 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)); orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
if (!orig_node) if (!orig_node)
@ -250,9 +253,15 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
goto unlock; goto unlock;
batman_if = orig_node->batman_if; batman_if = orig_node->batman_if;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
spin_unlock_irqrestore(&orig_hash_lock, flags);
if (!batman_if) if (!batman_if)
goto unlock; goto dst_unreach;
if (batman_if->if_active != IF_ACTIVE)
goto dst_unreach;
memcpy(icmp_packet.orig, memcpy(icmp_packet.orig,
batman_if->net_dev->dev_addr, 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, send_raw_packet((unsigned char *)&icmp_packet,
sizeof(struct icmp_packet), sizeof(struct icmp_packet),
batman_if, orig_node->router->addr); batman_if, dstaddr);
spin_unlock(&orig_hash_lock);
goto out; goto out;
unlock: unlock:
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
dst_unreach: dst_unreach:
icmp_packet.msg_type = DESTINATION_UNREACHABLE; icmp_packet.msg_type = DESTINATION_UNREACHABLE;
bat_device_add_packet(device_client, &icmp_packet); 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 icmp_packet *icmp_packet)
{ {
struct device_packet *device_packet; struct device_packet *device_packet;
unsigned long flags;
device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL); 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, memcpy(&device_packet->icmp_packet, icmp_packet,
sizeof(struct 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 /* while waiting for the lock the device_client could have been
* deleted */ * deleted */
if (!device_client_hash[icmp_packet->uid]) { if (!device_client_hash[icmp_packet->uid]) {
spin_unlock(&device_client->lock); spin_unlock_irqrestore(&device_client->lock, flags);
kfree(device_packet); kfree(device_packet);
return; return;
} }
@ -323,7 +332,7 @@ void bat_device_add_packet(struct device_client *device_client,
device_client->queue_len--; device_client->queue_len--;
} }
spin_unlock(&device_client->lock); spin_unlock_irqrestore(&device_client->lock, flags);
wake_up(&device_client->queue_wait); wake_up(&device_client->queue_wait);
} }

View File

@ -21,13 +21,11 @@
#include "main.h" #include "main.h"
#include "hard-interface.h" #include "hard-interface.h"
#include "log.h"
#include "soft-interface.h" #include "soft-interface.h"
#include "send.h" #include "send.h"
#include "translation-table.h" #include "translation-table.h"
#include "routing.h" #include "routing.h"
#include "hash.h" #include "hash.h"
#include "compat.h"
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #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) static void check_known_mac_addr(uint8_t *addr)
{ {
struct batman_if *batman_if; struct batman_if *batman_if;
char mac_string[ETH_STR_LEN];
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) { 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)) if (!compare_orig(batman_if->net_dev->dev_addr, addr))
continue; continue;
addr_to_string(mac_string, addr); printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n",
debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n", addr, batman_if->dev);
mac_string, batman_if->dev); printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n");
debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n");
} }
rcu_read_unlock(); rcu_read_unlock();
} }
@ -154,9 +150,6 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
if (batman_if->if_active != IF_ACTIVE) if (batman_if->if_active != IF_ACTIVE)
return; 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 * batman_if->net_dev has been acquired by dev_get_by_name() in
* proc_interfaces_write() and has to be unreferenced. * 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) if (batman_if->net_dev)
dev_put(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; batman_if->if_active = IF_INACTIVE;
active_ifs--; active_ifs--;
debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n", printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
batman_if->dev); batman_if->dev);
} }
/* (re)activate given interface. */ /* (re)activate given interface. */
static void hardif_activate_interface(struct batman_if *batman_if) static void hardif_activate_interface(struct batman_if *batman_if)
{ {
struct sockaddr_ll bind_addr;
int retval;
if (batman_if->if_active != IF_INACTIVE) if (batman_if->if_active != IF_INACTIVE)
return; return;
@ -192,35 +179,8 @@ static void hardif_activate_interface(struct batman_if *batman_if)
if (!batman_if->net_dev) if (!batman_if->net_dev)
goto dev_err; 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); 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); addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, 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) if (batman_if->if_num == 0)
set_main_if_addr(batman_if->net_dev->dev_addr); set_main_if_addr(batman_if->net_dev->dev_addr);
debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n", printk(KERN_INFO "batman-adv:Interface activated: %s\n",
batman_if->dev); batman_if->dev);
return; return;
bind_err:
sock_release(batman_if->raw_sock);
sock_err:
dev_put(batman_if->net_dev);
dev_err: dev_err:
batman_if->raw_sock = NULL;
batman_if->net_dev = 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, data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
GFP_ATOMIC); GFP_ATOMIC);
if (!data_ptr) { 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; 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); data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
if (!data_ptr) { 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; return -1;
} }
@ -319,16 +274,16 @@ int hardif_add_interface(char *dev, int if_num)
struct batman_if *batman_if; struct batman_if *batman_if;
struct batman_packet *batman_packet; struct batman_packet *batman_packet;
struct orig_node *orig_node; 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); batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
if (!batman_if) { 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; return -1;
} }
batman_if->raw_sock = NULL;
batman_if->net_dev = NULL; batman_if->net_dev = NULL;
if ((if_num == 0) && (num_hna > 0)) 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); batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
if (!batman_if->packet_buff) { 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; goto out;
} }
@ -348,7 +303,7 @@ int hardif_add_interface(char *dev, int if_num)
batman_if->if_active = IF_INACTIVE; batman_if->if_active = IF_INACTIVE;
INIT_RCU_HEAD(&batman_if->rcu); 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++; avail_ifs++;
INIT_LIST_HEAD(&batman_if->list); 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 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */ * if_num */
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 (resize_orig(orig_node, if_num) == -1) { if (resize_orig(orig_node, if_num) == -1) {
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
goto out; goto out;
} }
} }
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
if (!hardif_is_interface_up(batman_if->dev)) 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 else
hardif_activate_interface(batman_if); hardif_activate_interface(batman_if);
@ -400,8 +355,7 @@ int hardif_add_interface(char *dev, int if_num)
return 1; return 1;
out: out:
if (batman_if->packet_buff) kfree(batman_if->packet_buff);
kfree(batman_if->packet_buff);
kfree(batman_if); kfree(batman_if);
kfree(dev); kfree(dev);
return -1; return -1;
@ -413,7 +367,7 @@ char hardif_get_active_if_num(void)
} }
static int hard_if_event(struct notifier_block *this, 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 net_device *dev = (struct net_device *)ptr;
struct batman_if *batman_if = get_batman_if_by_name(dev->name); 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; break;
/* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */ /* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
default: default:
/* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */
break; break;
}; };
@ -446,6 +399,122 @@ out:
return NOTIFY_DONE; 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 = { struct notifier_block hard_if_notifier = {
.notifier_call = hard_if_event, .notifier_call = hard_if_event,
}; };

View File

@ -32,5 +32,9 @@ void hardif_deactivate_interface(struct batman_if *batman_if);
char hardif_get_active_if_num(void); char hardif_get_active_if_num(void);
void hardif_check_interfaces_status(void); void hardif_check_interfaces_status(void);
void hardif_check_interfaces_status_wq(struct work_struct *work); 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); int hardif_min_mtu(void);
void update_min_mtu(void); void update_min_mtu(void);

View File

@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *hash)
kfree(hash); kfree(hash);
} }
/* iterate though the hash. first element is selected with iter_in NULL. use /* iterate though the hash. First element is selected if an iterator
* the returned iterator to access the elements until hash_it_t returns NULL. */ * initialized with HASHIT() is supplied as iter. Use the returned
struct hash_it_t *hash_iterate(struct hashtable_t *hash, * (or supplied) iterator to access the elements until hash_iterate returns
struct hash_it_t *iter_in) * NULL. */
{
struct hash_it_t *iter;
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
struct hash_it_t *iter)
{
if (!hash) if (!hash)
return NULL; return NULL;
if (!iter)
if (iter_in == NULL) { return NULL;
iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
iter->index = -1;
iter->bucket = NULL;
iter->prev_bucket = NULL;
} else {
iter = iter_in;
}
/* sanity checks first (if our bucket got deleted in the last /* sanity checks first (if our bucket got deleted in the last
* iteration): */ * iteration): */
@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash,
} }
/* nothing to iterate over anymore */ /* nothing to iterate over anymore */
kfree(iter);
return NULL; return NULL;
} }

View File

@ -21,6 +21,11 @@
#ifndef _BATMAN_HASH_H #ifndef _BATMAN_HASH_H
#define _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_compare_cb)(void *, void *);
typedef int (*hashdata_choose_cb)(void *, int); typedef int (*hashdata_choose_cb)(void *, int);

View File

@ -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;
}

View File

@ -21,9 +21,9 @@
#include "main.h" #include "main.h"
#include "proc.h" #include "proc.h"
#include "log.h"
#include "routing.h" #include "routing.h"
#include "send.h" #include "send.h"
#include "originator.h"
#include "soft-interface.h" #include "soft-interface.h"
#include "device.h" #include "device.h"
#include "translation-table.h" #include "translation-table.h"
@ -31,7 +31,6 @@
#include "types.h" #include "types.h"
#include "vis.h" #include "vis.h"
#include "hash.h" #include "hash.h"
#include "compat.h"
struct list_head if_list; struct list_head if_list;
struct hlist_head forw_bat_list; struct hlist_head forw_bat_list;
@ -44,19 +43,34 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t originator_interval; atomic_t originator_interval;
atomic_t vis_interval; atomic_t vis_interval;
atomic_t vis_mode;
atomic_t aggregation_enabled; atomic_t aggregation_enabled;
int16_t num_hna; int16_t num_hna;
int16_t num_ifs; int16_t num_ifs;
struct net_device *soft_device; struct net_device *soft_device;
static struct task_struct *kthread_task;
unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
atomic_t module_state; 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; 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 init_module(void)
{ {
int retval; int retval;
@ -70,6 +84,7 @@ int init_module(void)
atomic_set(&originator_interval, 1000); atomic_set(&originator_interval, 1000);
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
* for debugging now. */ * for debugging now. */
atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
atomic_set(&aggregation_enabled, 1); atomic_set(&aggregation_enabled, 1);
/* the name should not be longer than 10 chars - see /* the name should not be longer than 10 chars - see
@ -90,21 +105,22 @@ int init_module(void)
interface_setup); interface_setup);
if (!soft_device) { 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; goto end;
} }
retval = register_netdev(soft_device); retval = register_netdev(soft_device);
if (retval < 0) { 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; goto free_soft_device;
} }
register_netdevice_notifier(&hard_if_notifier); 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", 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); SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
return 0; return 0;
@ -124,6 +140,8 @@ void cleanup_module(void)
soft_device = NULL; soft_device = NULL;
} }
dev_remove_pack(&batman_adv_packet_type);
unregister_netdevice_notifier(&hard_if_notifier); unregister_netdevice_notifier(&hard_if_notifier);
cleanup_procfs(); cleanup_procfs();
@ -151,22 +169,12 @@ void activate_module(void)
if (vis_init() < 1) if (vis_init() < 1)
goto err; 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(); update_min_mtu();
atomic_set(&module_state, MODULE_ACTIVE); atomic_set(&module_state, MODULE_ACTIVE);
goto end; goto end;
err: 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(); shutdown_module();
end: end:
return; return;
@ -182,14 +190,7 @@ void shutdown_module(void)
vis_quit(); vis_quit();
/* deactivate kernel thread for packet processing (if running) */ /* TODO: unregister BATMAN pack */
if (kthread_task) {
atomic_set(&exit_cond, 1);
wake_up_interruptible(&thread_wait);
kthread_stop(kthread_task);
kthread_task = NULL;
}
originator_free(); originator_free();

View File

@ -33,16 +33,16 @@
#define TQ_MAX_VALUE 255 #define TQ_MAX_VALUE 255
#define JITTER 20 #define JITTER 20
#define TTL 50 /* Time To Live of broadcast messages */ #define TTL 50 /* Time To Live of broadcast messages */
#define MAX_ADDR 16 /* number of interfaces which can be added to #define MAX_ADDR 16 /* number of interfaces which can be added to
* batman. */ * 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 * valid packet comes in -> TODO: check
* influence on TQ_LOCAL_WINDOW_SIZE */ * influence on TQ_LOCAL_WINDOW_SIZE */
#define LOCAL_HNA_TIMEOUT 3600000 #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 * messages in squence numbers (should be a
* multiple of our word size) */ * multiple of our word size) */
#define TQ_GLOBAL_WINDOW_SIZE 5 #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 #define DBG_BATMAN 1 /* all messages related to routing / flooding /
* blocked sockets / failed packet delivery / * broadcasting / etc */
* programming errors */ #define DBG_ROUTES 2 /* route or hna added / changed / deleted */
#define LOG_TYPE_WARN 1 /* warnings for small errors like wrong user
* input / damaged packets / etc */ #ifdef CONFIG_BATMAN_ADV_DEBUG
#define LOG_TYPE_NOTICE 2 /* notice information for new interfaces / extern int debug;
* changed settings / new originators / etc */
#define LOG_TYPE_BATMAN 4 /* all messages related to routing / flooding / extern int bat_debug_type(int type);
* broadcasting / etc */ #define bat_dbg(type, fmt, arg...) do { \
#define LOG_TYPE_ROUTES 8 /* route or hna added / changed / deleted */ if (bat_debug_type(type)) \
#define LOG_TYPE_CRIT_NAME "critical" printk(KERN_DEBUG "batman-adv:" fmt, ## arg); \
#define LOG_TYPE_WARN_NAME "warnings" } \
#define LOG_TYPE_NOTICE_NAME "notices" while (0)
#define LOG_TYPE_BATMAN_NAME "batman" #else /* !CONFIG_BATMAN_ADV_DEBUG */
#define LOG_TYPE_ROUTES_NAME "routes" #define bat_dbg(type, fmt, arg...) do { \
} \
while (0)
#endif
/* /*
* Vis * Vis
@ -127,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock;
extern atomic_t originator_interval; extern atomic_t originator_interval;
extern atomic_t vis_interval; extern atomic_t vis_interval;
extern atomic_t vis_mode;
extern atomic_t aggregation_enabled; extern atomic_t aggregation_enabled;
extern int16_t num_hna; extern int16_t num_hna;
extern int16_t num_ifs; 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_my_mac(uint8_t *addr);
int is_bcast(uint8_t *addr); int is_bcast(uint8_t *addr);
int is_mcast(uint8_t *addr); int is_mcast(uint8_t *addr);

View 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();
}

View File

@ -19,14 +19,13 @@
* *
*/ */
extern const struct file_operations proc_log_operations; int originator_init(void);
extern uint8_t log_level; 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);

View File

@ -90,7 +90,7 @@ struct vis_packet {
uint8_t entries; /* number of entries behind this struct */ uint8_t entries; /* number of entries behind this struct */
uint8_t ttl; /* TTL */ uint8_t ttl; /* TTL */
uint8_t vis_orig[6]; /* originator that informs about its uint8_t vis_orig[6]; /* originator that informs about its
* neighbours */ * neighbors */
uint8_t target_orig[6]; /* who should receive this packet */ uint8_t target_orig[6]; /* who should receive this packet */
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
} __attribute__((packed)); } __attribute__((packed));

View File

@ -21,23 +21,18 @@
#include "main.h" #include "main.h"
#include "proc.h" #include "proc.h"
#include "log.h"
#include "routing.h" #include "routing.h"
#include "translation-table.h" #include "translation-table.h"
#include "hard-interface.h" #include "hard-interface.h"
#include "types.h" #include "types.h"
#include "hash.h" #include "hash.h"
#include "vis.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_batman_dir, *proc_interface_file;
static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_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_local_file;
static struct proc_dir_entry *proc_transt_global_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 struct proc_dir_entry *proc_aggr_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset) 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) size_t count, loff_t *data)
{ {
char *if_string, *colon_ptr = NULL, *cr_ptr = NULL; 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; struct batman_if *batman_if = NULL;
if_string = kmalloc(count, GFP_KERNEL); if_string = kmalloc(count, GFP_KERNEL);
@ -77,8 +72,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
return -ENOMEM; return -ENOMEM;
if (count > IFNAMSIZ - 1) { if (count > IFNAMSIZ - 1) {
debug_log(LOG_TYPE_WARN, printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
"Can't add interface: device name is too long\n");
goto end; goto end;
} }
@ -105,7 +99,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) { list_for_each_entry_rcu(batman_if, &if_list, list) {
if (strncmp(batman_if->dev, if_string, count) == 0) { 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(); rcu_read_unlock();
goto end; goto end;
@ -115,22 +109,17 @@ static ssize_t proc_interfaces_write(struct file *instance,
} }
rcu_read_unlock(); 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) && if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
(hardif_get_active_if_num() > 0)) (hardif_get_active_if_num() > 0))
activate_module(); 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; return count;
end: end:
kfree(if_string); kfree(if_string);
return count; 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); retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
if (retval) { if (retval) {
debug_log(LOG_TYPE_WARN, "New originator interval invalid\n"); printk(KERN_ERR "batman-adv:New originator interval invalid\n");
goto end; goto end;
} }
if (originator_interval_tmp <= JITTER * 2) { if (originator_interval_tmp <= JITTER * 2) {
debug_log(LOG_TYPE_WARN, printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n",
"New originator interval too small: %i (min: %i)\n", originator_interval_tmp, JITTER * 2);
originator_interval_tmp, JITTER * 2);
goto end; goto end;
} }
debug_log(LOG_TYPE_NOTICE, printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n",
"Changing originator interval from: %i to: %i\n", atomic_read(&originator_interval), originator_interval_tmp);
atomic_read(&originator_interval), originator_interval_tmp);
atomic_set(&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) 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 orig_node *orig_node;
struct neigh_node *neigh_node; struct neigh_node *neigh_node;
int batman_count = 0; int batman_count = 0;
char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
unsigned long flags;
rcu_read_lock(); rcu_read_lock();
if (list_empty(&if_list)) { 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); ((struct batman_if *)if_list.next)->addr_str);
rcu_read_unlock(); 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) if (!orig_node->router)
continue; 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) if (batman_count == 0)
seq_printf(seq, "No batman nodes in range ... \n"); 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); 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) static int proc_transt_local_read(struct seq_file *seq, void *offset)
{ {
char *buf; 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); 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 */ /* 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) size_t count, loff_t *ppos)
{ {
char *vis_mode_string; 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); not_copied = copy_from_user(vis_mode_string, buffer, count);
vis_mode_string[count - not_copied - 1] = 0; vis_mode_string[count - not_copied - 1] = 0;
if (strcmp(vis_mode_string, "client") == 0) { if ((strcmp(vis_mode_string, "client") == 0) ||
debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n"); (strcmp(vis_mode_string, "disabled") == 0)) {
vis_set_mode(VIS_TYPE_CLIENT_UPDATE); printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n");
} else if (strcmp(vis_mode_string, "server") == 0) { atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n"); } else if ((strcmp(vis_mode_string, "server") == 0) ||
vis_set_mode(VIS_TYPE_SERVER_SYNC); (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 } else
debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n", printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
vis_mode_string); vis_mode_string);
kfree(vis_mode_string); kfree(vis_mode_string);
return count; 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) seq_printf(seq, "[%c] client mode (server disabled) \n",
{ (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
uint8_t current_format = vis_format; 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; 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, static int proc_vis_data_read(struct seq_file *seq, void *offset)
const char __user *buffer,
size_t count, loff_t *ppos)
{ {
char *vis_format_string; HASHIT(hashit);
int not_copied = 0; 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) rcu_read_unlock();
return -ENOMEM;
not_copied = copy_from_user(vis_format_string, buffer, count); spin_lock_irqsave(&vis_hash_lock, flags);
vis_format_string[count - not_copied - 1] = 0; 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) { for (i = 0; i < info->packet.entries; i++) {
debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n", proc_vis_read_entry(seq, &entries[i], &vis_if_list,
VIS_FORMAT_DD_NAME); info->packet.vis_orig);
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);
kfree(vis_format_string); /* add primary/secondary records */
return count; 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) 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; char *aggr_string;
int not_copied = 0; int not_copied = 0;
unsigned long aggregation_enabled_tmp; unsigned long aggregation_enabled_tmp;
int retval;
aggr_string = kmalloc(count, GFP_KERNEL); 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); not_copied = copy_from_user(aggr_string, buffer, count);
aggr_string[count - not_copied - 1] = 0; 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)) { if (retval || 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); printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
goto end; } 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); kfree(aggr_string);
return count; return count;
} }
@ -715,20 +473,20 @@ static const struct file_operations proc_aggr_fops = {
.release = single_release, .release = single_release,
}; };
static const struct file_operations proc_vis_format_fops = { static const struct file_operations proc_vis_srv_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = proc_vis_format_open, .open = proc_vis_srv_open,
.read = seq_read, .read = seq_read,
.write = proc_vis_format_write, .write = proc_vis_srv_write,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
static const struct file_operations proc_vis_fops = { static const struct file_operations proc_vis_data_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = proc_vis_open, .open = proc_vis_data_open,
.read = seq_read, .read = seq_read,
.write = proc_vis_write, .write = proc_dummy_write,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
@ -760,15 +518,6 @@ static const struct file_operations proc_transt_global_fops = {
.release = single_release, .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 = { static const struct file_operations proc_interfaces_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = proc_interfaces_open, .open = proc_interfaces_open,
@ -795,12 +544,6 @@ void cleanup_procfs(void)
if (proc_transt_local_file) if (proc_transt_local_file)
remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir); 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) if (proc_originators_file)
remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir); remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
@ -810,11 +553,11 @@ void cleanup_procfs(void)
if (proc_interface_file) if (proc_interface_file)
remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
if (proc_vis_file) if (proc_vis_data_file)
remove_proc_entry(PROC_FILE_VIS, proc_batman_dir); remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir);
if (proc_vis_format_file) if (proc_vis_srv_file)
remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir); remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
if (proc_aggr_file) if (proc_aggr_file)
remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir); remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
@ -862,17 +605,6 @@ int setup_procfs(void)
return -EFAULT; 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, proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
S_IRUGO, proc_batman_dir); S_IRUGO, proc_batman_dir);
if (proc_originators_file) { if (proc_originators_file) {
@ -883,16 +615,6 @@ int setup_procfs(void)
return -EFAULT; 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, proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
S_IRUGO, proc_batman_dir); S_IRUGO, proc_batman_dir);
if (proc_transt_local_file) { if (proc_transt_local_file) {
@ -913,23 +635,23 @@ int setup_procfs(void)
return -EFAULT; return -EFAULT;
} }
proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO, proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
proc_batman_dir); S_IWUSR | S_IRUGO,
if (proc_vis_file) { proc_batman_dir);
proc_vis_file->proc_fops = &proc_vis_fops; if (proc_vis_srv_file) {
proc_vis_srv_file->proc_fops = &proc_vis_srv_fops;
} else { } 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(); cleanup_procfs();
return -EFAULT; return -EFAULT;
} }
proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT, proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO,
S_IWUSR | S_IRUGO, proc_batman_dir);
proc_batman_dir); if (proc_vis_data_file) {
if (proc_vis_format_file) { proc_vis_data_file->proc_fops = &proc_vis_data_fops;
proc_vis_format_file->proc_fops = &proc_vis_format_fops;
} else { } 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(); cleanup_procfs();
return -EFAULT; return -EFAULT;
} }
@ -946,5 +668,3 @@ int setup_procfs(void)
return 0; return 0;
} }

View File

@ -31,19 +31,10 @@
#define PROC_FILE_LOG_LEVEL "log_level" #define PROC_FILE_LOG_LEVEL "log_level"
#define PROC_FILE_TRANST_LOCAL "transtable_local" #define PROC_FILE_TRANST_LOCAL "transtable_local"
#define PROC_FILE_TRANST_GLOBAL "transtable_global" #define PROC_FILE_TRANST_GLOBAL "transtable_global"
#define PROC_FILE_VIS "vis" #define PROC_FILE_VIS_SRV "vis_server"
#define PROC_FILE_VIS_FORMAT "vis_format" #define PROC_FILE_VIS_DATA "vis_data"
#define PROC_FILE_AGGR "aggregate_ogm" #define PROC_FILE_AGGR "aggregate_ogm"
void cleanup_procfs(void); void cleanup_procfs(void);
int setup_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

View File

@ -22,13 +22,18 @@
#include "types.h" #include "types.h"
extern wait_queue_head_t thread_wait; 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 slide_own_bcast_window(struct batman_if *batman_if);
void batman_data_ready(struct sock *sk, int len); void receive_bat_packet(struct ethhdr *ethhdr,
void purge_orig(struct work_struct *work); struct batman_packet *batman_packet,
int packet_recv_thread(void *data); unsigned char *hna_buff, int hna_buff_len,
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); 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);

View File

@ -21,16 +21,14 @@
#include "main.h" #include "main.h"
#include "send.h" #include "send.h"
#include "log.h"
#include "routing.h" #include "routing.h"
#include "translation-table.h" #include "translation-table.h"
#include "soft-interface.h"
#include "hard-interface.h" #include "hard-interface.h"
#include "types.h" #include "types.h"
#include "vis.h" #include "vis.h"
#include "aggregation.h" #include "aggregation.h"
#include "compat.h"
/* apply hop penalty for a normal link */ /* apply hop penalty for a normal link */
static uint8_t hop_penalty(const uint8_t tq) static uint8_t hop_penalty(const uint8_t tq)
{ {
@ -59,51 +57,69 @@ static unsigned long forward_send_time(void)
return send_time; return send_time;
} }
/* sends a raw packet. */ /* send out an already prepared packet to the given address via the
void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, * specified batman interface */
struct batman_if *batman_if, uint8_t *dst_addr) int send_skb_packet(struct sk_buff *skb,
struct batman_if *batman_if,
uint8_t *dst_addr)
{ {
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
struct sk_buff *skb;
int retval;
char *data;
if (batman_if->if_active != IF_ACTIVE) 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)) { if (!(batman_if->net_dev->flags & IFF_UP)) {
debug_log(LOG_TYPE_WARN, printk(KERN_WARNING
"Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n", "batman-adv:Interface %s is not up - can't send packet via that interface!\n",
batman_if->dev); batman_if->dev);
return; goto send_skb_err;
} }
skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr)); /* push to the ethernet header. */
if (!skb) if (my_skb_push(skb, sizeof(struct ethhdr)) < 0)
return; goto send_skb_err;
data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
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_source, batman_if->net_dev->dev_addr, ETH_ALEN);
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
skb_reset_mac_header(skb);
skb_set_network_header(skb, ETH_HLEN); skb_set_network_header(skb, ETH_HLEN);
skb->priority = TC_PRIO_CONTROL; skb->priority = TC_PRIO_CONTROL;
skb->protocol = __constant_htons(ETH_P_BATMAN); skb->protocol = __constant_htons(ETH_P_BATMAN);
skb->dev = batman_if->net_dev; skb->dev = batman_if->net_dev;
/* dev_queue_xmit() returns a negative result on error. However on /* dev_queue_xmit() returns a negative result on error. However on
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
* (which is > 0). This will not be treated as an error. */ * (which is > 0). This will not be treated as an error. */
retval = dev_queue_xmit(skb);
if (retval < 0) return dev_queue_xmit(skb);
debug_log(LOG_TYPE_CRIT, send_skb_err:
"Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n", kfree_skb(skb);
retval); 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 */ /* 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; uint8_t packet_num;
int16_t buff_pos; int16_t buff_pos;
struct batman_packet *batman_packet; struct batman_packet *batman_packet;
char orig_str[ETH_STR_LEN];
if (batman_if->if_active != IF_ACTIVE) if (batman_if->if_active != IF_ACTIVE)
return; return;
@ -136,19 +151,18 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
else else
batman_packet->flags &= ~DIRECTLINK; batman_packet->flags &= ~DIRECTLINK;
addr_to_string(orig_str, batman_packet->orig);
fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
"Sending own" : "Sending own" :
"Forwarding")); "Forwarding"));
debug_log(LOG_TYPE_BATMAN, bat_dbg(DBG_BATMAN,
"%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n", "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
fwd_str, fwd_str,
(packet_num > 0 ? "aggregated " : ""), (packet_num > 0 ? "aggregated " : ""),
orig_str, ntohs(batman_packet->seqno), batman_packet->orig, ntohs(batman_packet->seqno),
batman_packet->tq, batman_packet->ttl, batman_packet->tq, batman_packet->ttl,
(batman_packet->flags & DIRECTLINK ? (batman_packet->flags & DIRECTLINK ?
"on" : "off"), "on" : "off"),
batman_if->dev, batman_if->addr_str); batman_if->dev, batman_if->addr_str);
buff_pos += sizeof(struct batman_packet) + buff_pos += sizeof(struct batman_packet) +
(batman_packet->num_hna * ETH_ALEN); (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_if *batman_if;
struct batman_packet *batman_packet = struct batman_packet *batman_packet =
(struct batman_packet *)(forw_packet->packet_buff); (struct batman_packet *)(forw_packet->packet_buff);
char orig_str[ETH_STR_LEN];
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) { if (!forw_packet->if_incoming) {
debug_log(LOG_TYPE_CRIT, printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n");
"Error - can't forward packet: incoming iface not specified\n");
return; return;
} }
if (forw_packet->if_incoming->if_active != IF_ACTIVE) if (forw_packet->if_incoming->if_active != IF_ACTIVE)
return; return;
addr_to_string(orig_str, batman_packet->orig);
/* multihomed peer assumed */ /* multihomed peer assumed */
/* non-primary OGMs are only broadcasted on their interface */ /* non-primary OGMs are only broadcasted on their interface */
if ((directlink && (batman_packet->ttl == 1)) || if ((directlink && (batman_packet->ttl == 1)) ||
(forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
/* FIXME: what about aggregated packets ? */ /* FIXME: what about aggregated packets ? */
debug_log(LOG_TYPE_BATMAN, bat_dbg(DBG_BATMAN,
"%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n", "%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n",
(forw_packet->own ? "Sending own" : "Forwarding"), (forw_packet->own ? "Sending own" : "Forwarding"),
orig_str, ntohs(batman_packet->seqno), batman_packet->orig, ntohs(batman_packet->seqno),
batman_packet->ttl, forw_packet->if_incoming->dev, batman_packet->ttl, forw_packet->if_incoming->dev,
forw_packet->if_incoming->addr_str); forw_packet->if_incoming->addr_str);
send_raw_packet(forw_packet->packet_buff, send_raw_packet(forw_packet->packet_buff,
forw_packet->packet_len, forw_packet->packet_len,
@ -238,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if)
{ {
unsigned long send_time; unsigned long send_time;
struct batman_packet *batman_packet; struct batman_packet *batman_packet;
int vis_server = atomic_read(&vis_mode);
/** /**
* the interface gets activated here to avoid race conditions between * 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 */ /* change sequence number to network order */
batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); 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; batman_packet->flags = VIS_SERVER;
else else
batman_packet->flags = 0; batman_packet->flags = 0;
@ -286,7 +297,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
unsigned long send_time; unsigned long send_time;
if (batman_packet->ttl <= 1) { if (batman_packet->ttl <= 1) {
debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n"); bat_dbg(DBG_BATMAN, "ttl exceeded \n");
return; return;
} }
@ -314,9 +325,9 @@ void schedule_forward_packet(struct orig_node *orig_node,
/* apply hop penalty */ /* apply hop penalty */
batman_packet->tq = hop_penalty(batman_packet->tq); 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", 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, in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
batman_packet->ttl); batman_packet->ttl);
batman_packet->seqno = htons(batman_packet->seqno); 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) 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->packet_buff);
kfree(forw_packet); 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, static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
unsigned long send_time) unsigned long send_time)
{ {
unsigned long flags;
INIT_HLIST_NODE(&forw_packet->list); INIT_HLIST_NODE(&forw_packet->list);
/* add new packet to 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); 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 */ /* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet->delayed_work, 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); 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; 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) if (!forw_packet)
return; return;
forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); skb = skb_copy(skb, GFP_ATOMIC);
if (!forw_packet->packet_buff) { if (!skb) {
kfree(forw_packet); kfree(forw_packet);
return; return;
} }
forw_packet->packet_len = packet_len; skb_reset_mac_header(skb);
memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len);
forw_packet->skb = skb;
forw_packet->packet_buff = NULL;
/* how often did we send the bcast packet ? */ /* how often did we send the bcast packet ? */
forw_packet->num_packets = 0; 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); container_of(work, struct delayed_work, work);
struct forw_packet *forw_packet = struct forw_packet *forw_packet =
container_of(delayed_work, struct forw_packet, delayed_work); 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); hlist_del(&forw_packet->list);
spin_unlock(&forw_bcast_list_lock); spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
/* rebroadcast packet */ /* rebroadcast packet */
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) { list_for_each_entry_rcu(batman_if, &if_list, list) {
send_raw_packet(forw_packet->packet_buff, /* send a copy of the saved skb */
forw_packet->packet_len, skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
if (skb1)
send_skb_packet(skb1,
batman_if, broadcastAddr); batman_if, broadcastAddr);
} }
rcu_read_unlock(); rcu_read_unlock();
@ -415,10 +435,11 @@ void send_outstanding_bat_packet(struct work_struct *work)
container_of(work, struct delayed_work, work); container_of(work, struct delayed_work, work);
struct forw_packet *forw_packet = struct forw_packet *forw_packet =
container_of(delayed_work, struct forw_packet, delayed_work); 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); hlist_del(&forw_packet->list);
spin_unlock(&forw_bat_list_lock); spin_unlock_irqrestore(&forw_bat_list_lock, flags);
send_packet(forw_packet); send_packet(forw_packet);
@ -438,38 +459,39 @@ void purge_outstanding_packets(void)
{ {
struct forw_packet *forw_packet; struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node; 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 */ /* 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, hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
&forw_bcast_list, list) { &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 * send_outstanding_bcast_packet() will lock the list to
* delete the item from the list * delete the item from the list
*/ */
cancel_delayed_work_sync(&forw_packet->delayed_work); 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 */ /* 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, hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
&forw_bat_list, list) { &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 * send_outstanding_bat_packet() will lock the list to
* delete the item from the list * delete the item from the list
*/ */
cancel_delayed_work_sync(&forw_packet->delayed_work); 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);
} }

View File

@ -22,6 +22,9 @@
#include "types.h" #include "types.h"
void send_own_packet_work(struct work_struct *work); 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, void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
struct batman_if *batman_if, uint8_t *dst_addr); struct batman_if *batman_if, uint8_t *dst_addr);
void schedule_own_packet(struct batman_if *batman_if); 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, struct batman_packet *batman_packet,
uint8_t directlink, int hna_buff_len, uint8_t directlink, int hna_buff_len,
struct batman_if *if_outgoing); 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_bcast_packet(struct work_struct *work);
void send_outstanding_bat_packet(struct work_struct *work); void send_outstanding_bat_packet(struct work_struct *work);
void purge_outstanding_packets(void); void purge_outstanding_packets(void);

View File

@ -24,18 +24,15 @@
#include "hard-interface.h" #include "hard-interface.h"
#include "send.h" #include "send.h"
#include "translation-table.h" #include "translation-table.h"
#include "log.h"
#include "types.h" #include "types.h"
#include "hash.h" #include "hash.h"
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include "compat.h"
static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
* broadcast storms */ * broadcast storms */
static int32_t skb_packets; static int32_t skb_packets;
static int32_t skb_bad_packets; static int32_t skb_bad_packets;
static int32_t lock_dropped;
unsigned char mainIfAddr[ETH_ALEN]; unsigned char mainIfAddr[ETH_ALEN];
static unsigned char mainIfAddr_default[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); 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; int result = 0;
skb_packets++; skb_packets++;
if (skb->data - len < skb->head) { if (skb_headroom(skb) < len) {
skb_bad_packets++; skb_bad_packets++;
result = pskb_expand_head(skb, len, 0, GFP_ATOMIC); result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
@ -122,7 +119,7 @@ void interface_setup(struct net_device *dev)
/* generate random address */ /* generate random address */
random_ether_addr(dev_addr); 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); SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
@ -147,9 +144,18 @@ struct net_device_stats *interface_stats(struct net_device *dev)
return &priv->stats; 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) 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 orig_node *orig_node;
struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *priv = netdev_priv(dev); struct bat_priv *priv = netdev_priv(dev);
struct batman_if *batman_if;
uint8_t dstaddr[6];
int data_len = skb->len; int data_len = skb->len;
unsigned long flags;
if (atomic_read(&module_state) != MODULE_ACTIVE) if (atomic_read(&module_state) != MODULE_ACTIVE)
goto dropped; goto dropped;
@ -186,7 +195,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
goto dropped; goto dropped;
bcast_packet = (struct bcast_packet *)skb->data; bcast_packet = (struct bcast_packet *)skb->data;
bcast_packet->version = COMPAT_VERSION; bcast_packet->version = COMPAT_VERSION;
/* batman packet type: broadcast */ /* 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 /* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */ * this mac is known throughout the mesh */
memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN); memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
/* set broadcast sequence number */ /* set broadcast sequence number */
bcast_packet->seqno = htons(bcast_seqno); bcast_packet->seqno = htons(bcast_seqno);
bcast_seqno++; bcast_seqno++;
/* broadcast packet */ /* 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 */ /* unicast packet */
} else { } else {
spin_lock_irqsave(&orig_hash_lock, flags);
/* 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;
}
/* get routing information */ /* get routing information */
orig_node = ((struct orig_node *)hash_find(orig_hash, orig_node = ((struct orig_node *)hash_find(orig_hash,
ethhdr->h_dest)); 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) if (orig_node->batman_if->if_active != IF_ACTIVE)
goto unlock; goto unlock;
send_raw_packet(skb->data, skb->len, /* don't lock while sending the packets ... we therefore
orig_node->batman_if, * copy the required data before sending */
orig_node->router->addr);
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 { } else {
goto unlock; goto unlock;
} }
spin_unlock(&orig_hash_lock);
} }
priv->stats.tx_packets++; priv->stats.tx_packets++;
@ -259,42 +264,44 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
goto end; goto end;
unlock: unlock:
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
dropped: dropped:
priv->stats.tx_dropped++; priv->stats.tx_dropped++;
end: end:
kfree_skb(skb); return NETDEV_TX_OK;
return 0;
} }
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); struct bat_priv *priv = netdev_priv(dev);
skb = dev_alloc_skb(packet_len); /* check if enough space is available for pulling, and pull */
if (!pskb_may_pull(skb, hdr_size)) {
if (!skb) { kfree_skb(skb);
priv->stats.rx_dropped++; return;
goto out;
} }
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->dev = dev;
skb->protocol = eth_type_trans(skb, 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_packets++;
priv->stats.rx_bytes += packet_len; priv->stats.rx_bytes += skb->len;
dev->last_rx = jiffies; dev->last_rx = jiffies;
netif_rx(skb); netif_rx(skb);
out:
return;
} }
/* ethtool */ /* 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) static void bat_set_msglevel(struct net_device *dev, u32 value)
{ {
return;
} }
static u32 bat_get_link(struct net_device *dev) static u32 bat_get_link(struct net_device *dev)

View File

@ -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_set_mac_addr(struct net_device *dev, void *addr);
int interface_change_mtu(struct net_device *dev, int new_mtu); int interface_change_mtu(struct net_device *dev, int new_mtu);
int interface_tx(struct sk_buff *skb, struct net_device *dev); 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[]; extern unsigned char mainIfAddr[];

View File

@ -21,11 +21,9 @@
#include "main.h" #include "main.h"
#include "translation-table.h" #include "translation-table.h"
#include "log.h"
#include "soft-interface.h" #include "soft-interface.h"
#include "types.h" #include "types.h"
#include "hash.h" #include "hash.h"
#include "compat.h"
struct hashtable_t *hna_local_hash; struct hashtable_t *hna_local_hash;
static struct hashtable_t *hna_global_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_local_entry *hna_local_entry;
struct hna_global_entry *hna_global_entry; struct hna_global_entry *hna_global_entry;
struct hashtable_t *swaphash; struct hashtable_t *swaphash;
char hna_str[ETH_STR_LEN];
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, flags); spin_lock_irqsave(&hna_local_hash_lock, flags);
@ -75,19 +72,17 @@ void hna_local_add(uint8_t *addr)
return; return;
} }
addr_to_string(hna_str, addr);
/* only announce as many hosts as possible in the batman-packet and /* 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 space in batman_packet->num_hna That also should give a limit to
MAC-flooding. */ MAC-flooding. */
if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
(num_hna + 1 > 255)) { (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; return;
} }
debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n", bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n",
hna_str); addr);
hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
if (!hna_local_entry) if (!hna_local_entry)
@ -113,7 +108,7 @@ void hna_local_add(uint8_t *addr)
hna_local_hash->size * 2); hna_local_hash->size * 2);
if (swaphash == NULL) 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 else
hna_local_hash = swaphash; 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) int hna_local_fill_buffer(unsigned char *buff, int buff_len)
{ {
struct hna_local_entry *hna_local_entry; struct hna_local_entry *hna_local_entry;
struct hash_it_t *hashit = NULL; HASHIT(hashit);
int i = 0; int i = 0;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, 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) if (buff_len < (i + 1) * ETH_ALEN)
break; break;
hna_local_entry = hashit->bucket->data; hna_local_entry = hashit.bucket->data;
memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
i++; 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) int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
{ {
struct hna_local_entry *hna_local_entry; struct hna_local_entry *hna_local_entry;
struct hash_it_t *hashit = NULL; HASHIT(hashit);
int bytes_written = 0; int bytes_written = 0;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, 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) if (buff_len < bytes_written + ETH_STR_LEN + 4)
break; break;
hna_local_entry = hashit->bucket->data; hna_local_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4, bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
" * %02x:%02x:%02x:%02x:%02x:%02x\n", " * %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, static void hna_local_del(struct hna_local_entry *hna_local_entry,
char *message) char *message)
{ {
char hna_str[ETH_STR_LEN]; bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n",
hna_local_entry->addr, message);
addr_to_string(hna_str, hna_local_entry->addr);
debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
hna_str, message);
hash_remove(hna_local_hash, hna_local_entry->addr); hash_remove(hna_local_hash, hna_local_entry->addr);
_hna_local_del(hna_local_entry); _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) void hna_local_purge(struct work_struct *work)
{ {
struct hna_local_entry *hna_local_entry; struct hna_local_entry *hna_local_entry;
struct hash_it_t *hashit = NULL; HASHIT(hashit);
unsigned long flags; unsigned long flags;
unsigned long timeout; unsigned long timeout;
spin_lock_irqsave(&hna_local_hash_lock, 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)) {
hna_local_entry = hashit->bucket->data; hna_local_entry = hashit.bucket->data;
timeout = hna_local_entry->last_seen + timeout = hna_local_entry->last_seen +
((LOCAL_HNA_TIMEOUT / 1000) * HZ); ((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_global_entry *hna_global_entry;
struct hna_local_entry *hna_local_entry; struct hna_local_entry *hna_local_entry;
struct hashtable_t *swaphash; struct hashtable_t *swaphash;
char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
int hna_buff_count = 0; int hna_buff_count = 0;
unsigned long flags; unsigned long flags;
unsigned char *hna_ptr; unsigned char *hna_ptr;
addr_to_string(orig_str, orig_node->orig);
while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
spin_lock_irqsave(&hna_global_hash_lock, flags); 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); memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
addr_to_string(hna_str, hna_global_entry->addr); bat_dbg(DBG_ROUTES,
debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str); "Creating new global hna entry: %pM (via %pM)\n",
hna_global_entry->addr, orig_node->orig);
spin_lock_irqsave(&hna_global_hash_lock, flags); spin_lock_irqsave(&hna_global_hash_lock, flags);
hash_add(hna_global_hash, hna_global_entry); 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++; 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) { if (hna_buff_len > 0) {
orig_node->hna_buff = kmalloc(orig_node->hna_buff_len, orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
GFP_ATOMIC); if (orig_node->hna_buff) {
memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len); memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
} else { orig_node->hna_buff_len = hna_buff_len;
orig_node->hna_buff = NULL; }
} }
spin_lock_irqsave(&hna_global_hash_lock, flags); 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); hna_global_hash->size * 2);
if (swaphash == NULL) 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 else
hna_global_hash = swaphash; 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) int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
{ {
struct hna_global_entry *hna_global_entry; struct hna_global_entry *hna_global_entry;
struct hash_it_t *hashit = NULL; HASHIT(hashit);
int bytes_written = 0; int bytes_written = 0;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&hna_global_hash_lock, 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) if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
break; break;
hna_global_entry = hashit->bucket->data; hna_global_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, bytes_written += snprintf(buff + bytes_written,
(2 * ETH_STR_LEN) + 10, (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, void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *message) char *message)
{ {
char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN]; bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n",
hna_global_entry->addr, hna_global_entry->orig_node->orig,
addr_to_string(orig_str, hna_global_entry->orig_node->orig); message);
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);
hash_remove(hna_global_hash, hna_global_entry->addr); hash_remove(hna_global_hash, hna_global_entry->addr);
kfree(hna_global_entry); kfree(hna_global_entry);

View File

@ -23,6 +23,7 @@
int hna_local_init(void); int hna_local_init(void);
void hna_local_add(uint8_t *addr); 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(unsigned char *buff, int buff_len);
int hna_local_fill_buffer_text(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); void hna_local_purge(struct work_struct *work);

View File

@ -39,7 +39,6 @@ struct batman_if {
char if_active; char if_active;
char addr_str[ETH_STR_LEN]; char addr_str[ETH_STR_LEN];
struct net_device *net_dev; struct net_device *net_dev;
struct socket *raw_sock;
atomic_t seqno; atomic_t seqno;
unsigned char *packet_buff; unsigned char *packet_buff;
int packet_len; int packet_len;
@ -75,7 +74,7 @@ struct neigh_node {
uint8_t tq_index; uint8_t tq_index;
uint8_t tq_avg; uint8_t tq_avg;
uint8_t last_ttl; 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]; TYPE_OF_WORD real_bits[NUM_WORDS];
struct orig_node *orig_node; struct orig_node *orig_node;
struct batman_if *if_incoming; struct batman_if *if_incoming;
@ -113,6 +112,7 @@ struct forw_packet { /* structure for forw_list maintaining packet
struct hlist_node list; struct hlist_node list;
unsigned long send_time; unsigned long send_time;
uint8_t own; uint8_t own;
struct sk_buff *skb;
unsigned char *packet_buff; unsigned char *packet_buff;
uint16_t packet_len; uint16_t packet_len;
uint32_t direct_link_flags; uint32_t direct_link_flags;
@ -121,4 +121,14 @@ struct forw_packet { /* structure for forw_list maintaining packet
struct batman_if *if_incoming; 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 #endif

View File

@ -23,11 +23,9 @@
#include "send.h" #include "send.h"
#include "translation-table.h" #include "translation-table.h"
#include "vis.h" #include "vis.h"
#include "log.h"
#include "soft-interface.h" #include "soft-interface.h"
#include "hard-interface.h" #include "hard-interface.h"
#include "hash.h" #include "hash.h"
#include "compat.h"
struct hashtable_t *vis_hash; struct hashtable_t *vis_hash;
DEFINE_SPINLOCK(vis_hash_lock); DEFINE_SPINLOCK(vis_hash_lock);
@ -50,39 +48,6 @@ static void free_info(void *data)
kfree(info); 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 */ /* Compare two vis packets, used by the hashing algorithm */
static int vis_info_cmp(void *data1, void *data2) 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; 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. */ /* tries to add one entry to the receive list. */
static void recv_list_add(struct list_head *recv_list, char *mac) 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; struct vis_info *info;
int is_new; 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); info = add_packet(vis_packet, vis_info_len, &is_new);
if (info == NULL) if (info == NULL)
goto end; goto end;
/* only if we are server ourselves and packet is newer than the one in /* only if we are server ourselves and packet is newer than the one in
* hash.*/ * 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); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
if (list_empty(&info->send_list)) if (list_empty(&info->send_list))
list_add_tail(&info->send_list, &send_list); list_add_tail(&info->send_list, &send_list);
} }
end: end:
spin_unlock(&vis_hash_lock); spin_unlock_irqrestore(&vis_hash_lock, flags);
} }
/* handle an incoming client update packet and schedule forward if needed. */ /* 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; struct vis_info *info;
int is_new; int is_new;
unsigned long flags;
int vis_server = atomic_read(&vis_mode);
/* clients shall not broadcast. */ /* clients shall not broadcast. */
if (is_bcast(vis_packet->target_orig)) if (is_bcast(vis_packet->target_orig))
return; return;
spin_lock(&vis_hash_lock); spin_lock_irqsave(&vis_hash_lock, flags);
info = add_packet(vis_packet, vis_info_len, &is_new); info = add_packet(vis_packet, vis_info_len, &is_new);
if (info == NULL) if (info == NULL)
goto end; 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 ... */ /* 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_my_mac(info->packet.target_orig) &&
is_new) { is_new) {
info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ 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); list_add_tail(&info->send_list, &send_list);
} }
end: 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 /* 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 */ * Must be called with the originator hash locked */
static int find_best_vis_server(struct vis_info *info) static int find_best_vis_server(struct vis_info *info)
{ {
struct hash_it_t *hashit = NULL; HASHIT(hashit);
struct orig_node *orig_node; struct orig_node *orig_node;
int best_tq = -1; int best_tq = -1;
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 != NULL) && if ((orig_node != NULL) &&
(orig_node->router != NULL) && (orig_node->router != NULL) &&
(orig_node->flags & VIS_SERVER) && (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 */ * returns 0 on success, -1 if no packet could be generated */
static int generate_vis_packet(void) static int generate_vis_packet(void)
{ {
struct hash_it_t *hashit = NULL; HASHIT(hashit_local);
HASHIT(hashit_global);
struct orig_node *orig_node; struct orig_node *orig_node;
struct vis_info *info = (struct vis_info *)my_vis_info; struct vis_info *info = (struct vis_info *)my_vis_info;
struct vis_info_entry *entry, *entry_array; struct vis_info_entry *entry, *entry_array;
@ -307,27 +339,27 @@ static int generate_vis_packet(void)
unsigned long flags; unsigned long flags;
info->first_seen = jiffies; 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); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
info->packet.ttl = TTL; info->packet.ttl = TTL;
info->packet.seqno++; info->packet.seqno++;
info->packet.entries = 0; 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); best_tq = find_best_vis_server(info);
if (best_tq < 0) { if (best_tq < 0) {
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
return -1; return -1;
} }
} }
hashit = NULL;
entry_array = (struct vis_info_entry *) entry_array = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info)); ((char *)info + sizeof(struct vis_info));
while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { while (hash_iterate(orig_hash, &hashit_global)) {
orig_node = hashit->bucket->data; orig_node = hashit_global.bucket->data;
if (orig_node->router != NULL if (orig_node->router != NULL
&& compare_orig(orig_node->router->addr, orig_node->orig) && compare_orig(orig_node->router->addr, orig_node->orig)
&& orig_node->batman_if && orig_node->batman_if
@ -342,18 +374,17 @@ static int generate_vis_packet(void)
info->packet.entries++; info->packet.entries++;
if (vis_packet_full(info)) { if (vis_packet_full(info)) {
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0; return 0;
} }
} }
} }
spin_unlock(&orig_hash_lock); spin_unlock_irqrestore(&orig_hash_lock, flags);
hashit = NULL;
spin_lock_irqsave(&hna_local_hash_lock, 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_local)) {
hna_local_entry = hashit->bucket->data; hna_local_entry = hashit_local.bucket->data;
entry = &entry_array[info->packet.entries]; entry = &entry_array[info->packet.entries];
memset(entry->src, 0, ETH_ALEN); memset(entry->src, 0, ETH_ALEN);
memcpy(entry->dest, hna_local_entry->addr, 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) static void purge_vis_packets(void)
{ {
struct hash_it_t *hashit = NULL; HASHIT(hashit);
struct vis_info *info; struct vis_info *info;
while (NULL != (hashit = hash_iterate(vis_hash, hashit))) { while (hash_iterate(vis_hash, &hashit)) {
info = hashit->bucket->data; info = hashit.bucket->data;
if (info == my_vis_info) /* never purge own data. */ if (info == my_vis_info) /* never purge own data. */
continue; continue;
if (time_after(jiffies, if (time_after(jiffies,
info->first_seen + (VIS_TIMEOUT/1000)*HZ)) { info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
hash_remove_bucket(vis_hash, hashit); hash_remove_bucket(vis_hash, &hashit);
free_info(info); 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) 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; 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. */ /* send to all routers in range. */
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 it's a vis server and reachable, send it. */ /* if it's a vis server and reachable, send it. */
if (orig_node && 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); 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) static void unicast_vis_packet(struct vis_info *info, int packet_length)
{ {
struct orig_node *orig_node; 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 *) orig_node = ((struct orig_node *)
hash_find(orig_hash, info->packet.target_orig)); 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->batman_if,
orig_node->router->addr); 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() */ /* 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; int packet_length;
if (info->packet.ttl < 2) { if (info->packet.ttl < 2) {
debug_log(LOG_TYPE_NOTICE, printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
"Error - can't send vis packet: ttl exceeded\n");
return; return;
} }
@ -467,8 +499,9 @@ static void send_vis_packet(struct vis_info *info)
static void send_vis_packets(struct work_struct *work) static void send_vis_packets(struct work_struct *work)
{ {
struct vis_info *info, *temp; struct vis_info *info, *temp;
unsigned long flags;
spin_lock(&vis_hash_lock); spin_lock_irqsave(&vis_hash_lock, flags);
purge_vis_packets(); purge_vis_packets();
if (generate_vis_packet() == 0) if (generate_vis_packet() == 0)
@ -479,7 +512,7 @@ static void send_vis_packets(struct work_struct *work)
list_del_init(&info->send_list); list_del_init(&info->send_list);
send_vis_packet(info); send_vis_packet(info);
} }
spin_unlock(&vis_hash_lock); spin_unlock_irqrestore(&vis_hash_lock, flags);
start_vis_timer(); start_vis_timer();
} }
static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets); 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) */ * initialized (e.g. bat0 is initialized, interfaces have been added) */
int vis_init(void) int vis_init(void)
{ {
unsigned long flags;
if (vis_hash) if (vis_hash)
return 1; 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); vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
if (!vis_hash) { 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; goto err;
} }
my_vis_info = kmalloc(1000, GFP_ATOMIC); my_vis_info = kmalloc(1000, GFP_ATOMIC);
if (!my_vis_info) { 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; goto err;
} }
@ -511,7 +545,6 @@ int vis_init(void)
INIT_LIST_HEAD(&my_vis_info->send_list); INIT_LIST_HEAD(&my_vis_info->send_list);
my_vis_info->packet.version = COMPAT_VERSION; my_vis_info->packet.version = COMPAT_VERSION;
my_vis_info->packet.packet_type = BAT_VIS; 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.ttl = TTL;
my_vis_info->packet.seqno = 0; my_vis_info->packet.seqno = 0;
my_vis_info->packet.entries = 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); memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
if (hash_add(vis_hash, my_vis_info) < 0) { if (hash_add(vis_hash, my_vis_info) < 0) {
debug_log(LOG_TYPE_CRIT, printk(KERN_ERR
"Can't add own vis packet into hash\n"); "batman-adv:Can't add own vis packet into hash\n");
free_info(my_vis_info); /* not in hash, need to remove it free_info(my_vis_info); /* not in hash, need to remove it
* manually. */ * manually. */
goto err; goto err;
} }
spin_unlock(&vis_hash_lock); spin_unlock_irqrestore(&vis_hash_lock, flags);
start_vis_timer(); start_vis_timer();
return 1; return 1;
err: err:
spin_unlock(&vis_hash_lock); spin_unlock_irqrestore(&vis_hash_lock, flags);
vis_quit(); vis_quit();
return 0; return 0;
} }
@ -542,23 +575,23 @@ err:
/* shutdown vis-server */ /* shutdown vis-server */
void vis_quit(void) void vis_quit(void)
{ {
unsigned long flags;
if (!vis_hash) if (!vis_hash)
return; return;
cancel_delayed_work_sync(&vis_timer_wq); cancel_delayed_work_sync(&vis_timer_wq);
spin_lock(&vis_hash_lock); spin_lock_irqsave(&vis_hash_lock, flags);
/* properly remove, kill timers ... */ /* properly remove, kill timers ... */
hash_delete(vis_hash, free_info); hash_delete(vis_hash, free_info);
vis_hash = NULL; vis_hash = NULL;
my_vis_info = NULL; my_vis_info = NULL;
spin_unlock(&vis_hash_lock); spin_unlock_irqrestore(&vis_hash_lock, flags);
} }
/* schedule packets for (re)transmission */ /* schedule packets for (re)transmission */
static void start_vis_timer(void) static void start_vis_timer(void)
{ {
queue_delayed_work(bat_event_workqueue, &vis_timer_wq, queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
(atomic_read(&vis_interval)/1000) * HZ); (atomic_read(&vis_interval) * HZ) / 1000);
} }

View File

@ -45,16 +45,15 @@ struct recvlist_node {
uint8_t mac[ETH_ALEN]; uint8_t mac[ETH_ALEN];
}; };
enum vis_formats {
DOT_DRAW,
JSON,
};
extern struct hashtable_t *vis_hash; extern struct hashtable_t *vis_hash;
extern spinlock_t vis_hash_lock; extern spinlock_t vis_hash_lock;
void vis_set_mode(int mode); void proc_vis_read_entry(struct seq_file *seq,
int is_vis_server(void); 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, void receive_server_sync_packet(struct vis_packet *vis_packet,
int vis_info_len); int vis_info_len);
void receive_client_update_packet(struct vis_packet *vis_packet, void receive_client_update_packet(struct vis_packet *vis_packet,

View File

@ -26,7 +26,6 @@
#define __NO_VERSION__ #define __NO_VERSION__
#include "comedi.h" #include "comedi.h"
#include <linux/smp_lock.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include "comedi_compat32.h" #include "comedi_compat32.h"

View File

@ -63,7 +63,7 @@ module_param(comedi_debug, int, 0644);
int comedi_autoconfig = 1; int comedi_autoconfig = 1;
module_param(comedi_autoconfig, bool, 0444); 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); module_param(comedi_num_legacy_minors, int, 0444);
static DEFINE_SPINLOCK(comedi_file_info_table_lock); 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, 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_subdevice *s;
struct comedi_async *async; struct comedi_async *async;
@ -1612,7 +1612,7 @@ done:
} }
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes, 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_subdevice *s;
struct comedi_async *async; 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 (async->cb_mask & s->async->events) {
if (comedi_get_subdevice_runflags(s) & SRF_USER) { if (comedi_get_subdevice_runflags(s) & SRF_USER) {
wake_up_interruptible(&async->wait_head); 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); 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); kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
}
} else { } else {
if (async->cb_func) if (async->cb_func)
async->cb_func(s->async->events, async->cb_arg); async->cb_func(s->async->events, async->cb_arg);

View File

@ -44,7 +44,7 @@
#include <linux/cdev.h> #include <linux/cdev.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <asm/io.h> #include <linux/io.h>
#include <asm/system.h> #include <asm/system.h>
static int postconfig(struct comedi_device *dev); 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) static void __comedi_device_detach(struct comedi_device *dev)
{ {
dev->attached = 0; dev->attached = 0;
if (dev->driver) { if (dev->driver)
dev->driver->detach(dev); dev->driver->detach(dev);
} else { else
printk("BUG: dev->driver=NULL in comedi_device_detach()\n"); printk("BUG: dev->driver=NULL in comedi_device_detach()\n");
}
cleanup_device(dev); cleanup_device(dev);
} }
@ -380,9 +379,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (insn->insn == INSN_READ) { if (insn->insn == INSN_READ)
data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1; data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
}
return 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; new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
/* if no change is required, do nothing */ /* 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; return 0;
}
/* deallocate old buffer */ /* deallocate old buffer */
if (async->prealloc_buf) { if (async->prealloc_buf) {
vunmap(async->prealloc_buf); vunmap(async->prealloc_buf);
@ -494,9 +492,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
(void *) (void *)
get_zeroed_page(GFP_KERNEL); get_zeroed_page(GFP_KERNEL);
} }
if (async->buf_page_list[i].virt_addr == NULL) { if (async->buf_page_list[i].virt_addr == NULL)
break; break;
}
mem_map_reserve(virt_to_page mem_map_reserve(virt_to_page
(async->buf_page_list[i]. (async->buf_page_list[i].
virt_addr)); 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; 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; nbytes = free_end - async->buf_write_alloc_count;
}
async->buf_write_alloc_count += nbytes; async->buf_write_alloc_count += nbytes;
/* barrier insures the read of buf_read_count above occurs before /* barrier insures the read of buf_read_count above occurs before
we write data to the write-alloc'ed buffer space */ 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; 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; nbytes = 0;
}
async->buf_write_alloc_count += nbytes; async->buf_write_alloc_count += nbytes;
/* barrier insures the read of buf_read_count above occurs before /* barrier insures the read of buf_read_count above occurs before
we write data to the write-alloc'ed buffer space */ 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_count += nbytes;
async->buf_write_ptr += nbytes; async->buf_write_ptr += nbytes;
comedi_buf_munge(async, async->buf_write_count - async->munge_count); 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; async->buf_write_ptr %= async->prealloc_bufsz;
}
return nbytes; return nbytes;
} }

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */
@ -173,11 +173,10 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
} while (dw_eeprom_busy == EEPROM_BUSY); } while (dw_eeprom_busy == EEPROM_BUSY);
/* Select the upper address part */ /* Select the upper address part */
if (i_Counter == 0) { if (i_Counter == 0)
b_ReadLowByte = pb_ReadByte[0]; b_ReadLowByte = pb_ReadByte[0];
} else { else
b_ReadHighByte = pb_ReadByte[0]; b_ReadHighByte = pb_ReadByte[0];
}
/* Sleep */ /* Sleep */
msleep(1); msleep(1);

View File

@ -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 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 @endverbatim
*/ */

View File

@ -77,8 +77,8 @@ struct addi_board {
int i_NbrAoChannel; /* num of D/A chans */ int i_NbrAoChannel; /* num of D/A chans */
int i_AiMaxdata; /* resolution of A/D */ int i_AiMaxdata; /* resolution of A/D */
int i_AoMaxdata; /* resolution of D/A */ int i_AoMaxdata; /* resolution of D/A */
const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ 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_AoRangelist; /* rangelist for D/A */
int i_NbrDiChannel; /* Number of DI channels */ int i_NbrDiChannel; /* Number of DI channels */
int i_NbrDoChannel; /* Number of DO channels */ int i_NbrDoChannel; /* Number of DO channels */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */
@ -54,7 +54,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
#include "hwdrv_apci1032.h" #include "hwdrv_apci1032.h"
#include <linux/delay.h> #include <linux/delay.h>
/* Global variables */ /* 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 = ui_TmpValue =
inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
} /* if (data[1] == ADDIDATA_OR) */ } /* if (data[1] == ADDIDATA_OR) */
else { else
outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); 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) */ } /* if( data[0] == ADDIDATA_ENABLE) */
else { else {
ul_Command1 = ul_Command1 & 0xFFFF0000; ul_Command1 = ul_Command1 & 0xFFFF0000;
@ -221,9 +221,9 @@ int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub
} /* switch(ui_NoOfChannels) */ } /* switch(ui_NoOfChannels) */
} /* if(data[1]==0) */ } /* if(data[1]==0) */
else { else {
if (data[1] == 1) { if (data[1] == 1)
*data = ui_InterruptStatus; *data = ui_InterruptStatus;
} /* if(data[1]==1) */ /* if(data[1]==1) */
} /* else if(data[1]==0) */ } /* else if(data[1]==0) */
return insn->n; return insn->n;
} }

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */
@ -45,7 +45,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
*/ */
#include "hwdrv_apci3120.h" #include "hwdrv_apci3120.h"
static unsigned int ui_Temp = 0; static unsigned int ui_Temp;
/* FUNCTION DEFINITIONS */ /* FUNCTION DEFINITIONS */
@ -98,25 +98,22 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
devpriv->b_InterruptMode = APCI3120_EOS_MODE; devpriv->b_InterruptMode = APCI3120_EOS_MODE;
if (data[1]) { if (data[1])
devpriv->b_EocEosInterrupt = APCI3120_ENABLE; devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
} else else
devpriv->b_EocEosInterrupt = APCI3120_DISABLE; devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
/* Copy channel list and Range List to devpriv */ /* Copy channel list and Range List to devpriv */
devpriv->ui_AiNbrofChannels = data[3]; 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]; devpriv->ui_AiChannelList[i] = data[4 + i];
}
} else /* EOC */ } else { /* EOC */
{
devpriv->b_InterruptMode = APCI3120_EOC_MODE; devpriv->b_InterruptMode = APCI3120_EOC_MODE;
if (data[1]) { if (data[1])
devpriv->b_EocEosInterrupt = APCI3120_ENABLE; devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
} else { else
devpriv->b_EocEosInterrupt = APCI3120_DISABLE; devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
}
} }
return insn->n; return insn->n;
@ -166,13 +163,9 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd
devpriv->us_OutputRegister = 0; devpriv->us_OutputRegister = 0;
/* devpriv->b_DigitalOutputRegister=0; */ /* devpriv->b_DigitalOutputRegister=0; */
if (insn->unused[0] == 222) /* second insn read */ if (insn->unused[0] == 222) { /* second insn read */
{ for (i = 0; i < insn->n; i++)
for (i = 0; i < insn->n; i++) {
data[i] = devpriv->ui_AiReadData[i]; data[i] = devpriv->ui_AiReadData[i];
}
} else { } else {
devpriv->tsk_Current = current; /* Save the current process task structure */ 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 */ /* 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++; err++;
}
if (cmd->scan_begin_src != TRIG_TIMER && if (cmd->scan_begin_src != TRIG_TIMER &&
cmd->scan_begin_src != TRIG_FOLLOW) cmd->scan_begin_src != TRIG_FOLLOW)
@ -548,16 +540,14 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
err++; 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) { if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs; cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
err++; 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->scan_begin_src == TRIG_TIMER) {
if ((cmd->convert_arg) if ((cmd->convert_arg)
&& (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; */ /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
devpriv->ui_AiDataLength = s->async->prealloc_bufsz; 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; devpriv->ui_AiNbrofScans = cmd->stop_arg;
} else { else
devpriv->ui_AiNbrofScans = 0; devpriv->ui_AiNbrofScans = 0;
}
devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
devpriv->ui_AiTimer1 = 0; devpriv->ui_AiTimer1 = 0;
@ -849,9 +838,8 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
} }
/*** EL241003 End ******************************************************************************/ /*** EL241003 End ******************************************************************************/
if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */ i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */
}
switch (mode) { switch (mode) {
case 1: case 1:
/* init timer0 in mode 2 */ /* init timer0 in mode 2 */
@ -1049,12 +1037,10 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
dmalen1 = 4; dmalen1 = 4;
} }
} else { /* isn't output buff smaller that our DMA buff? */ } else { /* isn't output buff smaller that our DMA buff? */
if (dmalen0 > (devpriv->ui_AiDataLength)) { if (dmalen0 > (devpriv->ui_AiDataLength))
dmalen0 = devpriv->ui_AiDataLength; dmalen0 = devpriv->ui_AiDataLength;
} if (dmalen1 > (devpriv->ui_AiDataLength))
if (dmalen1 > (devpriv->ui_AiDataLength)) {
dmalen1 = devpriv->ui_AiDataLength; dmalen1 = devpriv->ui_AiDataLength;
}
} }
devpriv->ui_DmaBufferUsesize[0] = dmalen0; devpriv->ui_DmaBufferUsesize[0] = dmalen0;
devpriv->ui_DmaBufferUsesize[1] = dmalen1; 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 */ /* store range list to card */
us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ 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 */ us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */
} else { else
us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */
}
gain = CR_RANGE(chanlist[i]); /* get gain number */ gain = CR_RANGE(chanlist[i]); /* get gain number */
us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ 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 */ /* Check If EOS interrupt */
if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { 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) { if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
ui_Check = 0; ui_Check = 0;
@ -1966,8 +1950,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
APCI3120_DISABLE_EOS_INT; APCI3120_DISABLE_EOS_INT;
outb(devpriv->b_ModeSelectRegister, outb(devpriv->b_ModeSelectRegister,
devpriv->iobase + APCI3120_WRITE_MODE_SELECT); 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 | /* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister |
* APCI3120_ENABLE_TIMER_INT; */ * APCI3120_ENABLE_TIMER_INT; */
@ -2006,8 +1989,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
/* timer2 in Timer mode enabled */ /* timer2 in Timer mode enabled */
devpriv->b_Timer2Mode = APCI3120_TIMER; devpriv->b_Timer2Mode = APCI3120_TIMER;
} else /* Initialize Watch dog */ } else { /* Initialize Watch dog */
{
/* Set the Timer 2 in mode 5(Watchdog) */ /* 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; return -EINVAL;
} }
if (data[0] == 2) /* write new value */ if (data[0] == 2) { /* write new value */
{
if (devpriv->b_Timer2Mode != APCI3120_TIMER) { if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
comedi_error(dev, comedi_error(dev,
"write :timer2 not configured in TIMER MODE"); "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 */ /* Reset FC_TIMER BIT */
inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); 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 */ /* Enable Timer */
devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister =
devpriv->b_ModeSelectRegister & 0x0B; devpriv->b_ModeSelectRegister & 0x0B;
} else /* start watch dog */ } else { /* start watch dog */
{
/* Enable WatchDog */ /* Enable WatchDog */
devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister =
(devpriv-> (devpriv->
@ -2146,8 +2125,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
outb(devpriv->b_ModeSelectRegister, outb(devpriv->b_ModeSelectRegister,
devpriv->iobase + APCI3120_WRITE_MODE_SELECT); 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 */ /* For Timer mode is Gate2 must be activated **timer started */
devpriv->us_OutputRegister = devpriv->us_OutputRegister =
devpriv-> devpriv->
@ -2299,8 +2277,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice
/* combining both words */ /* combining both words */
data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16)); 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 = inw(devpriv->iobase + APCI3120_RD_STATUS);
us_StatusValue = us_StatusValue =
@ -2441,10 +2418,9 @@ int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
devpriv->b_OutputMemoryStatus = APCI3120_DISABLE; devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
devpriv->b_DigitalOutputRegister = 0; devpriv->b_DigitalOutputRegister = 0;
} }
if (!devpriv->b_OutputMemoryStatus) { if (!devpriv->b_OutputMemoryStatus)
ui_Temp = 0; ui_Temp = 0;
/* if(!devpriv->b_OutputMemoryStatus ) */
} /* if(!devpriv->b_OutputMemoryStatus ) */
return insn->n; 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,| | Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | |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 | | Input Parameters : struct comedi_device *dev |
| struct comedi_subdevice *s | | struct comedi_subdevice *s |
| struct comedi_insn *insn | | struct comedi_insn *insn |
| unsigned int *data | | unsigned int *data |
data[0] Value to be written data[0] Value to be written
data[1] :1 Set digital o/p ON data[1] :1 Set digital o/p ON
data[1] 2 Set digital o/p OFF with memory 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); ui_Channel = CR_CHAN(insn->chanspec);
/* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */ /* 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) if (data[0] != 0)
data[0] = data[0] =
@ -2627,8 +2602,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
13) | 8192); 13) | 8192);
} else /* if 0 then bipolar */ } else { /* if 0 then bipolar */
{
data[0] = data[0] =
((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) | ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
data[0]); 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 * out put n values at the given channel. printk("\nwaiting for
* DA_READY BIT"); * DA_READY BIT");
*/ */
do /* Waiting of DA_READY BIT */ do { /* Waiting of DA_READY BIT */
{
us_TmpValue = us_TmpValue =
((unsigned short) inw(devpriv->iobase + ((unsigned short) inw(devpriv->iobase +
APCI3120_RD_STATUS)) & 0x0001; APCI3120_RD_STATUS)) & 0x0001;

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */

View File

@ -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 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 @endverbatim
*/ */
@ -1206,7 +1206,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
if (b_Channel < 8) { 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); dw_Status = inl(devpriv->iobase + 80);
@ -1228,7 +1228,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
== 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); dw_Status = inl(devpriv->iobase + 112);

View File

@ -88,9 +88,9 @@ Configuration options:
#define IORANGE_9118 64 /* I hope */ #define IORANGE_9118 64 /* I hope */
#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */ #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_CNT0 0x00 /* R/W: 8254 counter 0 */
#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */ #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */ #define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */ #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
#define PCI9118_AD_DATA 0x10 /* R: A/D data */ #define PCI9118_AD_DATA 0x10 /* R: A/D data */
#define PCI9118_DA1 0x10 /* W: D/A registers */ #define PCI9118_DA1 0x10 /* W: D/A registers */

View File

@ -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 option 1: I/O base address. The following table is provided as a help
of the hardware jumpers. of the hardware jumpers.
address jumper JADR address jumper JADR
0x300 1 (factory default) 0x300 1 (factory default)
0x320 2 0x320 2
0x340 3 0x340 3
0x360 4 0x360 4
0x380 5 0x380 5
0x3A0 6 0x3A0 6
option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
selection comedi_config option JUB selection comedi_config option JUB
bipolar 0 2-3 (factory default) bipolar 0 2-3 (factory default)
unipolar 1 1-2 unipolar 1 1-2
option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential 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) single-ended 0 1-2 1-2 (factory default)
differential 1 2-3 2-3 differential 1 2-3 2-3
@ -140,7 +140,7 @@ static const struct adq12b_board adq12b_boards[] = {
.ai_bits = 12, .ai_bits = 12,
.di_chans = 8, .di_chans = 8,
.do_chans = 5 .do_chans = 5
}*/ }*/
}; };
#define thisboard ((const struct adq12b_board *)dev->board_ptr) #define thisboard ((const struct adq12b_board *)dev->board_ptr)
@ -164,14 +164,15 @@ struct adq12b_private {
static int adq12b_attach(struct comedi_device *dev, static int adq12b_attach(struct comedi_device *dev,
struct comedi_devconfig *it); struct comedi_devconfig *it);
static int adq12b_detach(struct comedi_device *dev); static int adq12b_detach(struct comedi_device *dev);
static struct comedi_driver driver_adq12b = { static struct comedi_driver driver_adq12b = {
driver_name:"adq12b", .driver_name = "adq12b",
module:THIS_MODULE, .module = THIS_MODULE,
attach:adq12b_attach, .attach = adq12b_attach,
detach:adq12b_detach, .detach = adq12b_detach,
board_name:&adq12b_boards[0].name, .board_name = &adq12b_boards[0].name,
offset:sizeof(struct adq12b_board), .offset = sizeof(struct adq12b_board),
num_names:ARRAY_SIZE(adq12b_boards), .num_names = ARRAY_SIZE(adq12b_boards),
}; };
static int adq12b_ai_rinsn(struct comedi_device *dev, 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]; unipolar = it->options[1];
differential = it->options[2]; differential = it->options[2];
printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n", printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, "
dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar", "%s and %s\n", dev->minor, iobase,
(unipolar == 1) ? "unipolar" : "bipolar",
(differential == 1) ? "differential" : "single-ended"); (differential == 1) ? "differential" : "single-ended");
/* if no address was specified, try the default 0x300 */ /* if no address was specified, try the default 0x300 */
if (iobase == 0) { if (iobase == 0) {
printk printk(KERN_WARNING "comedi%d: adq12b warning: I/O base "
("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", "address not specified. Trying the default 0x300.\n",
dev->minor); dev->minor);
iobase = 0x300; 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; s->n_chan = thisboard->ai_se_chans;
} }
if (unipolar) { if (unipolar)
s->range_table = &range_adq12b_ai_unipolar; s->range_table = &range_adq12b_ai_unipolar;
} else { else
s->range_table = &range_adq12b_ai_bipolar; s->range_table = &range_adq12b_ai_bipolar;
}
s->maxdata = (1 << thisboard->ai_bits) - 1; 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->range_table = &range_digital;
s->insn_bits = adq12b_do_insn_bits; s->insn_bits = adq12b_do_insn_bits;
printk("attached\n"); printk(KERN_INFO "attached\n");
return 0; return 0;
} }
@ -309,7 +310,7 @@ static int adq12b_detach(struct comedi_device *dev)
kfree(devpriv); kfree(devpriv);
printk("comedi%d: adq12b: removed\n", dev->minor); printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor);
return 0; return 0;
} }
@ -344,17 +345,18 @@ static int adq12b_ai_rinsn(struct comedi_device *dev,
/* wait for end of convertion */ /* wait for end of convertion */
i = 0; i = 0;
do { do {
/* udelay(1); */ /* udelay(1); */
status = inb(dev->iobase + ADQ12B_STINR); status = inb(dev->iobase + ADQ12B_STINR);
status = status & ADQ12B_EOC; status = status & ADQ12B_EOC;
} while (status == 0 && ++i < TIMEOUT); } while (status == 0 && ++i < TIMEOUT);
/* } while (++i < 10); */ /* } while (++i < 10); */
/* read data */ /* read data */
hi = inb(dev->iobase + ADQ12B_ADHIG); hi = inb(dev->iobase + ADQ12B_ADHIG);
lo = inb(dev->iobase + ADQ12B_ADLOW); 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; data[n] = (hi << 8) | lo;
} }

View File

@ -84,9 +84,9 @@ Configuration options:
#define PCI171x_DAREF 14 /* W: D/A reference control */ #define PCI171x_DAREF 14 /* W: D/A reference control */
#define PCI171x_DI 16 /* R: digi inputs */ #define PCI171x_DI 16 /* R: digi inputs */
#define PCI171x_DO 16 /* R: digi inputs */ #define PCI171x_DO 16 /* R: digi inputs */
#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */ #define PCI171x_CNT0 24 /* R/W: 8254 counter 0 */
#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */ #define PCI171x_CNT1 26 /* R/W: 8254 counter 1 */
#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */ #define PCI171x_CNT2 28 /* R/W: 8254 counter 2 */
#define PCI171x_CNTCTRL 30 /* W: 8254 counter control */ #define PCI171x_CNTCTRL 30 /* W: 8254 counter control */
/* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */ /* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */
@ -724,6 +724,7 @@ static int move_block_from_fifo(struct comedi_device *dev,
devpriv->ai_act_scan++; devpriv->ai_act_scan++;
} }
} }
s->async->cur_chan = j;
DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n"); DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
return 0; 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) { if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len; cmd->scan_end_arg = cmd->chanlist_len;
err++; err++;
@ -1230,6 +1223,12 @@ static void setup_channel_list(struct comedi_device *dev,
DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
devpriv->act_chanlist[i]); 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 = devpriv->ai_et_MuxVal =
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);

View File

@ -98,7 +98,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
int iobase; int iobase;
struct comedi_subdevice *s; 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; 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) 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) if (dev->iobase)
release_region(dev->iobase, AIO_IIRO_16_SIZE); release_region(dev->iobase, AIO_IIRO_16_SIZE);

View File

@ -48,8 +48,8 @@ Passing a zero for an option is the same as leaving it unspecified.
SUBDEVICES SUBDEVICES
PC218E PC212E PC215E/PCI215 PC218E PC212E PC215E/PCI215
------------- ------------- ------------- ------------- ------------- -------------
Subdevices 7 6 5 Subdevices 7 6 5
0 CTR-X1 PPI-X PPI-X 0 CTR-X1 PPI-X PPI-X
1 CTR-X2 CTR-Y1 PPI-Y 1 CTR-X2 CTR-Y1 PPI-Y
@ -59,8 +59,8 @@ SUBDEVICES
5 CTR-Z2 INTERRUPT 5 CTR-Z2 INTERRUPT
6 INTERRUPT 6 INTERRUPT
PC214E PC272E/PCI272 PC214E PC272E/PCI272
------------- ------------- ------------- -------------
Subdevices 4 4 Subdevices 4 4
0 PPI-X PPI-X 0 PPI-X PPI-X
1 PPI-Y PPI-Y 1 PPI-Y PPI-Y
@ -96,8 +96,8 @@ instructions are supported:
0 to 7 as follows: 0 to 7 as follows:
0. CLK n, the counter channel's dedicated CLK input from the SK1 0. CLK n, the counter channel's dedicated CLK input from the SK1
connector. (N.B. for other values, the counter channel's CLKn connector. (N.B. for other values, the counter channel's CLKn
pin on the SK1 connector is an output!) pin on the SK1 connector is an output!)
1. Internal 10 MHz clock. 1. Internal 10 MHz clock.
2. Internal 1 MHz clock. 2. Internal 1 MHz clock.
3. Internal 100 kHz clock. 3. Internal 100 kHz clock.
@ -105,8 +105,8 @@ instructions are supported:
5. Internal 1 kHz clock. 5. Internal 1 kHz clock.
6. OUT n-1, the output of counter channel n-1 (see note 1 below). 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 7. Ext Clock, the counter chip's dedicated Ext Clock input from
the SK1 connector. This pin is shared by all three counter the SK1 connector. This pin is shared by all three counter
channels on the chip. channels on the chip.
INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
clock source in data[1]. For internal clock sources, data[2] is set 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. 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
1. GND (internal 0V d.c.), i.e. gate permanently disabled. 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
2. GAT n, the counter channel's dedicated GAT input from the SK1 2. GAT n, the counter channel's dedicated GAT input from the SK1
connector. (N.B. for other values, the counter channel's GATn connector. (N.B. for other values, the counter channel's GATn
pin on the SK1 connector is an output!) pin on the SK1 connector is an output!)
3. /OUT n-2, the inverted output of counter channel n-2 (see note 3. /OUT n-2, the inverted output of counter channel n-2 (see note
2 below). 2 below).
4. Reserved. 4. Reserved.
5. Reserved. 5. Reserved.
6. Reserved. 6. Reserved.
@ -153,8 +153,8 @@ below.
INTERRUPT SOURCES INTERRUPT SOURCES
PC218E PC212E PC215E/PCI215 PC218E PC212E PC215E/PCI215
------------- ------------- ------------- ------------- ------------- -------------
Sources 6 6 6 Sources 6 6 6
0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 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 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
PC214E PC272E/PCI272 PC214E PC272E/PCI272
------------- ------------- ------------- -------------
Sources 1 6 Sources 1 6
0 JUMPER-J5 PPI-X-C0 0 JUMPER-J5 PPI-X-C0
1 PPI-X-C3 1 PPI-X-C3
@ -435,11 +435,13 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table);
* Useful for shorthand access to the particular board structure * Useful for shorthand access to the particular board structure
*/ */
#define thisboard ((const struct dio200_board *)dev->board_ptr) #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 /* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure, 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 { struct dio200_private {
#ifdef CONFIG_COMEDI_PCI #ifdef CONFIG_COMEDI_PCI
struct pci_dev *pci_dev; /* PCI device */ struct pci_dev *pci_dev; /* PCI device */
@ -603,9 +605,8 @@ static void dio200_stop_intr(struct comedi_device *dev,
subpriv->active = 0; subpriv->active = 0;
subpriv->enabled_isns = 0; subpriv->enabled_isns = 0;
if (subpriv->has_int_sce) { if (subpriv->has_int_sce)
outb(0, subpriv->iobase); outb(0, subpriv->iobase);
}
} }
/* /*
@ -629,16 +630,14 @@ static int dio200_start_intr(struct comedi_device *dev,
/* Determine interrupt sources to enable. */ /* Determine interrupt sources to enable. */
isn_bits = 0; isn_bits = 0;
if (cmd->chanlist) { 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 |= (1U << CR_CHAN(cmd->chanlist[n]));
}
} }
isn_bits &= subpriv->valid_isns; isn_bits &= subpriv->valid_isns;
/* Enable interrupt sources. */ /* Enable interrupt sources. */
subpriv->enabled_isns = isn_bits; subpriv->enabled_isns = isn_bits;
if (subpriv->has_int_sce) { if (subpriv->has_int_sce)
outb(isn_bits, subpriv->iobase); outb(isn_bits, subpriv->iobase);
}
} }
return retval; return retval;
@ -662,14 +661,13 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
spin_lock_irqsave(&subpriv->spinlock, flags); spin_lock_irqsave(&subpriv->spinlock, flags);
s->async->inttrig = 0; s->async->inttrig = 0;
if (subpriv->active) { if (subpriv->active)
event = dio200_start_intr(dev, s); event = dio200_start_intr(dev, s);
}
spin_unlock_irqrestore(&subpriv->spinlock, flags); spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (event) { if (event)
comedi_event(dev, s); comedi_event(dev, s);
}
return 1; 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. * Reenable them NOW to minimize the time they are disabled.
*/ */
cur_enabled = subpriv->enabled_isns; cur_enabled = subpriv->enabled_isns;
if (subpriv->has_int_sce) { if (subpriv->has_int_sce)
outb(cur_enabled, subpriv->iobase); outb(cur_enabled, subpriv->iobase);
}
if (subpriv->active) { if (subpriv->active) {
/* /*
@ -747,9 +744,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
len = s->async->cmd.chanlist_len; len = s->async->cmd.chanlist_len;
for (n = 0; n < len; n++) { for (n = 0; n < len; n++) {
ch = CR_CHAN(s->async->cmd.chanlist[n]); ch = CR_CHAN(s->async->cmd.chanlist[n]);
if (triggered & (1U << ch)) { if (triggered & (1U << ch))
val |= (1U << n); val |= (1U << n);
}
} }
/* Write the scan to the buffer. */ /* Write the scan to the buffer. */
if (comedi_buf_put(s->async, val)) { 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); spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (oldevents != s->async->events) { if (oldevents != s->async->events)
comedi_event(dev, s); comedi_event(dev, s);
}
return (triggered != 0); return (triggered != 0);
} }
@ -798,9 +793,9 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&subpriv->spinlock, flags); spin_lock_irqsave(&subpriv->spinlock, flags);
if (subpriv->active) { if (subpriv->active)
dio200_stop_intr(dev, s); dio200_stop_intr(dev, s);
}
spin_unlock_irqrestore(&subpriv->spinlock, flags); spin_unlock_irqrestore(&subpriv->spinlock, flags);
return 0; return 0;
@ -846,7 +841,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev,
if (err) if (err)
return 1; 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 */ /* these tests are true if more than one _src bit is set */
if ((cmd->start_src & (cmd->start_src - 1)) != 0) 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); spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (event) { if (event)
comedi_event(dev, s); comedi_event(dev, s);
}
return 0; return 0;
} }
@ -980,9 +975,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
subpriv->valid_isns = valid_isns; subpriv->valid_isns = valid_isns;
spin_lock_init(&subpriv->spinlock); spin_lock_init(&subpriv->spinlock);
if (has_int_sce) { if (has_int_sce)
outb(0, subpriv->iobase); /* Disable interrupt sources. */ outb(0, subpriv->iobase); /* Disable interrupt sources. */
}
s->private = subpriv; s->private = subpriv;
s->type = COMEDI_SUBD_DI; s->type = COMEDI_SUBD_DI;
@ -1013,10 +1007,7 @@ dio200_subdev_intr_cleanup(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
struct dio200_subdev_intr *subpriv = s->private; struct dio200_subdev_intr *subpriv = s->private;
kfree(subpriv);
if (subpriv) {
kfree(subpriv);
}
} }
/* /*
@ -1027,9 +1018,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
struct comedi_device *dev = d; struct comedi_device *dev = d;
int handled; int handled;
if (!dev->attached) { if (!dev->attached)
return IRQ_NONE; return IRQ_NONE;
}
if (devpriv->intr_sd >= 0) { if (devpriv->intr_sd >= 0) {
handled = dio200_handle_read_intr(dev, handled = dio200_handle_read_intr(dev,
@ -1266,10 +1256,7 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev,
struct comedi_subdevice *s) struct comedi_subdevice *s)
{ {
struct dio200_subdev_intr *subpriv = s->private; struct dio200_subdev_intr *subpriv = s->private;
kfree(subpriv);
if (subpriv) {
kfree(subpriv);
}
} }
/* /*
@ -1348,9 +1335,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
#endif #endif
{ {
ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
if (ret < 0) { if (ret < 0)
return ret; return ret;
}
} }
dev->iobase = iobase; 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, ret = dio200_subdev_8254_init(dev, s, iobase,
layout->sdinfo[n], layout->sdinfo[n],
layout->has_clk_gat_sce); layout->has_clk_gat_sce);
if (ret < 0) { if (ret < 0)
return ret; return ret;
}
break; break;
case sd_8255: case sd_8255:
/* digital i/o subdevice (8255) */ /* digital i/o subdevice (8255) */
ret = subdev_8255_init(dev, s, 0, ret = subdev_8255_init(dev, s, 0,
iobase + layout->sdinfo[n]); iobase + layout->sdinfo[n]);
if (ret < 0) { if (ret < 0)
return ret; return ret;
}
break; break;
case sd_intr: case sd_intr:
/* 'INTERRUPT' subdevice */ /* 'INTERRUPT' subdevice */
@ -1392,9 +1378,9 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
layout->sdinfo[n], layout->sdinfo[n],
layout-> layout->
has_int_sce); has_int_sce);
if (ret < 0) { if (ret < 0)
return ret; return ret;
}
devpriv->intr_sd = n; devpriv->intr_sd = n;
} else { } else {
s->type = COMEDI_SUBD_UNUSED; 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; 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->read_subdev = &dev->subdevices[sdx];
}
dev->board_name = thisboard->name; 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)); printk("(pci %s) ", pci_name(pci_dev));
#endif #endif
} }
if (irq) { if (irq)
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
} else { else
printk("(no irq) "); printk("(no irq) ");
}
printk("attached\n"); 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, printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
DIO200_DRIVER_NAME); DIO200_DRIVER_NAME);
if (dev->irq) { if (dev->irq)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
}
if (dev->subdevices) { if (dev->subdevices) {
layout = thislayout; layout = thislayout;
for (n = 0; n < dev->n_subdevices; n++) { for (n = 0; n < dev->n_subdevices; n++) {
@ -1486,22 +1469,19 @@ static int dio200_detach(struct comedi_device *dev)
if (devpriv) { if (devpriv) {
#ifdef CONFIG_COMEDI_PCI #ifdef CONFIG_COMEDI_PCI
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (dev->iobase) { if (dev->iobase)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev);
} else } else
#endif #endif
{ {
if (dev->iobase) { if (dev->iobase)
release_region(dev->iobase, DIO200_IO_SIZE); release_region(dev->iobase, DIO200_IO_SIZE);
}
} }
} }
if (dev->board_name) { if (dev->board_name)
printk(KERN_INFO "comedi%d: %s removed\n", printk(KERN_INFO "comedi%d: %s removed\n",
dev->minor, dev->board_name); dev->minor, dev->board_name);
}
return 0; return 0;
} }

View File

@ -78,18 +78,18 @@ unused.
*/ */
/* Disable interrupt, also clear any interrupt there */ /* Disable interrupt, also clear any interrupt there */
#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \ #define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \
| PLX9052_INTCSR_LI1POL_HIGH \ | PLX9052_INTCSR_LI1POL_HIGH \
| PLX9052_INTCSR_LI2POL_HIGH \ | PLX9052_INTCSR_LI2POL_HIGH \
| PLX9052_INTCSR_PCIENAB_DISABLED \ | PLX9052_INTCSR_PCIENAB_DISABLED \
| PLX9052_INTCSR_LI1SEL_EDGE \ | PLX9052_INTCSR_LI1SEL_EDGE \
| PLX9052_INTCSR_LI1CLRINT_ASSERTED) | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
/* Enable interrupt, also clear any interrupt there. */ /* Enable interrupt, also clear any interrupt there. */
#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \ #define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \
| PLX9052_INTCSR_LI1POL_HIGH \ | PLX9052_INTCSR_LI1POL_HIGH \
| PLX9052_INTCSR_LI2POL_HIGH \ | PLX9052_INTCSR_LI2POL_HIGH \
| PLX9052_INTCSR_PCIENAB_ENABLED \ | PLX9052_INTCSR_PCIENAB_ENABLED \
| PLX9052_INTCSR_LI1SEL_EDGE \ | PLX9052_INTCSR_LI1SEL_EDGE \
| PLX9052_INTCSR_LI1CLRINT_ASSERTED) | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
/* /*
* Board descriptions for Amplicon PC36AT and PCI236. * 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 /* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure, 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 { struct pc236_private {
#ifdef CONFIG_COMEDI_PCI #ifdef CONFIG_COMEDI_PCI
/* PCI device */ /* PCI device */
struct pci_dev *pci_dev; 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 #endif
int enable_irq; int enable_irq;
}; };
@ -345,9 +346,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
#endif #endif
{ {
ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
if (ret < 0) { if (ret < 0)
return ret; return ret;
}
} }
dev->iobase = iobase; 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)); printk("(pci %s) ", pci_name(pci_dev));
#endif #endif
} }
if (irq) { if (irq)
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
} else { else
printk("(no irq) "); printk("(no irq) ");
}
printk("attached\n"); 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, printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
PC236_DRIVER_NAME); PC236_DRIVER_NAME);
if (devpriv) { if (devpriv)
pc236_intr_disable(dev); pc236_intr_disable(dev);
}
if (dev->irq) if (dev->irq)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
if (dev->subdevices) { if (dev->subdevices)
subdev_8255_cleanup(dev, dev->subdevices + 0); subdev_8255_cleanup(dev, dev->subdevices + 0);
}
if (devpriv) { if (devpriv) {
#ifdef CONFIG_COMEDI_PCI #ifdef CONFIG_COMEDI_PCI
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (dev->iobase) { if (dev->iobase)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev);
} else } else
#endif #endif
{ {
if (dev->iobase) { if (dev->iobase)
release_region(dev->iobase, PC236_IO_SIZE); release_region(dev->iobase, PC236_IO_SIZE);
}
} }
} }
if (dev->board_name) { if (dev->board_name) {

View File

@ -1536,20 +1536,12 @@ static int pci224_detach(struct comedi_device *dev)
s = dev->subdevices + 0; s = dev->subdevices + 0;
/* AO subdevice */ /* AO subdevice */
if (s->range_table_list) { kfree(s->range_table_list);
kfree(s->range_table_list);
}
} }
if (devpriv) { if (devpriv) {
if (devpriv->ao_readback) { kfree(devpriv->ao_readback);
kfree(devpriv->ao_readback); kfree(devpriv->ao_scan_vals);
} kfree(devpriv->ao_scan_order);
if (devpriv->ao_scan_vals) {
kfree(devpriv->ao_scan_vals);
}
if (devpriv->ao_scan_order) {
kfree(devpriv->ao_scan_order);
}
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (dev->iobase) { if (dev->iobase) {
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);

View File

@ -45,7 +45,7 @@ http://robot0.ge.uiuc.edu/~spong/mecha/
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <asm/io.h> #include <linux/io.h>
#include <linux/pnp.h> #include <linux/pnp.h>
#include "../comedidev.h" #include "../comedidev.h"
@ -220,11 +220,11 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel)
/* printk("Inside C6X_encInput\n"); */ /* printk("Inside C6X_encInput\n"); */
enc.value = 0; enc.value = 0;
if (channel == 0) { if (channel == 0)
ppcmd = 0x48; ppcmd = 0x48;
} else { else
ppcmd = 0x50; ppcmd = 0x50;
}
WriteByteToHwPort(baseAddr, ppcmd); WriteByteToHwPort(baseAddr, ppcmd);
tmp = ReadByteFromHwPort(baseAddr + 1); tmp = ReadByteFromHwPort(baseAddr + 1);
while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { 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 n;
int chan = CR_CHAN(insn->chanspec); 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); data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
}
return n; return n;
} }
@ -420,9 +419,9 @@ static void board_init(struct comedi_device *dev)
static const struct pnp_device_id c6xdigio_pnp_tbl[] = { static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
/* Standard LPT Printer Port */ /* Standard LPT Printer Port */
{.id = "PNP0400",.driver_data = 0}, {.id = "PNP0400", .driver_data = 0},
/* ECP Printer Port */ /* 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) if (result < 0)
return result; return result;
/* Make sure that PnP ports gets activated */ /* Make sure that PnP ports get activated */
pnp_register_driver(&c6xdigio_pnp_driver); pnp_register_driver(&c6xdigio_pnp_driver);
irq = it->options[1]; irq = it->options[1];
if (irq > 0) { if (irq > 0)
printk("comedi%d: irq = %u ignored\n", dev->minor, irq); 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); printk("comedi%d: no irq\n", dev->minor);
}
s = dev->subdevices + 0; s = dev->subdevices + 0;
/* pwm output subdevice */ /* pwm output subdevice */
@ -483,19 +481,19 @@ static int c6xdigio_attach(struct comedi_device *dev,
s->maxdata = 0xffffff; s->maxdata = 0xffffff;
s->range_table = &range_unknown; s->range_table = &range_unknown;
/* s = dev->subdevices + 2; */ /* s = dev->subdevices + 2; */
/* pwm output subdevice */ /* pwm output subdevice */
/* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
/* s->subdev_flags = SDF_WRITEABLE; */ /* s->subdev_flags = SDF_WRITEABLE; */
/* s->n_chan = 1; */ /* s->n_chan = 1; */
/* s->trig[0] = c6xdigio_ei_init; */ /* s->trig[0] = c6xdigio_ei_init; */
/* s->insn_read = c6xdigio_ei_init_insn_read; */ /* s->insn_read = c6xdigio_ei_init_insn_read; */
/* s->insn_write = c6xdigio_ei_init_insn_write; */ /* s->insn_write = c6xdigio_ei_init_insn_write; */
/* s->maxdata = 0xFFFF; // Really just a don't care */ /* s->maxdata = 0xFFFF; // Really just a don't care */
/* s->range_table = &range_unknown; // Not sure what to put here */ /* 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 */ /* I will call this init anyway but more than likely the DSP board */
/* when device driver is loaded. */ /* will not be connected when device driver is loaded. */
board_init(dev); board_init(dev);
return 0; return 0;
@ -503,16 +501,17 @@ static int c6xdigio_attach(struct comedi_device *dev,
static int c6xdigio_detach(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); printk("comedi%d: c6xdigio: remove\n", dev->minor);
if (dev->iobase) { if (dev->iobase)
release_region(dev->iobase, C6XDIGIO_SIZE); 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); free_irq(dev->irq, dev);
} /* Not using IRQ so I am not sure if I need this */
pnp_unregister_driver(&c6xdigio_pnp_driver); pnp_unregister_driver(&c6xdigio_pnp_driver);
return 0; return 0;

View File

@ -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, static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
uint8_t value); uint8_t value);
static int nvram_read(struct comedi_device *dev, unsigned int address, 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) 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) if (dev->subdevices)
subdev_8255_cleanup(dev, dev->subdevices + 2); subdev_8255_cleanup(dev, dev->subdevices + 2);
if (devpriv && devpriv->pci_dev) { if (devpriv && devpriv->pci_dev) {
if (devpriv->s5933_config) { if (devpriv->s5933_config)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(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); cmd->flags & TRIG_ROUND_MASK);
/* set number of conversions */ /* set number of conversions */
if (cmd->stop_src == TRIG_COUNT) { if (cmd->stop_src == TRIG_COUNT)
devpriv->count = cmd->chanlist_len * cmd->stop_arg; devpriv->count = cmd->chanlist_len * cmd->stop_arg;
}
/* enable interrupts */ /* enable interrupts */
spin_lock_irqsave(&dev->spinlock, flags); spin_lock_irqsave(&dev->spinlock, flags);
devpriv->adc_fifo_bits |= INTE; devpriv->adc_fifo_bits |= INTE;
@ -1449,9 +1447,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
devpriv->ao_divisor2, 2); devpriv->ao_divisor2, 2);
} }
/* set number of conversions */ /* 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; devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
}
/* set pacer source */ /* set pacer source */
spin_lock_irqsave(&dev->spinlock, flags); spin_lock_irqsave(&dev->spinlock, flags);
switch (cmd->scan_begin_src) { 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 * sizeof(short));
num_points = num_bytes / 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; devpriv->ao_count -= num_points;
}
/* write data to board's fifo */ /* write data to board's fifo */
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 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; static const int timeout = 10000;
unsigned long flags; unsigned long flags;
if (dev->attached == 0) { if (dev->attached == 0)
return IRQ_NONE; return IRQ_NONE;
}
async = s->async; async = s->async;
async->events = 0; async->events = 0;
@ -1558,15 +1553,13 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
status = inw(devpriv->control_status + INT_ADCFIFO); status = inw(devpriv->control_status + INT_ADCFIFO);
#ifdef CB_PCIDAS_DEBUG #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"); comedi_error(dev, "spurious interrupt");
}
#endif #endif
/* check for analog output interrupt */ /* check for analog output interrupt */
if (status & (DAHFI | DAEMI)) { if (status & (DAHFI | DAEMI))
handle_ao_interrupt(dev, status); handle_ao_interrupt(dev, status);
}
/* check for analog input interrupts */ /* check for analog input interrupts */
/* if fifo half-full */ /* if fifo half-full */
if (status & ADHFI) { 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 * sizeof(short));
num_points = num_bytes / 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; devpriv->ao_count -= num_points;
}
/* write data to board's fifo */ /* write data to board's fifo */
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
num_points); 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, static int nvram_read(struct comedi_device *dev, unsigned int address,
uint8_t * data) uint8_t *data)
{ {
unsigned long iobase = devpriv->s5933_config; unsigned long iobase = devpriv->s5933_config;

View File

@ -410,9 +410,8 @@ static int cb_pcidda_detach(struct comedi_device *dev)
*/ */
if (devpriv) { if (devpriv) {
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (devpriv->dac) { if (devpriv->dac)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(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++) { for (i = 1; i <= value_width; i++) {
/* read bits most significant bit first */ /* 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); value |= 1 << (value_width - i);
}
} }
return value; return value;
@ -716,9 +714,8 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
/* send serial output stream to eeprom */ /* send serial output stream to eeprom */
cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT; cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
/* deactivate caldacs (one caldac for every two channels) */ /* 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); cal2_bits |= DESELECT_CALDAC_BIT(i);
}
outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
/* tell eeprom we want to read */ /* 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; cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
/* deactivate caldacs (one caldac for every two channels) */ /* 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); cal2_bits |= DESELECT_CALDAC_BIT(i);
}
/* activate the caldac we want */ /* activate the caldac we want */
cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);

View File

@ -283,17 +283,15 @@ static int pcidio_detach(struct comedi_device *dev)
printk("comedi%d: cb_pcidio: remove\n", dev->minor); printk("comedi%d: cb_pcidio: remove\n", dev->minor);
if (devpriv) { if (devpriv) {
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (devpriv->dio_reg_base) { if (devpriv->dio_reg_base)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev);
} }
} }
if (dev->subdevices) { if (dev->subdevices) {
int i; 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); subdev_8255_cleanup(dev, dev->subdevices + i);
}
} }
return 0; return 0;
} }

View File

@ -330,11 +330,10 @@ found:
s = dev->subdevices + 2; s = dev->subdevices + 2;
/* digital i/o subdevice */ /* digital i/o subdevice */
if (thisboard->has_dio) { if (thisboard->has_dio)
subdev_8255_init(dev, s, NULL, devpriv->BADR4); subdev_8255_init(dev, s, NULL, devpriv->BADR4);
} else { else
s->type = COMEDI_SUBD_UNUSED; s->type = COMEDI_SUBD_UNUSED;
}
printk("attached\n"); printk("attached\n");
@ -365,9 +364,8 @@ static int cb_pcimdas_detach(struct comedi_device *dev)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
if (devpriv) { if (devpriv) {
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (devpriv->BADR0) { if (devpriv->BADR0)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev);
} }
} }

View File

@ -284,11 +284,10 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->n_chan = thisboard->ao_chans; s->n_chan = thisboard->ao_chans;
s->maxdata = figure_out_maxdata(thisboard->ao_bits); s->maxdata = figure_out_maxdata(thisboard->ao_bits);
/* this is hard-coded here */ /* this is hard-coded here */
if (it->options[2]) { if (it->options[2])
s->range_table = &range_bipolar10; s->range_table = &range_bipolar10;
} else { else
s->range_table = &range_bipolar5; s->range_table = &range_bipolar5;
}
s->insn_write = &ao_winsn; s->insn_write = &ao_winsn;
s->insn_read = &ao_rinsn; s->insn_read = &ao_rinsn;
@ -337,9 +336,8 @@ static int detach(struct comedi_device *dev)
} }
if (devpriv->pci_dev) { if (devpriv->pci_dev) {
if (devpriv->registers) { if (devpriv->registers)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev);
} }

View File

@ -417,7 +417,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
int sdev = -1, nchans, tmp; int sdev = -1, nchans, tmp;
struct BondedDevice *bdev = NULL; 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); ERROR("Minor %d is invalid!\n", minor);
return 0; return 0;
} }

View File

@ -173,9 +173,8 @@ static int contec_detach(struct comedi_device *dev)
printk("comedi%d: contec: remove\n", dev->minor); printk("comedi%d: contec: remove\n", dev->minor);
if (devpriv && devpriv->pci_dev) { if (devpriv && devpriv->pci_dev) {
if (dev->iobase) { if (dev->iobase)
comedi_pci_disable(devpriv->pci_dev); comedi_pci_disable(devpriv->pci_dev);
}
pci_dev_put(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev);
} }

View File

@ -34,7 +34,7 @@ This is the PCMCIA-specific support split off from the
das08 driver. das08 driver.
Options (for pcm-das08): Options (for pcm-das08):
NONE NONE
Command support does not exist, but could be added for this board. 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/cistpl.h>
#include <pcmcia/ds.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) #define thisboard ((const struct das08_board_struct *)dev->board_ptr)

View File

@ -45,7 +45,7 @@ This driver has suffered bitrot.
#define DAS6402_SIZE 16 #define DAS6402_SIZE 16
#define N_WORDS 3000*64 #define N_WORDS (3000*64)
#define STOP 0 #define STOP 0
#define START 1 #define START 1

View File

@ -399,9 +399,8 @@ static irqreturn_t das800_interrupt(int irq, void *d)
} else { } else {
fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */ fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */
} }
if (fifo_empty) { if (fifo_empty)
break; break;
}
/* strip off extraneous bits for 12 bit cards */ /* strip off extraneous bits for 12 bit cards */
if (thisboard->resolution == 12) if (thisboard->resolution == 12)
dataPoint = (dataPoint >> 4) & 0xfff; dataPoint = (dataPoint >> 4) & 0xfff;
@ -457,9 +456,8 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int board; int board;
printk("comedi%d: das800: io 0x%lx", dev->minor, iobase); printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
if (irq) { if (irq)
printk(", irq %u", irq); printk(", irq %u", irq);
}
printk("\n"); printk("\n");
/* allocate and initialize dev->private */ /* allocate and initialize dev->private */

View File

@ -1048,11 +1048,10 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev,
* value COMEDI_INPUT or COMEDI_OUTPUT. */ * value COMEDI_INPUT or COMEDI_OUTPUT. */
/* if output clear the bit, otherwise set it */ /* if output clear the bit, otherwise set it */
if (data[0] == COMEDI_OUTPUT) { if (data[0] == COMEDI_OUTPUT)
devpriv->dio_config &= ~chanbit; devpriv->dio_config &= ~chanbit;
} else { else
devpriv->dio_config |= chanbit; devpriv->dio_config |= chanbit;
}
/* get access to the DIO regs */ /* get access to the DIO regs */
dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
/* set the DIO's to the new configuration setting */ /* set the DIO's to the new configuration setting */

View File

@ -18,10 +18,10 @@ Configuration options:
[1] - unused [1] - unused
[2] - A/D reference 0=differential, 1=single-ended [2] - A/D reference 0=differential, 1=single-ended
[3] - A/D range [3] - A/D range
0 = [-10,10] 0 = [-10, 10]
1 = [0,10] 1 = [0,10]
[4] - D/A 0 range [4] - D/A 0 range
0 = [-10,10] 0 = [-10, 10]
1 = [-5,5] 1 = [-5,5]
2 = [-2.5,2.5] 2 = [-2.5,2.5]
3 = [0,10] 3 = [0,10]
@ -279,9 +279,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data)
do { do {
stat = inb_p(dev->iobase + DT2801_STATUS); 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; return stat;
}
if (stat & DT_S_DATA_OUT_READY) { if (stat & DT_S_DATA_OUT_READY) {
*data = inb_p(dev->iobase + DT2801_DATA); *data = inb_p(dev->iobase + DT2801_DATA);
return 0; return 0;
@ -315,9 +314,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
do { do {
stat = inb_p(dev->iobase + DT2801_STATUS); stat = inb_p(dev->iobase + DT2801_STATUS);
if (stat & DT_S_COMPOSITE_ERROR) { if (stat & DT_S_COMPOSITE_ERROR)
return stat; return stat;
}
if (!(stat & DT_S_DATA_IN_FULL)) { if (!(stat & DT_S_DATA_IN_FULL)) {
outb_p(data & 0xff, dev->iobase + DT2801_DATA); outb_p(data & 0xff, dev->iobase + DT2801_DATA);
return 0; return 0;
@ -354,18 +352,15 @@ static int dt2801_wait_for_ready(struct comedi_device *dev)
int stat; int stat;
stat = inb_p(dev->iobase + DT2801_STATUS); stat = inb_p(dev->iobase + DT2801_STATUS);
if (stat & DT_S_READY) { if (stat & DT_S_READY)
return 0; return 0;
}
do { do {
stat = inb_p(dev->iobase + DT2801_STATUS); stat = inb_p(dev->iobase + DT2801_STATUS);
if (stat & DT_S_COMPOSITE_ERROR) { if (stat & DT_S_COMPOSITE_ERROR)
return stat; return stat;
} if (stat & DT_S_READY)
if (stat & DT_S_READY) {
return 0; return 0;
}
} while (--timeout > 0); } while (--timeout > 0);
return -ETIME; return -ETIME;
@ -382,9 +377,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command)
printk printk
("dt2801: composite-error in dt2801_writecmd(), ignoring\n"); ("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"); printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
}
outb_p(command, dev->iobase + DT2801_CMD); outb_p(command, dev->iobase + DT2801_CMD);
return 0; return 0;
@ -418,9 +412,8 @@ static int dt2801_reset(struct comedi_device *dev)
if (stat & DT_S_READY) if (stat & DT_S_READY)
break; break;
} while (timeout--); } while (timeout--);
if (!timeout) { if (!timeout)
printk("dt2801: timeout 1 status=0x%02x\n", stat); printk("dt2801: timeout 1 status=0x%02x\n", stat);
}
/* printk("dt2801: reading dummy\n"); */ /* printk("dt2801: reading dummy\n"); */
/* dt2801_readdata(dev,&board_code); */ /* dt2801_readdata(dev,&board_code); */
@ -436,9 +429,8 @@ static int dt2801_reset(struct comedi_device *dev)
if (stat & DT_S_READY) if (stat & DT_S_READY)
break; break;
} while (timeout--); } while (timeout--);
if (!timeout) { if (!timeout)
printk("dt2801: timeout 2 status=0x%02x\n", stat); printk("dt2801: timeout 2 status=0x%02x\n", stat);
}
DPRINTK("dt2801: reading code\n"); DPRINTK("dt2801: reading code\n");
dt2801_readdata(dev, &board_code); 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) static int dt2801_error(struct comedi_device *dev, int stat)
{ {
if (stat < 0) { if (stat < 0) {
if (stat == -ETIME) { if (stat == -ETIME)
printk("dt2801: timeout\n"); printk("dt2801: timeout\n");
} else { else
printk("dt2801: error %d\n", stat); printk("dt2801: error %d\n", stat);
}
return stat; return stat;
} }
printk("dt2801: error status 0x%02x, resetting...\n", stat); printk("dt2801: error status 0x%02x, resetting...\n", stat);

View File

@ -34,19 +34,19 @@ Configuration options:
[0] - I/O port base base address [0] - I/O port base base address
[1] - IRQ (unused) [1] - IRQ (unused)
[2] - Voltage unipolar/bipolar configuration [2] - Voltage unipolar/bipolar configuration
0 == unipolar 5V (0V -- +5V) 0 == unipolar 5V (0V -- +5V)
1 == bipolar 5V (-5V -- +5V) 1 == bipolar 5V (-5V -- +5V)
[3] - Current offset configuration [3] - Current offset configuration
0 == disabled (0mA -- +32mAV) 0 == disabled (0mA -- +32mAV)
1 == enabled (+4mA -- +20mAV) 1 == enabled (+4mA -- +20mAV)
[4] - Firmware program configuration [4] - Firmware program configuration
0 == program 1 (see manual table 5-4) 0 == program 1 (see manual table 5-4)
1 == program 2 (see manual table 5-4) 1 == program 2 (see manual table 5-4)
2 == program 3 (see manual table 5-4) 2 == program 3 (see manual table 5-4)
3 == program 4 (see manual table 5-4) 3 == program 4 (see manual table 5-4)
[5] - Analog output 0 range configuration [5] - Analog output 0 range configuration
0 == voltage 0 == voltage
1 == current 1 == current
[6] - Analog output 1 range configuration (same options) [6] - Analog output 1 range configuration (same options)
[7] - Analog output 2 range configuration (same options) [7] - Analog output 2 range configuration (same options)
[8] - Analog output 3 range configuration (same options) [8] - Analog output 3 range configuration (same options)
@ -61,17 +61,11 @@ Configuration options:
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/delay.h> #include <linux/delay.h>
static const struct comedi_lrange range_dt2815_ao_32_current = { 1, { static const struct comedi_lrange
RANGE_mA(0, range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} };
32)
}
};
static const struct comedi_lrange range_dt2815_ao_20_current = { 1, { static const struct comedi_lrange
RANGE_mA(4, range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} };
20)
}
};
#define DT2815_SIZE 2 #define DT2815_SIZE 2
@ -118,9 +112,8 @@ static int dt2815_ao_insn_read(struct comedi_device *dev,
int i; int i;
int chan = CR_CHAN(insn->chanspec); 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]; data[i] = devpriv->ao_readback[chan];
}
return i; 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); status = dt2815_wait_for_status(dev, 0x00);
if (status != 0) { if (status != 0) {
printk printk(KERN_WARNING "dt2815: failed to write low byte "
("dt2815: failed to write low byte on %d reason %x\n", "on %d reason %x\n", chan, status);
chan, status);
return -EBUSY; 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); status = dt2815_wait_for_status(dev, 0x10);
if (status != 0x10) { if (status != 0x10) {
printk printk(KERN_WARNING "dt2815: failed to write high byte "
("dt2815: failed to write high byte on %d reason %x\n", "on %d reason %x\n", chan, status);
chan, status);
return -EBUSY; return -EBUSY;
} }
devpriv->ao_readback[chan] = data[i]; 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[0] Board base address
options[1] IRQ (not applicable) options[1] IRQ (not applicable)
options[2] Voltage unipolar/bipolar configuration options[2] Voltage unipolar/bipolar configuration
0 == unipolar 5V (0V -- +5V) 0 == unipolar 5V (0V -- +5V)
1 == bipolar 5V (-5V -- +5V) 1 == bipolar 5V (-5V -- +5V)
options[3] Current offset configuration options[3] Current offset configuration
0 == disabled (0mA -- +32mAV) 0 == disabled (0mA -- +32mAV)
1 == enabled (+4mA -- +20mAV) 1 == enabled (+4mA -- +20mAV)
options[4] Firmware program configuration options[4] Firmware program configuration
0 == program 1 (see manual table 5-4) 0 == program 1 (see manual table 5-4)
1 == program 2 (see manual table 5-4) 1 == program 2 (see manual table 5-4)
2 == program 3 (see manual table 5-4) 2 == program 3 (see manual table 5-4)
3 == program 4 (see manual table 5-4) 3 == program 4 (see manual table 5-4)
options[5] Analog output 0 range configuration options[5] Analog output 0 range configuration
0 == voltage 0 == voltage
1 == current 1 == current
options[6] Analog output 1 range configuration options[6] Analog output 1 range configuration
... ...
options[12] Analog output 7 range configuration options[12] Analog output 7 range configuration
0 == voltage 0 == voltage
1 == current 1 == current
*/ */
static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) 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; unsigned long iobase;
iobase = it->options[0]; 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")) { if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
printk("I/O port conflict\n"); printk(KERN_WARNING "I/O port conflict\n");
return -EIO; return -EIO;
} }
@ -236,19 +227,17 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned int program; unsigned int program;
program = (it->options[4] & 0x3) << 3 | 0x7; program = (it->options[4] & 0x3) << 3 | 0x7;
outb(program, dev->iobase + DT2815_DATA); 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; break;
} else if (status != 0x00) { } else if (status != 0x00) {
printk("dt2815: unexpected status 0x%x (@t=%d)\n", printk(KERN_WARNING "dt2815: unexpected status 0x%x "
status, i); "(@t=%d)\n", status, i);
if (status & 0x60) { if (status & 0x60)
outb(0x00, dev->iobase + DT2815_STATUS); outb(0x00, dev->iobase + DT2815_STATUS);
}
} }
} }
printk("\n");
return 0; return 0;
} }
@ -260,7 +249,7 @@ static void dt2815_free_resources(struct comedi_device *dev)
static int dt2815_detach(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); dt2815_free_resources(dev);

View File

@ -264,7 +264,7 @@ struct dt9812_usb_cmd {
static DECLARE_MUTEX(dt9812_mutex); static DECLARE_MUTEX(dt9812_mutex);
static struct usb_device_id dt9812_table[] = { static const struct usb_device_id dt9812_table[] = {
{USB_DEVICE(0x0867, 0x9812)}, {USB_DEVICE(0x0867, 0x9812)},
{} /* Terminating entry */ {} /* Terminating entry */
}; };

View File

@ -76,14 +76,14 @@ static int fl512_ai_insn(struct comedi_device *dev,
unsigned long iobase = dev->iobase; unsigned long iobase = dev->iobase;
for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */ 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 /* XXX probably can move next step out of for() loop -- will
* AI a little bit faster. */ * make AI a little bit faster. */
outb(chan, iobase + 2); /* select chan */ outb(chan, iobase + 2); /* select chan */
outb(0, iobase + 3); /* start conversion */ outb(0, iobase + 3); /* start conversion */
/* XXX should test "done" flag instead of delay */ /* XXX should test "done" flag instead of delay */
udelay(30); /* sleep 30 usec */ udelay(30); /* sleep 30 usec */
lo_byte = inb(iobase + 2); /* low 8 byte */ 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); data[n] = lo_byte + (hi_byte << 8);
} }
return n; return n;
@ -101,8 +101,10 @@ static int fl512_ao_insn(struct comedi_device *dev,
unsigned long iobase = dev->iobase; /* get base address */ unsigned long iobase = dev->iobase; /* get base address */
for (n = 0; n < insn->n; n++) { /* write n data set */ for (n = 0; n < insn->n; n++) { /* write n data set */
outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */ /* write low byte */
outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high 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 */ inb(iobase + 4 + 2 * chan); /* trig */
devpriv->ao_readback[chan] = data[n]; devpriv->ao_readback[chan] = data[n];
@ -121,9 +123,8 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
int n; int n;
int chan = CR_CHAN(insn->chanspec); 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]; data[n] = devpriv->ao_readback[chan];
}
return n; 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) static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ {
unsigned long iobase; 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]; 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")) { if (!request_region(iobase, FL512_SIZE, "fl512")) {
printk(" I/O port conflict\n"); printk(KERN_WARNING " I/O port conflict\n");
return -EIO; return -EIO;
} }
dev->iobase = iobase; dev->iobase = iobase;
@ -149,7 +152,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -ENOMEM; return -ENOMEM;
#if DEBUG #if DEBUG
printk("malloc ok\n"); printk(KERN_DEBUG "malloc ok\n");
#endif #endif
if (alloc_subdevices(dev, 2) < 0) if (alloc_subdevices(dev, 2) < 0)
@ -160,24 +163,37 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
*/ */
/* Analog indput */ /* Analog indput */
s = dev->subdevices + 0; s = dev->subdevices + 0;
s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */ /* define subdevice as Analog In */
s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */ s->type = COMEDI_SUBD_AI;
s->n_chan = 16; /* Number of Analog input channels */ /* you can read it from userspace */
s->maxdata = 0x0fff; /* accept only 12 bits of data */ s->subdev_flags = SDF_READABLE | SDF_GROUND;
s->range_table = &range_fl512; /* device use one of the ranges */ /* Number of Analog input channels */
s->insn_read = fl512_ai_insn; /* function to call when read AD */ s->n_chan = 16;
printk("comedi: fl512: subdevice 0 initialized\n"); /* 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 */ /* Analog output */
s = dev->subdevices + 1; s = dev->subdevices + 1;
s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */ /* define subdevice as Analog OUT */
s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */ s->type = COMEDI_SUBD_AO;
s->n_chan = 2; /* Number of Analog output channels */ /* you can write it from userspace */
s->maxdata = 0x0fff; /* accept only 12 bits of data */ s->subdev_flags = SDF_WRITABLE;
s->range_table = &range_fl512; /* device use one of the ranges */ /* Number of Analog output channels */
s->insn_write = fl512_ao_insn; /* function to call when write DA */ s->n_chan = 2;
s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */ /* accept only 12 bits of data */
printk("comedi: fl512: subdevice 1 initialized\n"); 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; return 1;
} }
@ -186,6 +202,6 @@ static int fl512_detach(struct comedi_device *dev)
{ {
if (dev->iobase) if (dev->iobase)
release_region(dev->iobase, FL512_SIZE); 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; return 0;
} }

View File

@ -954,6 +954,8 @@ out:
return result; return result;
} }
MODULE_FIRMWARE("comedi/jr3pci.idm");
static int jr3_pci_detach(struct comedi_device *dev) static int jr3_pci_detach(struct comedi_device *dev)
{ {
int i; int i;

View File

@ -284,7 +284,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH); outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
/* printk("Channel %d: \n", insn->chanspec); */ /* printk("Channel %d: \n", insn->chanspec); */
if (!insn->n) { if (!insn->n) {
printk("MPC624: Warning, no data to aquire\n"); printk("MPC624: Warning, no data to acquire\n");
return 0; return 0;
} }

View File

@ -26,12 +26,13 @@
/* /*
Driver: ni_65xx Driver: ni_65xx
Description: National Instruments 65xx static dio boards 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 Status: testing
Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511, Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515, PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521, PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
PCI-6528, PXI-6528 PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
Updated: Wed Oct 18 08:59:11 EDT 2006 Updated: Wed Oct 18 08:59:11 EDT 2006
Based on the PCI-6527 driver by ds. 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; return -EINVAL;
base_bitfield_channel = CR_CHAN(insn->chanspec); base_bitfield_channel = CR_CHAN(insn->chanspec);
for (j = 0; j < max_ports_per_bitfield; ++j) { 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 = const unsigned port =
sprivate(s)->base_port + port_offset; sprivate(s)->base_port + port_offset;
unsigned base_port_channel; unsigned base_port_channel;
unsigned port_mask, port_data, port_read_bits; unsigned port_mask, port_data, port_read_bits;
int bitshift; int bitshift;
@ -463,11 +465,11 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
* subdevice.) */ * subdevice.) */
port_read_bits ^= 0xFF; port_read_bits ^= 0xFF;
} }
if (bitshift > 0) { if (bitshift > 0)
port_read_bits <<= bitshift; port_read_bits <<= bitshift;
} else { else
port_read_bits >>= -bitshift; port_read_bits >>= -bitshift;
}
read_bits |= port_read_bits; read_bits |= port_read_bits;
} }
data[1] = read_bits; data[1] = read_bits;
@ -532,7 +534,8 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
if (err) if (err)
return 1; 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) if (err)
return 2; return 2;
@ -652,7 +655,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
unsigned i; unsigned i;
int ret; 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)); ret = alloc_private(dev, sizeof(struct ni_65xx_private));
if (ret < 0) if (ret < 0)
@ -664,15 +667,15 @@ static int ni_65xx_attach(struct comedi_device *dev,
ret = mite_setup(private(dev)->mite); ret = mite_setup(private(dev)->mite);
if (ret < 0) { if (ret < 0) {
printk("error setting up mite\n"); printk(KERN_WARNING "error setting up mite\n");
return ret; return ret;
} }
dev->board_name = board(dev)->name; dev->board_name = board(dev)->name;
dev->irq = mite_irq(private(dev)->mite); 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)); readb(private(dev)->mite->daq_io_addr + ID_Register));
ret = alloc_subdevices(dev, 4); ret = alloc_subdevices(dev, 4);
@ -773,7 +776,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
"ni_65xx", dev); "ni_65xx", dev);
if (ret < 0) { if (ret < 0) {
dev->irq = 0; dev->irq = 0;
printk(" irq not available"); printk(KERN_WARNING " irq not available");
} }
printk("\n"); printk("\n");
@ -790,21 +793,17 @@ static int ni_65xx_detach(struct comedi_device *dev)
Master_Interrupt_Control); Master_Interrupt_Control);
} }
if (dev->irq) { if (dev->irq)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
}
if (private(dev)) { if (private(dev)) {
unsigned i; unsigned i;
for (i = 0; i < dev->n_subdevices; ++i) { for (i = 0; i < dev->n_subdevices; ++i) {
if (dev->subdevices[i].private) { kfree(dev->subdevices[i].private);
kfree(dev->subdevices[i].private); dev->subdevices[i].private = NULL;
dev->subdevices[i].private = NULL;
}
} }
if (private(dev)->mite) { if (private(dev)->mite)
mite_unsetup(private(dev)->mite); mite_unsetup(private(dev)->mite);
}
} }
return 0; 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(); mite_list_devices();
return -EIO; return -EIO;
} }

View File

@ -52,7 +52,8 @@ enum ni_660x_constants {
}; };
#define NUM_PFI_CHANNELS 40 #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 #define MAX_DMA_CHANNEL 4
/* See Register-Level Programmer Manual page 3.1 */ /* See Register-Level Programmer Manual page 3.1 */
@ -198,7 +199,7 @@ struct NI_660xRegisterData {
const char *name; /* Register Name */ const char *name; /* Register Name */
int offset; /* Offset from base address from GPCT chip */ int offset; /* Offset from base address from GPCT chip */
enum ni_660x_register_direction direction; 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] = { 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 */ /* 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 + /* First chip is at base-address + 0x00, etc. */
0x00, etc. */ static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
/* Board description*/ /* Board description*/
struct ni_660x_board { 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; ni_660x_register = G0StatusRegister;
break; break;
case NITIO_G1_Status_Reg: case NITIO_G1_Status_Reg:
ni_660x_register = G0StatusRegister; ni_660x_register = G1StatusRegister;
break; break;
case NITIO_G2_Status_Reg: case NITIO_G2_Status_Reg:
ni_660x_register = G0StatusRegister; ni_660x_register = G2StatusRegister;
break; break;
case NITIO_G3_Status_Reg: case NITIO_G3_Status_Reg:
ni_660x_register = G0StatusRegister; ni_660x_register = G3StatusRegister;
break; break;
case NITIO_G0_Interrupt_Enable_Reg: case NITIO_G0_Interrupt_Enable_Reg:
ni_660x_register = G0InterruptEnable; 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; ni_660x_register = G3InterruptEnable;
break; break;
default: default:
printk("%s: unhandled register 0x%x in switch.\n", printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n",
__func__, reg); __func__, reg);
BUG(); BUG();
return 0; return 0;
@ -737,7 +738,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
writel(bits, write_address); writel(bits, write_address);
break; break;
default: 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); __FILE__, __func__, reg);
BUG(); BUG();
break; break;
@ -760,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
return readl(read_address); return readl(read_address);
break; break;
default: 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); __FILE__, __func__, reg);
BUG(); BUG();
break; 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)->mite_channel_lock);
spin_lock_init(&private(dev)->interrupt_lock); spin_lock_init(&private(dev)->interrupt_lock);
spin_lock_init(&private(dev)->soft_reg_copy_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; private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
}
return 0; 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) { for (j = 0; j < counters_per_chip; ++j) {
private(dev)->mite_rings[i][j] = private(dev)->mite_rings[i][j] =
mite_alloc_ring(private(dev)->mite); 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 -ENOMEM;
}
} }
} }
return 0; return 0;
@ -1022,9 +1022,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev)
unsigned j; unsigned j;
for (i = 0; i < board(dev)->n_chips; ++i) { 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]); 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 i;
unsigned global_interrupt_config_bits; 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); ret = ni_660x_allocate_private(dev);
if (ret < 0) if (ret < 0)
@ -1049,7 +1048,7 @@ static int ni_660x_attach(struct comedi_device *dev,
ret = mite_setup2(private(dev)->mite, 1); ret = mite_setup2(private(dev)->mite, 1);
if (ret < 0) { if (ret < 0) {
printk("error setting up mite\n"); printk(KERN_WARNING "error setting up mite\n");
return ret; return ret;
} }
comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); 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) if (ret < 0)
return ret; return ret;
printk(" %s ", dev->board_name); printk(KERN_INFO " %s ", dev->board_name);
dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS; 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_bits = ni_660x_dio_insn_bits;
s->insn_config = ni_660x_dio_insn_config; s->insn_config = ni_660x_dio_insn_config;
s->io_bits = 0; /* all bits default to input */ 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); ni_660x_write_register(dev, 0, 0, STCDIOControl);
private(dev)->counter_dev = ni_gpct_device_construct(dev, private(dev)->counter_dev = ni_gpct_device_construct(dev,
&ni_gpct_write_register, &ni_gpct_write_register,
&ni_gpct_read_register, &ni_gpct_read_register,
ni_gpct_variant_660x, ni_gpct_variant_660x,
ni_660x_num_counters ni_660x_num_counters
(dev)); (dev));
if (private(dev)->counter_dev == NULL) if (private(dev)->counter_dev == NULL)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { 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; 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); 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]); ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
}
for (i = 0; i < NUM_PFI_CHANNELS; ++i) { for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
if (i < min_counter_pfi_chan) if (i < min_counter_pfi_chan)
ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); 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 /* to be safe, set counterswap bits on tio chips after all the counter
outputs have been set to high impedance mode */ 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); set_tio_counterswap(dev, i);
}
ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt, ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
IRQF_SHARED, "ni_660x", dev); IRQF_SHARED, "ni_660x", dev);
if (ret < 0) { if (ret < 0) {
printk(" irq not available\n"); printk(KERN_WARNING " irq not available\n");
return ret; return ret;
} }
dev->irq = mite_irq(private(dev)->mite); 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; global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
ni_660x_write_register(dev, 0, global_interrupt_config_bits, ni_660x_write_register(dev, 0, global_interrupt_config_bits,
GlobalInterruptConfigRegister); GlobalInterruptConfigRegister);
printk("attached\n"); printk(KERN_INFO "attached\n");
return 0; return 0;
} }
static int ni_660x_detach(struct comedi_device *dev) 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 */ /* Free irq */
if (dev->irq) if (dev->irq)
@ -1193,9 +1193,8 @@ static void init_tio_chip(struct comedi_device *dev, int chipset)
private(dev)-> private(dev)->
dma_configuration_soft_copies[chipset], dma_configuration_soft_copies[chipset],
DMAConfigRegister); 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)); ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
}
} }
static int 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(); mite_list_devices();
return -EIO; return -EIO;
} }

Some files were not shown because too many files have changed in this diff Show More