Skip to content

Commit

Permalink
Add mISDN core files
Browse files Browse the repository at this point in the history
Add mISDN core files

Signed-off-by: Karsten Keil <kkeil@suse.de>
  • Loading branch information
Karsten Keil committed Jul 26, 2008
1 parent 04578dd commit 1b2b03f
Show file tree
Hide file tree
Showing 17 changed files with 7,515 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/isdn/mISDN/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# modularer ISDN driver
#

menuconfig MISDN
tristate "Modular ISDN driver"
help
Enable support for the modular ISDN driver.

9 changes: 9 additions & 0 deletions drivers/isdn/mISDN/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Makefile for the modular ISDN driver
#

obj-$(CONFIG_MISDN) += mISDN_core.o

# multi objects

mISDN_core-objs := core.o fsm.o socket.o hwchannel.o stack.o layer1.o layer2.o tei.o timerdev.o
244 changes: 244 additions & 0 deletions drivers/isdn/mISDN/core.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
/*
* Copyright 2008 by Karsten Keil <kkeil@novell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 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.
*
*/

#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/mISDNif.h>
#include "core.h"

static u_int debug;

MODULE_AUTHOR("Karsten Keil");
MODULE_LICENSE("GPL");
module_param(debug, uint, S_IRUGO | S_IWUSR);

static LIST_HEAD(devices);
DEFINE_RWLOCK(device_lock);
static u64 device_ids;
#define MAX_DEVICE_ID 63

static LIST_HEAD(Bprotocols);
DEFINE_RWLOCK(bp_lock);

struct mISDNdevice
*get_mdevice(u_int id)
{
struct mISDNdevice *dev;

read_lock(&device_lock);
list_for_each_entry(dev, &devices, D.list)
if (dev->id == id) {
read_unlock(&device_lock);
return dev;
}
read_unlock(&device_lock);
return NULL;
}

int
get_mdevice_count(void)
{
struct mISDNdevice *dev;
int cnt = 0;

read_lock(&device_lock);
list_for_each_entry(dev, &devices, D.list)
cnt++;
read_unlock(&device_lock);
return cnt;
}

static int
get_free_devid(void)
{
u_int i;

for (i = 0; i <= MAX_DEVICE_ID; i++)
if (!test_and_set_bit(i, (u_long *)&device_ids))
return i;
return -1;
}

int
mISDN_register_device(struct mISDNdevice *dev, char *name)
{
u_long flags;
int err;

dev->id = get_free_devid();
if (dev->id < 0)
return -EBUSY;
if (name && name[0])
strcpy(dev->name, name);
else
sprintf(dev->name, "mISDN%d", dev->id);
if (debug & DEBUG_CORE)
printk(KERN_DEBUG "mISDN_register %s %d\n",
dev->name, dev->id);
err = create_stack(dev);
if (err)
return err;
write_lock_irqsave(&device_lock, flags);
list_add_tail(&dev->D.list, &devices);
write_unlock_irqrestore(&device_lock, flags);
return 0;
}
EXPORT_SYMBOL(mISDN_register_device);

void
mISDN_unregister_device(struct mISDNdevice *dev) {
u_long flags;

if (debug & DEBUG_CORE)
printk(KERN_DEBUG "mISDN_unregister %s %d\n",
dev->name, dev->id);
write_lock_irqsave(&device_lock, flags);
list_del(&dev->D.list);
write_unlock_irqrestore(&device_lock, flags);
test_and_clear_bit(dev->id, (u_long *)&device_ids);
delete_stack(dev);
}
EXPORT_SYMBOL(mISDN_unregister_device);

u_int
get_all_Bprotocols(void)
{
struct Bprotocol *bp;
u_int m = 0;

read_lock(&bp_lock);
list_for_each_entry(bp, &Bprotocols, list)
m |= bp->Bprotocols;
read_unlock(&bp_lock);
return m;
}

struct Bprotocol *
get_Bprotocol4mask(u_int m)
{
struct Bprotocol *bp;

read_lock(&bp_lock);
list_for_each_entry(bp, &Bprotocols, list)
if (bp->Bprotocols & m) {
read_unlock(&bp_lock);
return bp;
}
read_unlock(&bp_lock);
return NULL;
}

struct Bprotocol *
get_Bprotocol4id(u_int id)
{
u_int m;

if (id < ISDN_P_B_START || id > 63) {
printk(KERN_WARNING "%s id not in range %d\n",
__func__, id);
return NULL;
}
m = 1 << (id & ISDN_P_B_MASK);
return get_Bprotocol4mask(m);
}

int
mISDN_register_Bprotocol(struct Bprotocol *bp)
{
u_long flags;
struct Bprotocol *old;

if (debug & DEBUG_CORE)
printk(KERN_DEBUG "%s: %s/%x\n", __func__,
bp->name, bp->Bprotocols);
old = get_Bprotocol4mask(bp->Bprotocols);
if (old) {
printk(KERN_WARNING
"register duplicate protocol old %s/%x new %s/%x\n",
old->name, old->Bprotocols, bp->name, bp->Bprotocols);
return -EBUSY;
}
write_lock_irqsave(&bp_lock, flags);
list_add_tail(&bp->list, &Bprotocols);
write_unlock_irqrestore(&bp_lock, flags);
return 0;
}
EXPORT_SYMBOL(mISDN_register_Bprotocol);

void
mISDN_unregister_Bprotocol(struct Bprotocol *bp)
{
u_long flags;

if (debug & DEBUG_CORE)
printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name,
bp->Bprotocols);
write_lock_irqsave(&bp_lock, flags);
list_del(&bp->list);
write_unlock_irqrestore(&bp_lock, flags);
}
EXPORT_SYMBOL(mISDN_unregister_Bprotocol);

int
mISDNInit(void)
{
int err;

printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n",
MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
mISDN_initstack(&debug);
err = mISDN_inittimer(&debug);
if (err)
goto error;
err = l1_init(&debug);
if (err) {
mISDN_timer_cleanup();
goto error;
}
err = Isdnl2_Init(&debug);
if (err) {
mISDN_timer_cleanup();
l1_cleanup();
goto error;
}
err = misdn_sock_init(&debug);
if (err) {
mISDN_timer_cleanup();
l1_cleanup();
Isdnl2_cleanup();
}
error:
return err;
}

void mISDN_cleanup(void)
{
misdn_sock_cleanup();
mISDN_timer_cleanup();
l1_cleanup();
Isdnl2_cleanup();

if (!list_empty(&devices))
printk(KERN_ERR "%s devices still registered\n", __func__);

if (!list_empty(&Bprotocols))
printk(KERN_ERR "%s Bprotocols still registered\n", __func__);
printk(KERN_DEBUG "mISDNcore unloaded\n");
}

module_init(mISDNInit);
module_exit(mISDN_cleanup);

77 changes: 77 additions & 0 deletions drivers/isdn/mISDN/core.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2008 by Karsten Keil <kkeil@novell.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 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.
*
*/

#ifndef mISDN_CORE_H
#define mISDN_CORE_H

extern struct mISDNdevice *get_mdevice(u_int);
extern int get_mdevice_count(void);

/* stack status flag */
#define mISDN_STACK_ACTION_MASK 0x0000ffff
#define mISDN_STACK_COMMAND_MASK 0x000f0000
#define mISDN_STACK_STATUS_MASK 0xfff00000
/* action bits 0-15 */
#define mISDN_STACK_WORK 0
#define mISDN_STACK_SETUP 1
#define mISDN_STACK_CLEARING 2
#define mISDN_STACK_RESTART 3
#define mISDN_STACK_WAKEUP 4
#define mISDN_STACK_ABORT 15
/* command bits 16-19 */
#define mISDN_STACK_STOPPED 16
#define mISDN_STACK_INIT 17
#define mISDN_STACK_THREADSTART 18
/* status bits 20-31 */
#define mISDN_STACK_BCHANNEL 20
#define mISDN_STACK_ACTIVE 29
#define mISDN_STACK_RUNNING 30
#define mISDN_STACK_KILLED 31


/* manager options */
#define MGR_OPT_USER 24
#define MGR_OPT_NETWORK 25

extern int connect_Bstack(struct mISDNdevice *, struct mISDNchannel *,
u_int, struct sockaddr_mISDN *);
extern int connect_layer1(struct mISDNdevice *, struct mISDNchannel *,
u_int, struct sockaddr_mISDN *);
extern int create_l2entity(struct mISDNdevice *, struct mISDNchannel *,
u_int, struct sockaddr_mISDN *);

extern int create_stack(struct mISDNdevice *);
extern int create_teimanager(struct mISDNdevice *);
extern void delete_teimanager(struct mISDNchannel *);
extern void delete_channel(struct mISDNchannel *);
extern void delete_stack(struct mISDNdevice *);
extern void mISDN_initstack(u_int *);
extern int misdn_sock_init(u_int *);
extern void misdn_sock_cleanup(void);
extern void add_layer2(struct mISDNchannel *, struct mISDNstack *);
extern void __add_layer2(struct mISDNchannel *, struct mISDNstack *);

extern u_int get_all_Bprotocols(void);
struct Bprotocol *get_Bprotocol4mask(u_int);
struct Bprotocol *get_Bprotocol4id(u_int);

extern int mISDN_inittimer(u_int *);
extern void mISDN_timer_cleanup(void);

extern int l1_init(u_int *);
extern void l1_cleanup(void);
extern int Isdnl2_Init(u_int *);
extern void Isdnl2_cleanup(void);

#endif
Loading

0 comments on commit 1b2b03f

Please sign in to comment.