dahdi_dynamic: Pass the dahdi_dynamic to create/destroy functions.
This allows the pvt member to be set under lock without holding the lock through the call to create destroy. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Acked-by: Kinsey Moore <kmoore@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9578 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
b68be9abb5
commit
e0d94d5ca4
@ -68,9 +68,6 @@
|
|||||||
before moving to the next.
|
before moving to the next.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Arbitrary limit to the max # of channels in a span */
|
|
||||||
#define DAHDI_DYNAMIC_MAX_CHANS 256
|
|
||||||
|
|
||||||
#define DAHDI_DYNAMIC_FLAG_YELLOW_ALARM (1 << 0)
|
#define DAHDI_DYNAMIC_FLAG_YELLOW_ALARM (1 << 0)
|
||||||
#define DAHDI_DYNAMIC_FLAG_SIGBITS_PRESENT (1 << 1)
|
#define DAHDI_DYNAMIC_FLAG_SIGBITS_PRESENT (1 << 1)
|
||||||
#define DAHDI_DYNAMIC_FLAG_LOOPBACK (1 << 2)
|
#define DAHDI_DYNAMIC_FLAG_LOOPBACK (1 << 2)
|
||||||
@ -93,25 +90,6 @@ static struct tasklet_struct dahdi_dynamic_tlet;
|
|||||||
static void dahdi_dynamic_tasklet(unsigned long data);
|
static void dahdi_dynamic_tasklet(unsigned long data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct dahdi_dynamic {
|
|
||||||
char addr[40];
|
|
||||||
char dname[20];
|
|
||||||
int err;
|
|
||||||
struct kref kref;
|
|
||||||
long rxjif;
|
|
||||||
unsigned short txcnt;
|
|
||||||
unsigned short rxcnt;
|
|
||||||
struct dahdi_span span;
|
|
||||||
struct dahdi_chan *chans[DAHDI_DYNAMIC_MAX_CHANS];
|
|
||||||
struct dahdi_dynamic_driver *driver;
|
|
||||||
void *pvt;
|
|
||||||
int timing;
|
|
||||||
int master;
|
|
||||||
unsigned char *msgbuf;
|
|
||||||
|
|
||||||
struct list_head list;
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(dspan_lock);
|
static DEFINE_SPINLOCK(dspan_lock);
|
||||||
static DEFINE_SPINLOCK(driver_lock);
|
static DEFINE_SPINLOCK(driver_lock);
|
||||||
|
|
||||||
@ -213,7 +191,7 @@ static void dahdi_dynamic_sendmessage(struct dahdi_dynamic *d)
|
|||||||
msglen += DAHDI_CHUNKSIZE;
|
msglen += DAHDI_CHUNKSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->driver->transmit(d->pvt, d->msgbuf, msglen);
|
d->driver->transmit(d, d->msgbuf, msglen);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +391,7 @@ static void dahdi_dynamic_release(struct kref *kref)
|
|||||||
if (d->pvt) {
|
if (d->pvt) {
|
||||||
if (d->driver && d->driver->destroy) {
|
if (d->driver && d->driver->destroy) {
|
||||||
__module_get(d->driver->owner);
|
__module_get(d->driver->owner);
|
||||||
d->driver->destroy(d->pvt);
|
d->driver->destroy(d);
|
||||||
module_put(d->driver->owner);
|
module_put(d->driver->owner);
|
||||||
} else {
|
} else {
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
@ -565,6 +543,7 @@ static const struct dahdi_span_ops dynamic_ops = {
|
|||||||
|
|
||||||
static int create_dynamic(struct dahdi_dynamic_span *dds)
|
static int create_dynamic(struct dahdi_dynamic_span *dds)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
struct dahdi_dynamic *d;
|
struct dahdi_dynamic *d;
|
||||||
struct dahdi_dynamic_driver *dtd;
|
struct dahdi_dynamic_driver *dtd;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -576,7 +555,7 @@ static int create_dynamic(struct dahdi_dynamic_span *dds)
|
|||||||
dds->numchans);
|
dds->numchans);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (dds->numchans >= DAHDI_DYNAMIC_MAX_CHANS) {
|
if (dds->numchans >= ARRAY_SIZE(d->chans)) {
|
||||||
printk(KERN_NOTICE "Can't create dynamic span with greater "
|
printk(KERN_NOTICE "Can't create dynamic span with greater "
|
||||||
"than %d channels. See dahdi_dynamic.c and increase "
|
"than %d channels. See dahdi_dynamic.c and increase "
|
||||||
"DAHDI_DYNAMIC_MAX_CHANS\n", dds->numchans);
|
"DAHDI_DYNAMIC_MAX_CHANS\n", dds->numchans);
|
||||||
@ -662,13 +641,13 @@ static int create_dynamic(struct dahdi_dynamic_span *dds)
|
|||||||
d->driver = dtd;
|
d->driver = dtd;
|
||||||
|
|
||||||
/* Create the stuff */
|
/* Create the stuff */
|
||||||
d->pvt = d->driver->create(&d->span, d->addr);
|
res = dtd->create(d, d->addr);
|
||||||
if (!d->pvt) {
|
if (res) {
|
||||||
printk(KERN_NOTICE "Driver '%s' (%s) rejected address '%s'\n",
|
printk(KERN_NOTICE "Driver '%s' (%s) rejected address '%s'\n",
|
||||||
dtd->name, dtd->desc, d->addr);
|
dtd->name, dtd->desc, d->addr);
|
||||||
dynamic_put(d);
|
dynamic_put(d);
|
||||||
module_put(dtd->owner);
|
module_put(dtd->owner);
|
||||||
return -EINVAL;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Whee! We're created. Now register the span */
|
/* Whee! We're created. Now register the span */
|
||||||
@ -766,9 +745,8 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
|
|||||||
if (d->pvt) {
|
if (d->pvt) {
|
||||||
if (d->driver && d->driver->destroy) {
|
if (d->driver && d->driver->destroy) {
|
||||||
__module_get(d->driver->owner);
|
__module_get(d->driver->owner);
|
||||||
d->driver->destroy(d->pvt);
|
d->driver->destroy(d);
|
||||||
module_put(d->driver->owner);
|
module_put(d->driver->owner);
|
||||||
d->pvt = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ static int ztdeth_notifier(struct notifier_block *block, unsigned long event, vo
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ztdeth_transmit(void *pvt, unsigned char *msg, int msglen)
|
static void ztdeth_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
|
||||||
{
|
{
|
||||||
struct ztdeth *z;
|
struct ztdeth *z;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
@ -151,7 +151,7 @@ static void ztdeth_transmit(void *pvt, unsigned char *msg, int msglen)
|
|||||||
unsigned short subaddr; /* Network byte order */
|
unsigned short subaddr; /* Network byte order */
|
||||||
|
|
||||||
spin_lock_irqsave(&zlock, flags);
|
spin_lock_irqsave(&zlock, flags);
|
||||||
z = pvt;
|
z = dyn->pvt;
|
||||||
if (z->dev) {
|
if (z->dev) {
|
||||||
/* Copy fields to local variables to remove spinlock ASAP */
|
/* Copy fields to local variables to remove spinlock ASAP */
|
||||||
dev = z->dev;
|
dev = z->dev;
|
||||||
@ -266,9 +266,9 @@ static int hex2int(char *s)
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ztdeth_destroy(void *pvt)
|
static void ztdeth_destroy(struct dahdi_dynamic *dyn)
|
||||||
{
|
{
|
||||||
struct ztdeth *z = pvt;
|
struct ztdeth *z = dyn->pvt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct ztdeth *prev=NULL, *cur;
|
struct ztdeth *prev=NULL, *cur;
|
||||||
spin_lock_irqsave(&zlock, flags);
|
spin_lock_irqsave(&zlock, flags);
|
||||||
@ -291,13 +291,14 @@ static void ztdeth_destroy(void *pvt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ztdeth_create(struct dahdi_span *span, const char *addr)
|
static int ztdeth_create(struct dahdi_dynamic *dyn, const char *addr)
|
||||||
{
|
{
|
||||||
struct ztdeth *z;
|
struct ztdeth *z;
|
||||||
char src[256];
|
char src[256];
|
||||||
char tmp[256], *tmp2, *tmp3, *tmp4 = NULL;
|
char tmp[256], *tmp2, *tmp3, *tmp4 = NULL;
|
||||||
int res,x;
|
int res,x;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
struct dahdi_span *const span = &dyn->span;
|
||||||
|
|
||||||
z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL);
|
z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL);
|
||||||
if (z) {
|
if (z) {
|
||||||
@ -314,7 +315,7 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr)
|
|||||||
} else {
|
} else {
|
||||||
printk(KERN_NOTICE "Invalid TDMoE address (no device) '%s'\n", addr);
|
printk(KERN_NOTICE "Invalid TDMoE address (no device) '%s'\n", addr);
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (tmp2) {
|
if (tmp2) {
|
||||||
tmp4 = strchr(tmp2+1, '/');
|
tmp4 = strchr(tmp2+1, '/');
|
||||||
@ -342,12 +343,12 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr)
|
|||||||
if (x != 6) {
|
if (x != 6) {
|
||||||
printk(KERN_NOTICE "TDMoE: Invalid MAC address in: %s\n", addr);
|
printk(KERN_NOTICE "TDMoE: Invalid MAC address in: %s\n", addr);
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_NOTICE "TDMoE: Missing MAC address\n");
|
printk(KERN_NOTICE "TDMoE: Missing MAC address\n");
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (tmp4) {
|
if (tmp4) {
|
||||||
int sub = 0;
|
int sub = 0;
|
||||||
@ -361,7 +362,7 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr)
|
|||||||
} else {
|
} else {
|
||||||
printk(KERN_NOTICE "TDMoE: Invalid subaddress\n");
|
printk(KERN_NOTICE "TDMoE: Invalid subaddress\n");
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
mul *= 10;
|
mul *= 10;
|
||||||
tmp3--;
|
tmp3--;
|
||||||
@ -376,7 +377,7 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr)
|
|||||||
if (!z->dev) {
|
if (!z->dev) {
|
||||||
printk(KERN_NOTICE "TDMoE: Invalid device '%s'\n", z->ethdev);
|
printk(KERN_NOTICE "TDMoE: Invalid device '%s'\n", z->ethdev);
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
z->span = span;
|
z->span = span;
|
||||||
src[0] ='\0';
|
src[0] ='\0';
|
||||||
@ -388,9 +389,10 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr)
|
|||||||
spin_lock_irqsave(&zlock, flags);
|
spin_lock_irqsave(&zlock, flags);
|
||||||
z->next = zdevs;
|
z->next = zdevs;
|
||||||
zdevs = z;
|
zdevs = z;
|
||||||
|
dyn->pvt = z;
|
||||||
spin_unlock_irqrestore(&zlock, flags);
|
spin_unlock_irqrestore(&zlock, flags);
|
||||||
}
|
}
|
||||||
return z;
|
return (z) ? 0 : -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dahdi_dynamic_driver ztd_eth = {
|
static struct dahdi_dynamic_driver ztd_eth = {
|
||||||
|
@ -388,9 +388,9 @@ static int ztdethmf_notifier(struct notifier_block *block, unsigned long event,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ztdethmf_transmit(void *pvt, unsigned char *msg, int msglen)
|
static void ztdethmf_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
|
||||||
{
|
{
|
||||||
struct ztdeth *z = pvt, *ready_spans[ETHMF_MAX_PER_SPAN_GROUP];
|
struct ztdeth *z = dyn->pvt, *ready_spans[ETHMF_MAX_PER_SPAN_GROUP];
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct ztdeth_header *zh;
|
struct ztdeth_header *zh;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
@ -554,9 +554,9 @@ static struct packet_type ztdethmf_ptype = {
|
|||||||
.func = ztdethmf_rcv, /* Receiver */
|
.func = ztdethmf_rcv, /* Receiver */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ztdethmf_destroy(void *pvt)
|
static void ztdethmf_destroy(struct dahdi_dynamic *dyn)
|
||||||
{
|
{
|
||||||
struct ztdeth *z = pvt;
|
struct ztdeth *z = dyn->pvt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
atomic_set(&shutdown, 1);
|
atomic_set(&shutdown, 1);
|
||||||
@ -581,20 +581,21 @@ static void ztdethmf_destroy(void *pvt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ztdethmf_create(struct dahdi_span *span, const char *addr)
|
static int ztdethmf_create(struct dahdi_dynamic *dyn, const char *addr)
|
||||||
{
|
{
|
||||||
struct ztdeth *z;
|
struct ztdeth *z;
|
||||||
char src[256];
|
char src[256];
|
||||||
char *src_ptr;
|
char *src_ptr;
|
||||||
int x, bufsize, num_matched;
|
int x, bufsize, num_matched;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
struct dahdi_span *const span = &dyn->span;
|
||||||
|
|
||||||
BUG_ON(!span);
|
BUG_ON(!span);
|
||||||
BUG_ON(!addr);
|
BUG_ON(!addr);
|
||||||
|
|
||||||
z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL);
|
z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL);
|
||||||
if (!z)
|
if (!z)
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Zero it out */
|
/* Zero it out */
|
||||||
memset(z, 0, sizeof(struct ztdeth));
|
memset(z, 0, sizeof(struct ztdeth));
|
||||||
@ -625,7 +626,7 @@ static void *ztdethmf_create(struct dahdi_span *span, const char *addr)
|
|||||||
printk(KERN_ERR "Only matched %d entries in '%s'\n", num_matched, src);
|
printk(KERN_ERR "Only matched %d entries in '%s'\n", num_matched, src);
|
||||||
printk(KERN_ERR "Invalid TDMoE Multiframe address: %s\n", addr);
|
printk(KERN_ERR "Invalid TDMoE Multiframe address: %s\n", addr);
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
z->dev = dev_get_by_name(
|
z->dev = dev_get_by_name(
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
||||||
@ -635,7 +636,7 @@ static void *ztdethmf_create(struct dahdi_span *span, const char *addr)
|
|||||||
if (!z->dev) {
|
if (!z->dev) {
|
||||||
printk(KERN_ERR "TDMoE Multiframe: Invalid device '%s'\n", z->ethdev);
|
printk(KERN_ERR "TDMoE Multiframe: Invalid device '%s'\n", z->ethdev);
|
||||||
kfree(z);
|
kfree(z);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
z->span = span;
|
z->span = span;
|
||||||
z->subaddr = htons(z->subaddr);
|
z->subaddr = htons(z->subaddr);
|
||||||
@ -662,7 +663,8 @@ static void *ztdethmf_create(struct dahdi_span *span, const char *addr)
|
|||||||
/* enable the timer for enabling the spans */
|
/* enable the timer for enabling the spans */
|
||||||
mod_timer(&timer, jiffies + HZ);
|
mod_timer(&timer, jiffies + HZ);
|
||||||
atomic_set(&shutdown, 0);
|
atomic_set(&shutdown, 0);
|
||||||
return z;
|
dyn->pvt = z;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dahdi_dynamic_driver ztd_ethmf = {
|
static struct dahdi_dynamic_driver ztd_ethmf = {
|
||||||
|
@ -76,17 +76,17 @@ static DEFINE_SPINLOCK(local_lock);
|
|||||||
static LIST_HEAD(dynamic_local_list);
|
static LIST_HEAD(dynamic_local_list);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dahdi_dynamic_local_transmit(void *pvt, unsigned char *msg, int msglen)
|
dahdi_dynamic_local_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
|
||||||
{
|
{
|
||||||
struct dahdi_dynamic_local *const d = pvt;
|
struct dahdi_dynamic_local *const d = dyn->pvt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&local_lock, flags);
|
spin_lock_irqsave(&local_lock, flags);
|
||||||
if (d->peer && d->peer->span) {
|
if (d && d->peer && d->peer->span) {
|
||||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &d->peer->span->flags))
|
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &d->peer->span->flags))
|
||||||
dahdi_dynamic_receive(d->peer->span, msg, msglen);
|
dahdi_dynamic_receive(d->peer->span, msg, msglen);
|
||||||
}
|
}
|
||||||
if (d->monitor_rx_peer && d->monitor_rx_peer->span) {
|
if (d && d->monitor_rx_peer && d->monitor_rx_peer->span) {
|
||||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED,
|
if (test_bit(DAHDI_FLAGBIT_REGISTERED,
|
||||||
&d->monitor_rx_peer->span->flags)) {
|
&d->monitor_rx_peer->span->flags)) {
|
||||||
dahdi_dynamic_receive(d->monitor_rx_peer->span,
|
dahdi_dynamic_receive(d->monitor_rx_peer->span,
|
||||||
@ -128,9 +128,9 @@ static int digit2int(char d)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dahdi_dynamic_local_destroy(void *pvt)
|
static void dahdi_dynamic_local_destroy(struct dahdi_dynamic *dyn)
|
||||||
{
|
{
|
||||||
struct dahdi_dynamic_local *d = pvt;
|
struct dahdi_dynamic_local *d = dyn->pvt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct dahdi_dynamic_local *cur;
|
struct dahdi_dynamic_local *cur;
|
||||||
|
|
||||||
@ -142,6 +142,7 @@ static void dahdi_dynamic_local_destroy(void *pvt)
|
|||||||
cur->monitor_rx_peer = NULL;
|
cur->monitor_rx_peer = NULL;
|
||||||
}
|
}
|
||||||
list_del(&d->node);
|
list_del(&d->node);
|
||||||
|
dyn->pvt = NULL;
|
||||||
spin_unlock_irqrestore(&local_lock, flags);
|
spin_unlock_irqrestore(&local_lock, flags);
|
||||||
|
|
||||||
printk(KERN_INFO "TDMoL: Removed interface for %s, key %d "
|
printk(KERN_INFO "TDMoL: Removed interface for %s, key %d "
|
||||||
@ -149,12 +150,13 @@ static void dahdi_dynamic_local_destroy(void *pvt)
|
|||||||
kfree(d);
|
kfree(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *dahdi_dynamic_local_create(struct dahdi_span *span,
|
static int dahdi_dynamic_local_create(struct dahdi_dynamic *dyn,
|
||||||
const char *address)
|
const char *address)
|
||||||
{
|
{
|
||||||
struct dahdi_dynamic_local *d, *l;
|
struct dahdi_dynamic_local *d, *l;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int key = -1, id = -1, monitor = -1;
|
int key = -1, id = -1, monitor = -1;
|
||||||
|
struct dahdi_span *const span = &dyn->span;
|
||||||
|
|
||||||
if (strlen(address) >= 3) {
|
if (strlen(address) >= 3) {
|
||||||
if (address[1] != ':')
|
if (address[1] != ':')
|
||||||
@ -173,7 +175,7 @@ static void *dahdi_dynamic_local_create(struct dahdi_span *span,
|
|||||||
|
|
||||||
d = kzalloc(sizeof(*d), GFP_KERNEL);
|
d = kzalloc(sizeof(*d), GFP_KERNEL);
|
||||||
if (!d)
|
if (!d)
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
d->key = key;
|
d->key = key;
|
||||||
d->id = id;
|
d->id = id;
|
||||||
@ -214,11 +216,12 @@ static void *dahdi_dynamic_local_create(struct dahdi_span *span,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_add(&d->node, &dynamic_local_list);
|
list_add(&d->node, &dynamic_local_list);
|
||||||
|
dyn->pvt = d;
|
||||||
spin_unlock_irqrestore(&local_lock, flags);
|
spin_unlock_irqrestore(&local_lock, flags);
|
||||||
|
|
||||||
printk(KERN_INFO "TDMoL: Added new interface for %s, "
|
printk(KERN_INFO "TDMoL: Added new interface for %s, "
|
||||||
"key %d id %d\n", span->name, d->key, d->id);
|
"key %d id %d\n", span->name, d->key, d->id);
|
||||||
return d;
|
return 0;
|
||||||
|
|
||||||
CLEAR_AND_DEL_FROM_PEERS:
|
CLEAR_AND_DEL_FROM_PEERS:
|
||||||
list_for_each_entry(l, &dynamic_local_list, node) {
|
list_for_each_entry(l, &dynamic_local_list, node) {
|
||||||
@ -229,11 +232,11 @@ CLEAR_AND_DEL_FROM_PEERS:
|
|||||||
}
|
}
|
||||||
kfree(d);
|
kfree(d);
|
||||||
spin_unlock_irqrestore(&local_lock, flags);
|
spin_unlock_irqrestore(&local_lock, flags);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
|
|
||||||
INVALID_ADDRESS:
|
INVALID_ADDRESS:
|
||||||
printk (KERN_NOTICE "TDMoL: Invalid address %s\n", address);
|
printk (KERN_NOTICE "TDMoL: Invalid address %s\n", address);
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dahdi_dynamic_driver dahdi_dynamic_local = {
|
static struct dahdi_dynamic_driver dahdi_dynamic_local = {
|
||||||
|
@ -986,6 +986,25 @@ struct dahdi_transcoder {
|
|||||||
#define DAHDI_WATCHSTATE_FAILED 3
|
#define DAHDI_WATCHSTATE_FAILED 3
|
||||||
|
|
||||||
|
|
||||||
|
struct dahdi_dynamic {
|
||||||
|
char addr[40];
|
||||||
|
char dname[20];
|
||||||
|
int err;
|
||||||
|
struct kref kref;
|
||||||
|
long rxjif;
|
||||||
|
unsigned short txcnt;
|
||||||
|
unsigned short rxcnt;
|
||||||
|
struct dahdi_span span;
|
||||||
|
struct dahdi_chan *chans[256];
|
||||||
|
struct dahdi_dynamic_driver *driver;
|
||||||
|
void *pvt;
|
||||||
|
int timing;
|
||||||
|
int master;
|
||||||
|
unsigned char *msgbuf;
|
||||||
|
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
struct dahdi_dynamic_driver {
|
struct dahdi_dynamic_driver {
|
||||||
/*! Driver name (e.g. Eth) */
|
/*! Driver name (e.g. Eth) */
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -994,13 +1013,13 @@ struct dahdi_dynamic_driver {
|
|||||||
const char *desc;
|
const char *desc;
|
||||||
|
|
||||||
/*! Create a new transmission pipe */
|
/*! Create a new transmission pipe */
|
||||||
void *(*create)(struct dahdi_span *span, const char *address);
|
int (*create)(struct dahdi_dynamic *d, const char *address);
|
||||||
|
|
||||||
/*! Destroy a created transmission pipe */
|
/*! Destroy a created transmission pipe */
|
||||||
void (*destroy)(void *tpipe);
|
void (*destroy)(struct dahdi_dynamic *d);
|
||||||
|
|
||||||
/*! Transmit a given message */
|
/*! Transmit a given message */
|
||||||
void (*transmit)(void *tpipe, unsigned char *msg, int msglen);
|
void (*transmit)(struct dahdi_dynamic *d, u8 *msg, size_t msglen);
|
||||||
|
|
||||||
/*! Flush any pending messages */
|
/*! Flush any pending messages */
|
||||||
int (*flush)(void);
|
int (*flush)(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user