-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
17 changed files
with
7,515 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.