Release 4.11 drivers/isdn/mISDN/core.c
/*
* 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/slab.h>
#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 u64 device_ids;
#define MAX_DEVICE_ID 63
static LIST_HEAD(Bprotocols);
static DEFINE_RWLOCK(bp_lock);
static void mISDN_dev_release(struct device *dev)
{
/* nothing to do: the device is part of its parent's data structure */
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 10 | 83.33% | 1 | 50.00% |
Karsten Keil | 2 | 16.67% | 1 | 50.00% |
Total | 12 | 100.00% | 2 | 100.00% |
static ssize_t id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return -ENODEV;
return sprintf(buf, "%d\n", mdev->id);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 48 | 94.12% | 1 | 33.33% |
Karsten Keil | 2 | 3.92% | 1 | 33.33% |
Greg Kroah-Hartman | 1 | 1.96% | 1 | 33.33% |
Total | 51 | 100.00% | 3 | 100.00% |
static DEVICE_ATTR_RO(id);
static ssize_t nrbchan_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return -ENODEV;
return sprintf(buf, "%d\n", mdev->nrbchan);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 42 | 82.35% | 1 | 33.33% |
Karsten Keil | 8 | 15.69% | 1 | 33.33% |
Greg Kroah-Hartman | 1 | 1.96% | 1 | 33.33% |
Total | 51 | 100.00% | 3 | 100.00% |
static DEVICE_ATTR_RO(nrbchan);
static ssize_t d_protocols_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return -ENODEV;
return sprintf(buf, "%d\n", mdev->Dprotocols);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 50 | 98.04% | 1 | 50.00% |
Greg Kroah-Hartman | 1 | 1.96% | 1 | 50.00% |
Total | 51 | 100.00% | 2 | 100.00% |
static DEVICE_ATTR_RO(d_protocols);
static ssize_t b_protocols_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return -ENODEV;
return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols());
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 53 | 98.15% | 1 | 50.00% |
Greg Kroah-Hartman | 1 | 1.85% | 1 | 50.00% |
Total | 54 | 100.00% | 2 | 100.00% |
static DEVICE_ATTR_RO(b_protocols);
static ssize_t protocol_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return -ENODEV;
return sprintf(buf, "%d\n", mdev->D.protocol);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 52 | 98.11% | 1 | 50.00% |
Greg Kroah-Hartman | 1 | 1.89% | 1 | 50.00% |
Total | 53 | 100.00% | 2 | 100.00% |
static DEVICE_ATTR_RO(protocol);
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
strcpy(buf, dev_name(dev));
return strlen(buf);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 33 | 91.67% | 1 | 33.33% |
Karsten Keil | 2 | 5.56% | 1 | 33.33% |
Greg Kroah-Hartman | 1 | 2.78% | 1 | 33.33% |
Total | 36 | 100.00% | 3 | 100.00% |
static DEVICE_ATTR_RO(name);
#if 0 /* hangs */
static ssize_t name_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int err = 0;
char *out = kmalloc(count + 1, GFP_KERNEL);
if (!out)
return -ENOMEM;
memcpy(out, buf, count);
if (count && out[count - 1] == '\n')
out[--count] = 0;
if (count)
err = device_rename(dev, out);
kfree(out);
return (err < 0) ? err : count;
}
static DEVICE_ATTR_RW(name);
#endif
static ssize_t channelmap_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
char *bp = buf;
int i;
for (i = 0; i <= mdev->nrbchan; i++)
*bp++ = test_channelmap(i, mdev->channelmap) ? '1' : '0';
return bp - buf;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 73 | 96.05% | 1 | 33.33% |
Karsten Keil | 2 | 2.63% | 1 | 33.33% |
Greg Kroah-Hartman | 1 | 1.32% | 1 | 33.33% |
Total | 76 | 100.00% | 3 | 100.00% |
static DEVICE_ATTR_RO(channelmap);
static struct attribute *mISDN_attrs[] = {
&dev_attr_id.attr,
&dev_attr_d_protocols.attr,
&dev_attr_b_protocols.attr,
&dev_attr_protocol.attr,
&dev_attr_channelmap.attr,
&dev_attr_nrbchan.attr,
&dev_attr_name.attr,
NULL,
};
ATTRIBUTE_GROUPS(mISDN);
static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return 0;
if (add_uevent_var(env, "nchans=%d", mdev->nrbchan))
return -ENOMEM;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 52 | 96.30% | 1 | 50.00% |
Karsten Keil | 2 | 3.70% | 1 | 50.00% |
Total | 54 | 100.00% | 2 | 100.00% |
static void mISDN_class_release(struct class *cls)
{
/* do nothing, it's static */
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 12 | 100.00% | 1 | 100.00% |
Total | 12 | 100.00% | 1 | 100.00% |
static struct class mISDN_class = {
.name = "mISDN",
.owner = THIS_MODULE,
.dev_uevent = mISDN_uevent,
.dev_groups = mISDN_groups,
.dev_release = mISDN_dev_release,
.class_release = mISDN_class_release,
};
static int
_get_mdevice(struct device *dev, const void *id)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return 0;
if (mdev->id != *(const u_int *)id)
return 0;
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 49 | 90.74% | 1 | 33.33% |
Karsten Keil | 3 | 5.56% | 1 | 33.33% |
Michał Mirosław | 2 | 3.70% | 1 | 33.33% |
Total | 54 | 100.00% | 3 | 100.00% |
struct mISDNdevice
*get_mdevice(u_int id)
{
return dev_to_mISDN(class_find_device(&mISDN_class, NULL, &id,
_get_mdevice));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 20 | 74.07% | 1 | 50.00% |
Karsten Keil | 7 | 25.93% | 1 | 50.00% |
Total | 27 | 100.00% | 2 | 100.00% |
static int
_get_mdevice_count(struct device *dev, void *cnt)
{
*(int *)cnt += 1;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthias Urlichs | 23 | 85.19% | 1 | 50.00% |
Karsten Keil | 4 | 14.81% | 1 | 50.00% |
Total | 27 | 100.00% | 2 | 100.00% |
int
get_mdevice_count(void)
{
int cnt = 0;
class_for_each_device(&mISDN_class, NULL, &cnt, _get_mdevice_count);
return cnt;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 22 | 78.57% | 1 | 50.00% |
Matthias Urlichs | 6 | 21.43% | 1 | 50.00% |
Total | 28 | 100.00% | 2 | 100.00% |
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))
break;
if (i > MAX_DEVICE_ID)
return -EBUSY;
return i;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 43 | 81.13% | 1 | 33.33% |
Matthias Urlichs | 9 | 16.98% | 1 | 33.33% |
Roel Kluin | 1 | 1.89% | 1 | 33.33% |
Total | 53 | 100.00% | 3 | 100.00% |
int
mISDN_register_device(struct mISDNdevice *dev,
struct device *parent, char *name)
{
int err;
err = get_free_devid();
if (err < 0)
goto error1;
dev->id = err;
device_initialize(&dev->dev);
if (name && name[0])
dev_set_name(&dev->dev, "%s", name);
else
dev_set_name(&dev->dev, "mISDN%d", dev->id);
if (debug & DEBUG_CORE)
printk(KERN_DEBUG "mISDN_register %s %d\n",
dev_name(&dev->dev), dev->id);
err = create_stack(dev);
if (err)
goto error1;
dev->dev.class = &mISDN_class;
dev->dev.platform_data = dev;
dev->dev.parent = parent;
dev_set_drvdata(&dev->dev, dev);
err = device_add(&dev->dev);
if (err)
goto error3;
return 0;
error3:
delete_stack(dev);
return err;
error1:
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 100 | 51.55% | 1 | 25.00% |
Matthias Urlichs | 86 | 44.33% | 2 | 50.00% |
Roel Kluin | 8 | 4.12% | 1 | 25.00% |
Total | 194 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(mISDN_register_device);
void
mISDN_unregister_device(struct mISDNdevice *dev) {
if (debug & DEBUG_CORE)
printk(KERN_DEBUG "mISDN_unregister %s %d\n",
dev_name(&dev->dev), dev->id);
/* sysfs_remove_link(&dev->dev.kobj, "device"); */
device_del(&dev->dev);
dev_set_drvdata(&dev->dev, NULL);
test_and_clear_bit(dev->id, (u_long *)&device_ids);
delete_stack(dev);
put_device(&dev->dev);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 59 | 73.75% | 1 | 33.33% |
Matthias Urlichs | 21 | 26.25% | 2 | 66.67% |
Total | 80 | 100.00% | 3 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 46 | 100.00% | 1 | 100.00% |
Total | 46 | 100.00% | 1 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 57 | 100.00% | 1 | 100.00% |
Total | 57 | 100.00% | 1 | 100.00% |
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 54 | 100.00% | 1 | 100.00% |
Total | 54 | 100.00% | 1 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 111 | 100.00% | 1 | 100.00% |
Total | 111 | 100.00% | 1 | 100.00% |
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);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 59 | 100.00% | 1 | 100.00% |
Total | 59 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(mISDN_unregister_Bprotocol);
static const char *msg_no_channel = "<no channel>";
static const char *msg_no_stack = "<no stack>";
static const char *msg_no_stackdev = "<no stack device>";
const char *mISDNDevName4ch(struct mISDNchannel *ch)
{
if (!ch)
return msg_no_channel;
if (!ch->st)
return msg_no_stack;
if (!ch->st->dev)
return msg_no_stackdev;
return dev_name(&ch->st->dev->dev);
}Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 55 | 100.00% | 1 | 100.00% |
Total | 55 | 100.00% | 1 | 100.00% |
;
EXPORT_SYMBOL(mISDNDevName4ch);
static 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_init_clock(&debug);
mISDN_initstack(&debug);
err = class_register(&mISDN_class);
if (err)
goto error1;
err = mISDN_inittimer(&debug);
if (err)
goto error2;
err = l1_init(&debug);
if (err)
goto error3;
err = Isdnl2_Init(&debug);
if (err)
goto error4;
err = misdn_sock_init(&debug);
if (err)
goto error5;
return 0;
error5:
Isdnl2_cleanup();
error4:
l1_cleanup();
error3:
mISDN_timer_cleanup();
error2:
class_unregister(&mISDN_class);
error1:
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 93 | 65.96% | 1 | 25.00% |
Matthias Urlichs | 41 | 29.08% | 1 | 25.00% |
Andreas Eversberg | 6 | 4.26% | 1 | 25.00% |
Hannes Eder | 1 | 0.71% | 1 | 25.00% |
Total | 141 | 100.00% | 4 | 100.00% |
static void mISDN_cleanup(void)
{
misdn_sock_cleanup();
Isdnl2_cleanup();
l1_cleanup();
mISDN_timer_cleanup();
class_unregister(&mISDN_class);
printk(KERN_DEBUG "mISDNcore unloaded\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 27 | 84.38% | 1 | 33.33% |
Matthias Urlichs | 4 | 12.50% | 1 | 33.33% |
Hannes Eder | 1 | 3.12% | 1 | 33.33% |
Total | 32 | 100.00% | 3 | 100.00% |
module_init(mISDNInit);
module_exit(mISDN_cleanup);
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Karsten Keil | 881 | 50.87% | 2 | 20.00% |
Matthias Urlichs | 738 | 42.61% | 2 | 20.00% |
Greg Kroah-Hartman | 90 | 5.20% | 1 | 10.00% |
Roel Kluin | 9 | 0.52% | 1 | 10.00% |
Andreas Eversberg | 6 | 0.35% | 1 | 10.00% |
Hannes Eder | 3 | 0.17% | 1 | 10.00% |
Tejun Heo | 3 | 0.17% | 1 | 10.00% |
Michał Mirosław | 2 | 0.12% | 1 | 10.00% |
Total | 1732 | 100.00% | 10 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.