Commit 994b6e06 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Merge Ingo's work_struct and my tasklet changes

parents ab1180be f31b5ddd
...@@ -81,7 +81,7 @@ ifneq ($(filter all,$(MAKECMDGOALS)),) ...@@ -81,7 +81,7 @@ ifneq ($(filter all,$(MAKECMDGOALS)),)
KBUILD_MODULES := 1 KBUILD_MODULES := 1
endif endif
export KBUILD_MODULES KBUILD_BUILTIN export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE
# Beautify output # Beautify output
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
......
...@@ -11,9 +11,11 @@ obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o ...@@ -11,9 +11,11 @@ obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
# Multipart objects. # Multipart objects.
isdn-objs := isdn_net.o isdn_tty.o \ isdn-objs := isdn_net.o isdn_net_lib.o \
isdn_v110.o isdn_common.o \ isdn_fsm.o \
isdn_ciscohdlck.o isdn_ciscohdlck.o \
isdn_tty.o isdn_v110.o \
isdn_common.o \
# Optional parts of multipart objects. # Optional parts of multipart objects.
......
This diff is collapsed.
...@@ -46,8 +46,7 @@ struct isdn_slot { ...@@ -46,8 +46,7 @@ struct isdn_slot {
unsigned long obytes; /* Statistics outgoing bytes */ unsigned long obytes; /* Statistics outgoing bytes */
struct isdn_v110 iv110; /* For V.110 */ struct isdn_v110 iv110; /* For V.110 */
int m_idx; /* Index for mdm.... */ int m_idx; /* Index for mdm.... */
isdn_net_dev *rx_netdev; /* rx netdev-pointers */ isdn_net_dev *idev; /* pointer to isdn_net_dev */
isdn_net_dev *st_netdev; /* stat netdev-pointers */
}; };
static struct isdn_slot slot[ISDN_MAX_CHANNELS]; static struct isdn_slot slot[ISDN_MAX_CHANNELS];
...@@ -508,7 +507,7 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -508,7 +507,7 @@ isdn_status_callback(isdn_ctrl * c)
list_for_each(l, &isdn_net_devs) { list_for_each(l, &isdn_net_devs) {
isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list); isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
if (p->isdn_slot == i) { if (p->isdn_slot == i) {
strcpy(cmd.parm.setup.eazmsn, p->local.msn); strcpy(cmd.parm.setup.eazmsn, p->mlp->msn);
isdn_slot_command(i, ISDN_CMD_ACCEPTD, &cmd); isdn_slot_command(i, ISDN_CMD_ACCEPTD, &cmd);
retval = 1; retval = 1;
break; break;
...@@ -1010,19 +1009,6 @@ static int ...@@ -1010,19 +1009,6 @@ static int
isdn_status_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) isdn_status_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
{ {
int ret; int ret;
union iocpar {
char name[10];
char bname[22];
isdn_ioctl_struct iocts;
isdn_net_ioctl_phone phone;
isdn_net_ioctl_cfg cfg;
} iocpar;
#define name iocpar.name
#define bname iocpar.bname
#define iocts iocpar.iocts
#define phone iocpar.phone
#define cfg iocpar.cfg
switch (cmd) { switch (cmd) {
case IIOCGETDVR: case IIOCGETDVR:
...@@ -1044,26 +1030,11 @@ isdn_status_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1044,26 +1030,11 @@ isdn_status_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
} else } else
return -EINVAL; return -EINVAL;
break; break;
#ifdef CONFIG_NETDEVICES
case IIOCNETGPN: case IIOCNETGPN:
/* Get peer phone number of a connected return isdn_net_ioctl(inode, file, cmd, arg);
* isdn network interface */
if (arg) {
if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
return -EFAULT;
return isdn_net_getpeer(&phone, (isdn_net_ioctl_phone *) arg);
} else
return -EINVAL;
#endif
default: default:
return -EINVAL; return -EINVAL;
} }
#undef name
#undef bname
#undef iocts
#undef phone
#undef cfg
} }
static struct file_operations isdn_status_fops = static struct file_operations isdn_status_fops =
...@@ -1221,19 +1192,15 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1221,19 +1192,15 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
int ret; int ret;
int i; int i;
char *p; char *p;
union iocpar { /* save stack space */
char name[10]; union {
char bname[20]; char bname[20];
isdn_ioctl_struct iocts; isdn_ioctl_struct iocts;
isdn_net_ioctl_phone phone;
isdn_net_ioctl_cfg cfg;
} iocpar; } iocpar;
#define name iocpar.name
#define bname iocpar.bname
#define iocts iocpar.iocts #define iocts iocpar.iocts
#define phone iocpar.phone #define bname iocpar.bname
#define cfg iocpar.cfg
/* /*
* isdn net devices manage lots of configuration variables as linked lists. * isdn net devices manage lots of configuration variables as linked lists.
* Those lists must only be manipulated from user space. Some of the ioctl's * Those lists must only be manipulated from user space. Some of the ioctl's
...@@ -1242,134 +1209,19 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1242,134 +1209,19 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
* are serialized by means of a semaphore. * are serialized by means of a semaphore.
*/ */
switch (cmd) { switch (cmd) {
case IIOCNETDWRSET:
printk(KERN_INFO "INFO: ISDN_DW_ABC_EXTENSION not enabled\n");
return(-EINVAL);
case IIOCNETLCR:
printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
return -ENODEV;
#ifdef CONFIG_NETDEVICES
case IIOCNETAIF: case IIOCNETAIF:
/* Add a network-interface */
if (copy_from_user(name, (char *) arg, sizeof(name) - 1))
return -EFAULT;
name[sizeof(name)-1] = 0;
ret = down_interruptible(&dev->sem);
if (ret)
return ret;
ret = isdn_net_new(name, NULL);
up(&dev->sem);
return ret;
case IIOCNETASL: case IIOCNETASL:
/* Add a slave to a network-interface */
if (copy_from_user(bname, (char *) arg, sizeof(bname) - 1))
return -EFAULT;
bname[sizeof(bname)-1] = 0;
ret = down_interruptible(&dev->sem);
if (ret)
return ret;
ret = isdn_net_newslave(bname);
up(&dev->sem);
return ret;
case IIOCNETDIF: case IIOCNETDIF:
/* Delete a network-interface */
if (arg) {
if (copy_from_user(name, (char *) arg, sizeof(name)))
return -EFAULT;
ret = down_interruptible(&dev->sem);
if( ret ) return ret;
ret = isdn_net_rm(name);
up(&dev->sem);
return ret;
} else
return -EINVAL;
case IIOCNETSCF: case IIOCNETSCF:
/* Set configurable parameters of a network-interface */
if (arg) {
if (copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg)))
return -EFAULT;
return isdn_net_setcfg(&cfg);
} else
return -EINVAL;
case IIOCNETGCF: case IIOCNETGCF:
/* Get configurable parameters of a network-interface */
if (arg) {
if (copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg)))
return -EFAULT;
if (!(ret = isdn_net_getcfg(&cfg))) {
if (copy_to_user((char *) arg, (char *) &cfg, sizeof(cfg)))
return -EFAULT;
}
return ret;
} else
return -EINVAL;
case IIOCNETANM: case IIOCNETANM:
/* Add a phone-number to a network-interface */
if (arg) {
if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
return -EFAULT;
ret = down_interruptible(&dev->sem);
if( ret ) return ret;
ret = isdn_net_addphone(&phone);
up(&dev->sem);
return ret;
} else
return -EINVAL;
case IIOCNETGNM: case IIOCNETGNM:
/* Get list of phone-numbers of a network-interface */
if (arg) {
if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
return -EFAULT;
ret = down_interruptible(&dev->sem);
if( ret ) return ret;
ret = isdn_net_getphones(&phone, (char *) arg);
up(&dev->sem);
return ret;
} else
return -EINVAL;
case IIOCNETDNM: case IIOCNETDNM:
/* Delete a phone-number of a network-interface */
if (arg) {
if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
return -EFAULT;
ret = down_interruptible(&dev->sem);
if( ret ) return ret;
ret = isdn_net_delphone(&phone);
up(&dev->sem);
return ret;
} else
return -EINVAL;
case IIOCNETDIL: case IIOCNETDIL:
/* Force dialing of a network-interface */
if (arg) {
if (copy_from_user(name, (char *) arg, sizeof(name)))
return -EFAULT;
return isdn_net_force_dial(name);
} else
return -EINVAL;
#ifdef CONFIG_ISDN_PPP
case IIOCNETALN: case IIOCNETALN:
if (!arg)
return -EINVAL;
if (copy_from_user(name, (char *) arg, sizeof(name)))
return -EFAULT;
return isdn_ppp_dial_slave(name);
case IIOCNETDLN: case IIOCNETDLN:
if (!arg)
return -EINVAL;
if (copy_from_user(name, (char *) arg, sizeof(name)))
return -EFAULT;
return isdn_ppp_hangup_slave(name);
#endif
case IIOCNETHUP: case IIOCNETHUP:
/* Force hangup of a network-interface */ return isdn_net_ioctl(inode, file, cmd, arg);
if (!arg)
return -EINVAL;
if (copy_from_user(name, (char *) arg, sizeof(name)))
return -EFAULT;
return isdn_net_force_hangup(name);
break;
#endif /* CONFIG_NETDEVICES */
case IIOCSETVER: case IIOCSETVER:
dev->net_verbose = arg; dev->net_verbose = arg;
printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
...@@ -1577,12 +1429,8 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1577,12 +1429,8 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
} else } else
return -EINVAL; return -EINVAL;
} }
#undef name
#undef bname
#undef iocts #undef iocts
#undef phone #undef bname
#undef cfg
} }
static struct file_operations isdn_ctrl_fops = static struct file_operations isdn_ctrl_fops =
...@@ -2218,35 +2066,19 @@ isdn_slot_num(int sl) ...@@ -2218,35 +2066,19 @@ isdn_slot_num(int sl)
} }
void void
isdn_slot_set_rx_netdev(int sl, isdn_net_dev *nd) isdn_slot_set_idev(int sl, isdn_net_dev *idev)
{
BUG_ON(sl < 0);
slot[sl].rx_netdev = nd;
}
isdn_net_dev *
isdn_slot_rx_netdev(int sl)
{
BUG_ON(sl < 0);
return slot[sl].rx_netdev;
}
void
isdn_slot_set_st_netdev(int sl, isdn_net_dev *nd)
{ {
BUG_ON(sl < 0); BUG_ON(sl < 0);
slot[sl].st_netdev = nd; slot[sl].idev = idev;
} }
isdn_net_dev * isdn_net_dev *
isdn_slot_st_netdev(int sl) isdn_slot_idev(int sl)
{ {
BUG_ON(sl < 0); BUG_ON(sl < 0);
return slot[sl].st_netdev; return slot[sl].idev;
} }
int int
...@@ -2430,7 +2262,7 @@ static int __init isdn_init(void) ...@@ -2430,7 +2262,7 @@ static int __init isdn_init(void)
printk("\n"); printk("\n");
#endif #endif
isdn_info_update(); isdn_info_update();
isdn_net_init_module(); isdn_net_init();
return 0; return 0;
err_tty_modem: err_tty_modem:
...@@ -2456,8 +2288,7 @@ static void __exit isdn_exit(void) ...@@ -2456,8 +2288,7 @@ static void __exit isdn_exit(void)
#endif #endif
save_flags(flags); save_flags(flags);
cli(); cli();
if (isdn_net_rmall() < 0) isdn_net_exit();
BUG();
isdn_tty_exit(); isdn_tty_exit();
if (unregister_chrdev(ISDN_MAJOR, "isdn")) if (unregister_chrdev(ISDN_MAJOR, "isdn"))
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
#undef ISDN_DEBUG_MODEM_DUMP #undef ISDN_DEBUG_MODEM_DUMP
#undef ISDN_DEBUG_MODEM_VOICE #undef ISDN_DEBUG_MODEM_VOICE
#undef ISDN_DEBUG_AT #undef ISDN_DEBUG_AT
#undef ISDN_DEBUG_NET_DUMP #define ISDN_DEBUG_NET_DUMP
#undef ISDN_DEBUG_NET_DIAL #define ISDN_DEBUG_NET_DIAL
#undef ISDN_DEBUG_NET_ICALL #define ISDN_DEBUG_NET_ICALL
#undef ISDN_DEBUG_STATCALLB #define ISDN_DEBUG_STATCALLB
#undef ISDN_DEBUG_COMMAND #define ISDN_DEBUG_COMMAND
#ifdef ISDN_DEBUG_NET_DIAL #ifdef ISDN_DEBUG_NET_DIAL
#define dbg_net_dial(arg...) printk(KERN_DEBUG arg) #define dbg_net_dial(arg...) printk(KERN_DEBUG arg)
...@@ -52,6 +52,8 @@ do { printk(KERN_WARNING "ISDN Bug at %s:%d\n", __FILE__, __LINE__); \ ...@@ -52,6 +52,8 @@ do { printk(KERN_WARNING "ISDN Bug at %s:%d\n", __FILE__, __LINE__); \
#define HERE printk("%s:%d (%s)\n", __FILE__, __LINE__, __FUNCTION__) #define HERE printk("%s:%d (%s)\n", __FILE__, __LINE__, __FUNCTION__)
extern struct list_head isdn_net_devs;
/* Prototypes */ /* Prototypes */
extern void isdn_MOD_INC_USE_COUNT(void); extern void isdn_MOD_INC_USE_COUNT(void);
extern void isdn_MOD_DEC_USE_COUNT(void); extern void isdn_MOD_DEC_USE_COUNT(void);
...@@ -82,8 +84,6 @@ struct dial_info { ...@@ -82,8 +84,6 @@ struct dial_info {
unsigned char *phone; unsigned char *phone;
}; };
extern struct list_head isdn_net_devs;
extern int isdn_get_free_slot(int, int, int, int, int, char *); extern int isdn_get_free_slot(int, int, int, int, int, char *);
extern void isdn_slot_free(int slot, int usage); extern void isdn_slot_free(int slot, int usage);
extern void isdn_slot_all_eaz(int slot); extern void isdn_slot_all_eaz(int slot);
...@@ -100,8 +100,6 @@ extern void isdn_slot_set_usage(int slot, int usage); ...@@ -100,8 +100,6 @@ extern void isdn_slot_set_usage(int slot, int usage);
extern char *isdn_slot_num(int slot); extern char *isdn_slot_num(int slot);
extern int isdn_slot_m_idx(int slot); extern int isdn_slot_m_idx(int slot);
extern void isdn_slot_set_m_idx(int slot, int midx); extern void isdn_slot_set_m_idx(int slot, int midx);
extern void isdn_slot_set_rx_netdev(int sl, isdn_net_dev *nd); extern void isdn_slot_set_idev(int sl, isdn_net_dev *);
extern void isdn_slot_set_st_netdev(int sl, isdn_net_dev *nd); extern isdn_net_dev *isdn_slot_idev(int sl);
extern isdn_net_dev *isdn_slot_rx_netdev(int sl);
extern isdn_net_dev *isdn_slot_st_netdev(int sl);
extern int isdn_hard_header_len(void); extern int isdn_hard_header_len(void);
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
*/ */
int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb) static int
isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
{ {
struct net_device *ndev = concap -> net_dev; struct net_device *ndev = concap -> net_dev;
isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev; isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev;
...@@ -58,7 +59,8 @@ int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb) ...@@ -58,7 +59,8 @@ int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
} }
int isdn_concap_dl_connect_req(struct concap_proto *concap) static int
isdn_concap_dl_connect_req(struct concap_proto *concap)
{ {
struct net_device *ndev = concap -> net_dev; struct net_device *ndev = concap -> net_dev;
isdn_net_local *lp = (isdn_net_local *) ndev->priv; isdn_net_local *lp = (isdn_net_local *) ndev->priv;
...@@ -71,7 +73,8 @@ int isdn_concap_dl_connect_req(struct concap_proto *concap) ...@@ -71,7 +73,8 @@ int isdn_concap_dl_connect_req(struct concap_proto *concap)
return ret; return ret;
} }
int isdn_concap_dl_disconn_req(struct concap_proto *concap) static int
isdn_concap_dl_disconn_req(struct concap_proto *concap)
{ {
IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name); IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name);
...@@ -98,7 +101,8 @@ struct concap_device_ops isdn_concap_demand_dial_dops = { ...@@ -98,7 +101,8 @@ struct concap_device_ops isdn_concap_demand_dial_dops = {
this sourcefile does not need to include any protocol specific header this sourcefile does not need to include any protocol specific header
files. For now: files. For now:
*/ */
struct concap_proto * isdn_concap_new( int encap ) struct concap_proto *
isdn_concap_new( int encap )
{ {
switch ( encap ) { switch ( encap ) {
case ISDN_NET_ENCAP_X25IFACE: case ISDN_NET_ENCAP_X25IFACE:
...@@ -158,7 +162,7 @@ isdn_x25_disconnected(isdn_net_local *lp) ...@@ -158,7 +162,7 @@ isdn_x25_disconnected(isdn_net_local *lp)
pops -> disconn_ind(cprot); pops -> disconn_ind(cprot);
} }
int static int
isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev) isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
/* At this point hard_start_xmit() passes control to the encapsulation /* At this point hard_start_xmit() passes control to the encapsulation
...@@ -237,13 +241,8 @@ isdn_x25_cleanup(isdn_net_dev *p) ...@@ -237,13 +241,8 @@ isdn_x25_cleanup(isdn_net_dev *p)
restore_flags(flags); restore_flags(flags);
} }
void isdn_x25_realrm(isdn_net_dev *p)
{
if( p -> cprot && p -> cprot -> pops )
p -> cprot -> pops -> proto_del ( p -> cprot );
}
struct isdn_netif_ops isdn_x25_ops = { struct isdn_netif_ops isdn_x25_ops = {
.hard_start_xmit = isdn_x25_start_xmit,
.flags = IFF_NOARP | IFF_POINTOPOINT, .flags = IFF_NOARP | IFF_POINTOPOINT,
.type = ARPHRD_X25, .type = ARPHRD_X25,
.receive = isdn_x25_receive, .receive = isdn_x25_receive,
......
...@@ -12,18 +12,4 @@ extern struct concap_device_ops isdn_concap_demand_dial_dops; ...@@ -12,18 +12,4 @@ extern struct concap_device_ops isdn_concap_demand_dial_dops;
struct concap_proto *isdn_concap_new(int); struct concap_proto *isdn_concap_new(int);
#ifdef CONFIG_ISDN_X25
extern struct isdn_netif_ops isdn_x25_ops; extern struct isdn_netif_ops isdn_x25_ops;
int isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev);
#else
static inline int
isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
return 0;
}
#endif
/* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $
*
* Finite state machine
*
* Author Karsten Keil
* Copyright by Karsten Keil <keil@isdn4linux.de>
* by Kai Germaschewski <kai.germaschewski@gmx.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
* Thanks to Jan den Ouden
* Fritz Elfert
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include "isdn_fsm.h"
int
fsm_new(struct fsm *fsm)
{
int i;
int size = sizeof(fsm_fn) * fsm->st_cnt * fsm->ev_cnt;
fsm->jumpmatrix = kmalloc(size, GFP_KERNEL);
if (!fsm->jumpmatrix)
return -ENOMEM;
memset(fsm->jumpmatrix, 0, size);
for (i = 0; i < fsm->fn_cnt; i++) {
if (fsm->fn_tbl[i].st >= fsm->st_cnt ||
fsm->fn_tbl[i].ev >= fsm->ev_cnt) {
printk(KERN_ERR "FsmNew Error line %d st(%d/%d) ev(%d/%d)\n", i,
fsm->fn_tbl[i].st, fsm->st_cnt,
fsm->fn_tbl[i].ev, fsm->ev_cnt);
continue;
}
fsm->jumpmatrix[fsm->st_cnt * fsm->fn_tbl[i].ev + fsm->fn_tbl[i].st] = fsm->fn_tbl[i].routine;
}
return 0;
}
void
fsm_free(struct fsm *fsm)
{
kfree(fsm->jumpmatrix);
}
int
fsm_event(struct fsm_inst *fi, int event, void *arg)
{
fsm_fn fn;
if (fi->state >= fi->fsm->st_cnt ||
event >= fi->fsm->ev_cnt) {
printk(KERN_ERR "FsmEvent Error st(%d/%d) ev(%d/%d)\n",
fi->state, fi->fsm->st_cnt,event,
fi->fsm->ev_cnt);
return -EINVAL;
}
fn = fi->fsm->jumpmatrix[fi->fsm->st_cnt * event + fi->state];
if (!fn) {
if (fi->debug)
fi->printdebug(fi, "State %s Event %s no routine",
fi->fsm->st_str[fi->state],
fi->fsm->ev_str[event]);
return -ESRCH;
}
if (fi->debug)
fi->printdebug(fi, "State %s Event %s",
fi->fsm->st_str[fi->state],
fi->fsm->ev_str[event]);
fn(fi, event, arg);
return 0;
}
void
fsm_change_state(struct fsm_inst *fi, int newstate)
{
fi->state = newstate;
if (fi->debug)
fi->printdebug(fi, "ChangeState %s",
fi->fsm->st_str[newstate]);
}
#if 0
static void
FsmExpireTimer(struct FsmTimer *ft)
{
#if FSM_TIMER_DEBUG
if (ft->fi->debug)
ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft);
#endif
FsmEvent(ft->fi, ft->event, ft->arg);
}
void
FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft)
{
ft->fi = fi;
ft->tl.function = (void *) FsmExpireTimer;
ft->tl.data = (long) ft;
#if FSM_TIMER_DEBUG
if (ft->fi->debug)
ft->fi->printdebug(ft->fi, "FsmInitTimer %lx", (long) ft);
#endif
init_timer(&ft->tl);
}
void
FsmDelTimer(struct FsmTimer *ft, int where)
{
#if FSM_TIMER_DEBUG
if (ft->fi->debug)
ft->fi->printdebug(ft->fi, "FsmDelTimer %lx %d", (long) ft, where);
#endif
del_timer(&ft->tl);
}
int
FsmAddTimer(struct FsmTimer *ft,
int millisec, int event, void *arg, int where)
{
#if FSM_TIMER_DEBUG
if (ft->fi->debug)
ft->fi->printdebug(ft->fi, "FsmAddTimer %lx %d %d",
(long) ft, millisec, where);
#endif
if (timer_pending(&ft->tl)) {
printk(KERN_WARNING "FsmAddTimer: timer already active!\n");
ft->fi->printdebug(ft->fi, "FsmAddTimer already active!");
return -1;
}
init_timer(&ft->tl);
ft->event = event;
ft->arg = arg;
ft->tl.expires = jiffies + (millisec * HZ) / 1000;
add_timer(&ft->tl);
return 0;
}
void
FsmRestartTimer(struct FsmTimer *ft,
int millisec, int event, void *arg, int where)
{
#if FSM_TIMER_DEBUG
if (ft->fi->debug)
ft->fi->printdebug(ft->fi, "FsmRestartTimer %lx %d %d",
(long) ft, millisec, where);
#endif
if (timer_pending(&ft->tl))
del_timer(&ft->tl);
init_timer(&ft->tl);
ft->event = event;
ft->arg = arg;
ft->tl.expires = jiffies + (millisec * HZ) / 1000;
add_timer(&ft->tl);
}
#endif
/* $Id: fsm.h,v 1.3.2.2 2001/09/23 22:24:47 kai Exp $
*
* Finite state machine
*
* Author Karsten Keil
* Copyright by Karsten Keil <keil@isdn4linux.de>
* by Kai Germaschewski <kai.germaschewski@gmx.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#ifndef __FSM_H__
#define __FSM_H__
#include <linux/timer.h>
struct fsm_inst;
typedef void (*fsm_fn)(struct fsm_inst *, int, void *);
struct fsm {
fsm_fn *jumpmatrix;
int st_cnt, ev_cnt, fn_cnt;
char **st_str, **ev_str;
struct fsm_node *fn_tbl;
};
struct fsm_inst {
struct fsm *fsm;
int state;
int debug;
void *userdata;
int userint;
void (*printdebug) (struct fsm_inst *, char *, ...);
};
struct fsm_node {
int st, ev;
void (*routine) (struct fsm_inst *, int, void *);
};
struct fsm_timer {
struct fsm_inst *fi;
struct timer_list tl;
int ev;
void *arg;
};
int fsm_new(struct fsm *fsm);
void fsm_free(struct fsm *fsm);
int fsm_event(struct fsm_inst *fi, int event, void *arg);
void fsm_change_state(struct fsm_inst *fi, int newstate);
void fsm_init_timer(struct fsm_inst *fi, struct fsm_timer *ft);
int fsm_add_timer(struct fsm_timer *ft, int timeout, int event);
void fsm_mod_timer(struct fsm_timer *ft, int timeout, int event);
void fsm_del_timer(struct fsm_timer *ft);
#endif
This diff is collapsed.
...@@ -32,46 +32,49 @@ ...@@ -32,46 +32,49 @@
#define CISCO_SLARP_REPLY 1 #define CISCO_SLARP_REPLY 1
#define CISCO_SLARP_KEEPALIVE 2 #define CISCO_SLARP_KEEPALIVE 2
extern void isdn_net_init_module(void); extern void isdn_net_init(void);
extern void isdn_net_exit(void);
extern void isdn_net_lib_init(void);
extern void isdn_net_lib_exit(void);
extern void isdn_net_hangup_all(void);
extern int isdn_net_ioctl(struct inode *, struct file *, uint, ulong);
extern int register_isdn_netif(int encap, struct isdn_netif_ops *ops);
extern int isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev);
extern int isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev);
extern int isdn_net_bind_channel(isdn_net_dev *idev, int slot);
extern void isdn_net_unbind_channel(isdn_net_dev *idev);
extern int isdn_net_dial(isdn_net_dev *idev);
extern void isdn_net_accept(isdn_net_dev *idev, int slot, char *nr);
extern int isdn_net_do_callback(isdn_net_dev *idev);
extern int isdn_net_bsent(isdn_net_dev *idev, isdn_ctrl *c);
extern int isdn_net_new(char *, struct net_device *);
extern int isdn_net_newslave(char *);
extern int isdn_net_rm(char *);
extern int isdn_net_rmall(void);
extern int isdn_net_stat_callback(int, isdn_ctrl *); extern int isdn_net_stat_callback(int, isdn_ctrl *);
extern int isdn_net_setcfg(isdn_net_ioctl_cfg *);
extern int isdn_net_getcfg(isdn_net_ioctl_cfg *);
extern int isdn_net_addphone(isdn_net_ioctl_phone *);
extern int isdn_net_getphones(isdn_net_ioctl_phone *, char *);
extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *);
extern int isdn_net_delphone(isdn_net_ioctl_phone *);
extern int isdn_net_find_icall(int, int, int, setup_parm *); extern int isdn_net_find_icall(int, int, int, setup_parm *);
extern void isdn_net_hangup(isdn_net_dev *); extern int isdn_net_hangup(isdn_net_dev *);
extern void isdn_net_hangup_all(void);
extern int isdn_net_force_hangup(char *);
extern int isdn_net_force_dial(char *);
extern isdn_net_dev *isdn_net_findif(char *);
extern int isdn_net_rcv_skb(int, struct sk_buff *); extern int isdn_net_rcv_skb(int, struct sk_buff *);
extern int isdn_net_dial_req(isdn_net_local *); extern int isdn_net_dial_req(isdn_net_dev *);
extern void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb); extern void isdn_net_writebuf_skb(isdn_net_dev *, struct sk_buff *skb);
extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb); extern void isdn_net_write_super(isdn_net_dev *, struct sk_buff *skb);
extern int isdn_net_online(isdn_net_dev *idev); extern int isdn_net_online(isdn_net_dev *);
static inline void enum {
isdn_net_reset_huptimer(isdn_net_dev *idev, isdn_net_dev *idev2) ST_CHARGE_NULL,
{ ST_CHARGE_GOT_CINF, /* got a first charge info */
idev->huptimer = 0; ST_CHARGE_HAVE_CINT, /* got a second chare info and thus the timing */
idev2->huptimer = 0; };
}
#define ISDN_NET_MAX_QUEUE_LENGTH 2 #define ISDN_NET_MAX_QUEUE_LENGTH 2
/* /*
* is this particular channel busy? * is this particular channel busy?
*/ */
static __inline__ int isdn_net_lp_busy(isdn_net_local *lp) static inline int
isdn_net_dev_busy(isdn_net_dev *idev)
{ {
if (atomic_read(&lp->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH) if (atomic_read(&idev->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH)
return 0; return 0;
else else
return 1; return 1;
...@@ -81,86 +84,69 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp) ...@@ -81,86 +84,69 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp)
* For the given net device, this will get a non-busy channel out of the * For the given net device, this will get a non-busy channel out of the
* corresponding bundle. The returned channel is locked. * corresponding bundle. The returned channel is locked.
*/ */
static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd) static inline isdn_net_dev *
isdn_net_get_locked_dev(isdn_net_local *mlp)
{ {
unsigned long flags; unsigned long flags;
isdn_net_local *lp; isdn_net_dev *idev;
spin_lock_irqsave(&nd->queue_lock, flags); spin_lock_irqsave(&mlp->online_lock, flags);
lp = nd->queue; /* get lp on top of queue */
spin_lock_bh(&nd->queue->xmit_lock); list_for_each_entry(idev, &mlp->online, online) {
while (isdn_net_lp_busy(nd->queue)) { spin_lock_bh(&idev->xmit_lock);
spin_unlock_bh(&nd->queue->xmit_lock); if (!isdn_net_dev_busy(idev)) {
nd->queue = nd->queue->next; /* point the head to next online channel */
if (nd->queue == lp) { /* not found -- should never happen */ list_del(&mlp->online);
lp = NULL; list_add(&mlp->online, &idev->online);
goto errout; goto found;
} }
spin_lock_bh(&nd->queue->xmit_lock); spin_unlock_bh(&idev->xmit_lock);
} }
lp = nd->queue; idev = NULL;
nd->queue = nd->queue->next;
errout: found:
spin_unlock_irqrestore(&nd->queue_lock, flags); spin_unlock_irqrestore(&mlp->online_lock, flags);
return lp; return idev;
} }
/* /*
* add a channel to a bundle * add a channel to a bundle
*/ */
static __inline__ void isdn_net_add_to_bundle(isdn_net_dev *nd, isdn_net_local *nlp) static inline void
isdn_net_add_to_bundle(isdn_net_local *mlp, isdn_net_dev *idev)
{ {
isdn_net_local *lp;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&nd->queue_lock, flags); spin_lock_irqsave(&mlp->online_lock, flags);
list_add(&idev->online, &mlp->online);
lp = nd->queue; spin_unlock_irqrestore(&mlp->online_lock, flags);
nlp->last = lp->last;
lp->last->next = nlp;
lp->last = nlp;
nlp->next = lp;
nd->queue = nlp;
spin_unlock_irqrestore(&nd->queue_lock, flags);
} }
/* /*
* remove a channel from the bundle it belongs to * remove a channel from the bundle it belongs to
*/ */
static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp) static inline void
isdn_net_rm_from_bundle(isdn_net_dev *idev)
{ {
isdn_net_local *master_lp = lp; isdn_net_local *mlp = idev->mlp;
unsigned long flags; unsigned long flags;
if (lp->master) spin_lock_irqsave(&mlp->online_lock, flags);
master_lp = (isdn_net_local *) lp->master->priv; // list_del(&idev->online); FIXME
spin_unlock_irqrestore(&mlp->online_lock, flags);
spin_lock_irqsave(&master_lp->netdev->queue_lock, flags);
lp->last->next = lp->next;
lp->next->last = lp->last;
if (master_lp->netdev->queue == lp) {
master_lp->netdev->queue = lp->next;
if (lp->next == lp) { /* last in queue */
master_lp->netdev->queue = &master_lp->netdev->local;
}
}
lp->next = lp->last = lp; /* (re)set own pointers */
spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
} }
/* /*
* wake up the network -> net_device queue. * wake up the network -> net_device queue.
* For slaves, wake the corresponding master interface. * For slaves, wake the corresponding master interface.
*/ */
static inline void isdn_net_device_wake_queue(isdn_net_local *lp) static inline void
isdn_net_dev_wake_queue(isdn_net_dev *idev)
{ {
if (lp->master) netif_wake_queue(&idev->mlp->dev);
netif_wake_queue(lp->master);
else
netif_wake_queue(&lp->netdev->dev);
} }
static inline int isdn_net_bound(isdn_net_dev *idev) static inline int
isdn_net_bound(isdn_net_dev *idev)
{ {
return idev->isdn_slot >= 0; return idev->isdn_slot >= 0;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -20,20 +20,6 @@ extern void isdn_ppp_cleanup(void); ...@@ -20,20 +20,6 @@ extern void isdn_ppp_cleanup(void);
extern int isdn_ppp_dial_slave(char *); extern int isdn_ppp_dial_slave(char *);
extern int isdn_ppp_hangup_slave(char *); extern int isdn_ppp_hangup_slave(char *);
#ifdef CONFIG_ISDN_PPP
int isdn_ppp_xmit(struct sk_buff *, struct net_device *);
#else
static inline int
isdn_ppp_xmit(struct sk_buff *, struct net_device *)
{
return 0;
}
#endif
#define IPPP_OPEN 0x01 #define IPPP_OPEN 0x01
#define IPPP_CONNECT 0x02 #define IPPP_CONNECT 0x02
#define IPPP_CLOSEWAIT 0x04 #define IPPP_CLOSEWAIT 0x04
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include <linux/ioctl.h> #include <linux/ioctl.h>
// FIXME!!!
#include <../drivers/isdn/i4l/isdn_fsm.h>
#ifdef CONFIG_COBALT_MICRO_SERVER #ifdef CONFIG_COBALT_MICRO_SERVER
/* Save memory */ /* Save memory */
#define ISDN_MAX_DRIVERS 2 #define ISDN_MAX_DRIVERS 2
...@@ -282,6 +285,8 @@ struct isdn_net_dev_s; ...@@ -282,6 +285,8 @@ struct isdn_net_dev_s;
struct isdn_net_local_s; struct isdn_net_local_s;
struct isdn_netif_ops { struct isdn_netif_ops {
int (*hard_start_xmit) (struct sk_buff *skb,
struct net_device *dev);
int (*hard_header) (struct sk_buff *skb, int (*hard_header) (struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
unsigned short type, unsigned short type,
...@@ -294,26 +299,24 @@ struct isdn_netif_ops { ...@@ -294,26 +299,24 @@ struct isdn_netif_ops {
unsigned short flags; /* interface flags (a la BSD) */ unsigned short flags; /* interface flags (a la BSD) */
unsigned short type; /* interface hardware type */ unsigned short type; /* interface hardware type */
unsigned char addr_len;/* hardware address length */ unsigned char addr_len;/* hardware address length */
void (*receive)(struct isdn_net_dev_s *p, void (*receive)(struct isdn_net_local_s *,
struct isdn_net_local_s *olp, struct isdn_net_dev_s *,
struct sk_buff *skb); struct sk_buff *);
void (*connected)(struct isdn_net_local_s *lp); void (*connected)(struct isdn_net_dev_s *);
void (*disconnected)(struct isdn_net_local_s *lp); void (*disconnected)(struct isdn_net_dev_s *);
int (*bind)(struct isdn_net_local_s *lp); int (*bind)(struct isdn_net_dev_s *);
void (*unbind)(struct isdn_net_local_s *lp); void (*unbind)(struct isdn_net_dev_s *);
int (*init)(struct isdn_net_local_s *lp); int (*init)(struct isdn_net_local_s *);
void (*cleanup)(struct isdn_net_local_s *lp); void (*cleanup)(struct isdn_net_local_s *);
int (*open)(struct isdn_net_local_s *lp); int (*open)(struct isdn_net_local_s *);
void (*close)(struct isdn_net_local_s *lp); void (*close)(struct isdn_net_local_s *);
}; };
/* Local interface-data */ /* Local interface-data */
typedef struct isdn_net_local_s { typedef struct isdn_net_local_s {
ulong magic; ulong magic;
spinlock_t lock;
struct net_device_stats stats; /* Ethernet Statistics */ struct net_device_stats stats; /* Ethernet Statistics */
int flags; /* Connection-flags */ int flags; /* Connection-flags */
int dialretry; /* Counter for Dialout-retries */
int dialmax; /* Max. Number of Dial-retries */ int dialmax; /* Max. Number of Dial-retries */
int dialtimeout; /* How long shall we try on dialing */ int dialtimeout; /* How long shall we try on dialing */
int dialwait; /* wait after failed attempt */ int dialwait; /* wait after failed attempt */
...@@ -329,26 +332,17 @@ typedef struct isdn_net_local_s { ...@@ -329,26 +332,17 @@ typedef struct isdn_net_local_s {
u_char l2_proto; /* Layer-2-protocol */ u_char l2_proto; /* Layer-2-protocol */
u_char l3_proto; /* Layer-3-protocol */ u_char l3_proto; /* Layer-3-protocol */
int sqfull; /* Flag: netdev-queue overloaded */
ulong sqfull_stamp; /* Start-Time of overload */
ulong slavedelay; /* Dynamic bundling delaytime */ ulong slavedelay; /* Dynamic bundling delaytime */
int triggercps; /* BogoCPS needed for trigger slave */ int triggercps; /* BogoCPS needed for trigger slave */
struct list_head phone[2]; /* List of remote-phonenumbers */ struct list_head phone[2]; /* List of remote-phonenumbers */
/* phone[0] = Incoming Numbers */ /* phone[0] = Incoming Numbers */
/* phone[1] = Outgoing Numbers */ /* phone[1] = Outgoing Numbers */
struct net_device *master; /* Ptr to Master device for slaves */
struct net_device *slave; /* Ptr to Slave device for masters */ struct list_head slaves; /* list of all bundled channels */
struct isdn_net_local_s *next; /* Ptr to next link in bundle */ struct list_head online; /* circular list of all bundled
struct isdn_net_local_s *last; /* Ptr to last link in bundle */ channels, which are currently
struct isdn_net_dev_s *netdev; /* Ptr to netdev */ online */
struct sk_buff_head super_tx_queue; /* List of supervisory frames to */ spinlock_t online_lock; /* lock to protect queue */
/* be transmitted asap */
atomic_t frame_cnt; /* number of frames currently */
/* queued in HL driver */
/* Ptr to orig. hard_header_cache */
spinlock_t xmit_lock; /* used to protect the xmit path of */
/* a particular channel (including */
/* the frame_cnt */
#ifdef CONFIG_ISDN_X25 #ifdef CONFIG_ISDN_X25
struct concap_device_ops *dops; /* callbacks used by encapsulator */ struct concap_device_ops *dops; /* callbacks used by encapsulator */
...@@ -361,33 +355,34 @@ typedef struct isdn_net_local_s { ...@@ -361,33 +355,34 @@ typedef struct isdn_net_local_s {
ulong cisco_last_slarp_in; /* jiffie of last keepalive packet we received */ ulong cisco_last_slarp_in; /* jiffie of last keepalive packet we received */
char cisco_line_state; /* state of line according to keepalive packets */ char cisco_line_state; /* state of line according to keepalive packets */
char cisco_debserint; /* debugging flag of cisco hdlc with slarp */ char cisco_debserint; /* debugging flag of cisco hdlc with slarp */
struct timer_list cisco_timer; struct timer_list cisco_timer;
struct work_struct tqueue;
struct isdn_netif_ops *ops; struct isdn_netif_ops *ops;
struct net_device dev; /* interface to upper levels */
} isdn_net_local; } isdn_net_local;
/* the interface itself */ /* the interface itself */
typedef struct isdn_net_dev_s { typedef struct isdn_net_dev_s {
isdn_net_local local;
int isdn_slot; /* Index to isdn device/channel */ int isdn_slot; /* Index to isdn device/channel */
int pre_device; /* Preselected isdn-device */ int pre_device; /* Preselected isdn-device */
int pre_channel; /* Preselected isdn-channel */ int pre_channel; /* Preselected isdn-channel */
int exclusive; /* -1 if non excl./idx to excl chan */ int exclusive; /* -1 if non excl./idx to excl chan */
struct timer_list dial_timer; /* dial events timer */ struct timer_list dial_timer; /* dial events timer */
struct fsm_inst fi; /* call control state machine */
int dial_event; /* event in case of timer expiry */ int dial_event; /* event in case of timer expiry */
int dialstate; /* State for dialing */
int dial; /* # of phone number just dialed */ int dial; /* # of phone number just dialed */
int outgoing; /* Flag: outgoing call */ int outgoing; /* Flag: outgoing call */
unsigned long dialstarted; /* first dialing-attempt */ int dialretry; /* Counter for Dialout-retries */
unsigned long dialwait_timer;/* earliest next dialing-attempt */
int cps; /* current speed of this interface */ int cps; /* current speed of this interface */
int transcount; /* byte-counter for cps-calculation */ int transcount; /* byte-counter for cps-calculation */
int last_jiffies; /* when transcount was reset */ int last_jiffies; /* when transcount was reset */
int sqfull; /* Flag: netdev-queue overloaded */
ulong sqfull_stamp; /* Start-Time of overload */
struct timer_list hup_timer; /* auto hangup timer */
int huptimer; /* Timeout-counter for auto-hangup */ int huptimer; /* Timeout-counter for auto-hangup */
int charge; /* Counter for charging units */ int charge; /* Counter for charging units */
int charge_state; /* ChargeInfo state machine */ int charge_state; /* ChargeInfo state machine */
...@@ -397,13 +392,22 @@ typedef struct isdn_net_dev_s { ...@@ -397,13 +392,22 @@ typedef struct isdn_net_dev_s {
int pppbind; /* ippp device for bindings */ int pppbind; /* ippp device for bindings */
int ppp_slot; /* PPPD device slot number */ int ppp_slot; /* PPPD device slot number */
isdn_net_local *queue; /* circular list of all bundled spinlock_t xmit_lock; /* used to protect the xmit path of */
channels, which are currently /* a particular channel (including */
online */ /* the frame_cnt */
spinlock_t queue_lock; /* lock to protect queue */ struct sk_buff_head super_tx_queue; /* List of supervisory frames to */
/* be transmitted asap */
atomic_t frame_cnt; /* number of frames currently */
/* queued in HL driver */
struct tasklet_struct tlet;
isdn_net_local *mlp; /* Ptr to master device for all devs*/
struct list_head slaves; /* Members of local->slaves */
struct list_head online; /* Members of local->online */
char name[10]; /* Name of device */ char name[10]; /* Name of device */
struct list_head global_list; /* global list of all isdn_net_devs */ struct list_head global_list; /* global list of all isdn_net_devs */
struct net_device dev; /* interface to upper levels */
#ifdef CONFIG_ISDN_PPP #ifdef CONFIG_ISDN_PPP
ippp_bundle * pb; /* pointer to the common bundle structure ippp_bundle * pb; /* pointer to the common bundle structure
* with the per-bundle data */ * with the per-bundle data */
......
...@@ -159,14 +159,7 @@ typedef struct { ...@@ -159,14 +159,7 @@ typedef struct {
isdn_mppp_stats stats; isdn_mppp_stats stats;
} ippp_bundle; } ippp_bundle;
#define NUM_RCV_BUFFS 64 #define IPPP_MAX_RQ_LEN 8
struct ippp_buf_queue {
struct ippp_buf_queue *next;
struct ippp_buf_queue *last;
char *buf; /* NULL here indicates end of queue */
int len;
};
/* The data structure for one CCP reset transaction */ /* The data structure for one CCP reset transaction */
enum ippp_ccp_reset_states { enum ippp_ccp_reset_states {
...@@ -201,9 +194,7 @@ struct ippp_ccp_reset { ...@@ -201,9 +194,7 @@ struct ippp_ccp_reset {
struct ippp_struct { struct ippp_struct {
struct ippp_struct *next_link; struct ippp_struct *next_link;
int state; int state;
struct ippp_buf_queue rq[NUM_RCV_BUFFS]; /* packet queue for isdn_ppp_read() */ struct sk_buff_head rq;
struct ippp_buf_queue *first; /* pointer to (current) first packet */
struct ippp_buf_queue *last; /* pointer to (current) last used packet in queue */
wait_queue_head_t wq; wait_queue_head_t wq;
struct task_struct *tk; struct task_struct *tk;
unsigned int mpppcfg; unsigned int mpppcfg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment