diff --git a/drivers/dahdi/dahdi_dynamic.c b/drivers/dahdi/dahdi_dynamic.c index 879ce3a..1162c43 100644 --- a/drivers/dahdi/dahdi_dynamic.c +++ b/drivers/dahdi/dahdi_dynamic.c @@ -68,9 +68,6 @@ 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_SIGBITS_PRESENT (1 << 1) #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); #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(driver_lock); @@ -213,7 +191,7 @@ static void dahdi_dynamic_sendmessage(struct dahdi_dynamic *d) 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->driver && d->driver->destroy) { __module_get(d->driver->owner); - d->driver->destroy(d->pvt); + d->driver->destroy(d); module_put(d->driver->owner); } else { WARN_ON(1); @@ -565,6 +543,7 @@ static const struct dahdi_span_ops dynamic_ops = { static int create_dynamic(struct dahdi_dynamic_span *dds) { + int res = 0; struct dahdi_dynamic *d; struct dahdi_dynamic_driver *dtd; unsigned long flags; @@ -576,7 +555,7 @@ static int create_dynamic(struct dahdi_dynamic_span *dds) dds->numchans); 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 " "than %d channels. See dahdi_dynamic.c and increase " "DAHDI_DYNAMIC_MAX_CHANS\n", dds->numchans); @@ -662,13 +641,13 @@ static int create_dynamic(struct dahdi_dynamic_span *dds) d->driver = dtd; /* Create the stuff */ - d->pvt = d->driver->create(&d->span, d->addr); - if (!d->pvt) { + res = dtd->create(d, d->addr); + if (res) { printk(KERN_NOTICE "Driver '%s' (%s) rejected address '%s'\n", dtd->name, dtd->desc, d->addr); dynamic_put(d); module_put(dtd->owner); - return -EINVAL; + return res; } /* 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->driver && d->driver->destroy) { __module_get(d->driver->owner); - d->driver->destroy(d->pvt); + d->driver->destroy(d); module_put(d->driver->owner); - d->pvt = NULL; } else { WARN_ON(1); } diff --git a/drivers/dahdi/dahdi_dynamic_eth.c b/drivers/dahdi/dahdi_dynamic_eth.c index fb5c1e1..2f8aa51 100644 --- a/drivers/dahdi/dahdi_dynamic_eth.c +++ b/drivers/dahdi/dahdi_dynamic_eth.c @@ -140,7 +140,7 @@ static int ztdeth_notifier(struct notifier_block *block, unsigned long event, vo 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 sk_buff *skb; @@ -151,7 +151,7 @@ static void ztdeth_transmit(void *pvt, unsigned char *msg, int msglen) unsigned short subaddr; /* Network byte order */ spin_lock_irqsave(&zlock, flags); - z = pvt; + z = dyn->pvt; if (z->dev) { /* Copy fields to local variables to remove spinlock ASAP */ dev = z->dev; @@ -266,9 +266,9 @@ static int hex2int(char *s) 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; struct ztdeth *prev=NULL, *cur; 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; char src[256]; char tmp[256], *tmp2, *tmp3, *tmp4 = NULL; int res,x; unsigned long flags; + struct dahdi_span *const span = &dyn->span; z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL); if (z) { @@ -314,7 +315,7 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr) } else { printk(KERN_NOTICE "Invalid TDMoE address (no device) '%s'\n", addr); kfree(z); - return NULL; + return -EINVAL; } if (tmp2) { tmp4 = strchr(tmp2+1, '/'); @@ -342,12 +343,12 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr) if (x != 6) { printk(KERN_NOTICE "TDMoE: Invalid MAC address in: %s\n", addr); kfree(z); - return NULL; + return -EINVAL; } } else { printk(KERN_NOTICE "TDMoE: Missing MAC address\n"); kfree(z); - return NULL; + return -EINVAL; } if (tmp4) { int sub = 0; @@ -361,7 +362,7 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr) } else { printk(KERN_NOTICE "TDMoE: Invalid subaddress\n"); kfree(z); - return NULL; + return -EINVAL; } mul *= 10; tmp3--; @@ -376,7 +377,7 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr) if (!z->dev) { printk(KERN_NOTICE "TDMoE: Invalid device '%s'\n", z->ethdev); kfree(z); - return NULL; + return -EINVAL; } z->span = span; src[0] ='\0'; @@ -388,9 +389,10 @@ static void *ztdeth_create(struct dahdi_span *span, const char *addr) spin_lock_irqsave(&zlock, flags); z->next = zdevs; zdevs = z; + dyn->pvt = z; spin_unlock_irqrestore(&zlock, flags); } - return z; + return (z) ? 0 : -ENOMEM; } static struct dahdi_dynamic_driver ztd_eth = { diff --git a/drivers/dahdi/dahdi_dynamic_ethmf.c b/drivers/dahdi/dahdi_dynamic_ethmf.c index cd5a872..fecce48 100644 --- a/drivers/dahdi/dahdi_dynamic_ethmf.c +++ b/drivers/dahdi/dahdi_dynamic_ethmf.c @@ -388,9 +388,9 @@ static int ztdethmf_notifier(struct notifier_block *block, unsigned long event, 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 ztdeth_header *zh; struct net_device *dev; @@ -554,9 +554,9 @@ static struct packet_type ztdethmf_ptype = { .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; 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; char src[256]; char *src_ptr; int x, bufsize, num_matched; unsigned long flags; + struct dahdi_span *const span = &dyn->span; BUG_ON(!span); BUG_ON(!addr); z = kmalloc(sizeof(struct ztdeth), GFP_KERNEL); if (!z) - return NULL; + return -ENOMEM; /* Zero it out */ 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 "Invalid TDMoE Multiframe address: %s\n", addr); kfree(z); - return NULL; + return -EINVAL; } z->dev = dev_get_by_name( #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) { printk(KERN_ERR "TDMoE Multiframe: Invalid device '%s'\n", z->ethdev); kfree(z); - return NULL; + return -EINVAL; } z->span = span; 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 */ mod_timer(&timer, jiffies + HZ); atomic_set(&shutdown, 0); - return z; + dyn->pvt = z; + return 0; } static struct dahdi_dynamic_driver ztd_ethmf = { diff --git a/drivers/dahdi/dahdi_dynamic_loc.c b/drivers/dahdi/dahdi_dynamic_loc.c index 1f35bd1..6337780 100644 --- a/drivers/dahdi/dahdi_dynamic_loc.c +++ b/drivers/dahdi/dahdi_dynamic_loc.c @@ -76,17 +76,17 @@ static DEFINE_SPINLOCK(local_lock); static LIST_HEAD(dynamic_local_list); 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; 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)) 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, &d->monitor_rx_peer->span->flags)) { dahdi_dynamic_receive(d->monitor_rx_peer->span, @@ -128,9 +128,9 @@ static int digit2int(char d) 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; struct dahdi_dynamic_local *cur; @@ -142,6 +142,7 @@ static void dahdi_dynamic_local_destroy(void *pvt) cur->monitor_rx_peer = NULL; } list_del(&d->node); + dyn->pvt = NULL; spin_unlock_irqrestore(&local_lock, flags); printk(KERN_INFO "TDMoL: Removed interface for %s, key %d " @@ -149,12 +150,13 @@ static void dahdi_dynamic_local_destroy(void *pvt) kfree(d); } -static void *dahdi_dynamic_local_create(struct dahdi_span *span, - const char *address) +static int dahdi_dynamic_local_create(struct dahdi_dynamic *dyn, + const char *address) { struct dahdi_dynamic_local *d, *l; unsigned long flags; int key = -1, id = -1, monitor = -1; + struct dahdi_span *const span = &dyn->span; if (strlen(address) >= 3) { if (address[1] != ':') @@ -173,7 +175,7 @@ static void *dahdi_dynamic_local_create(struct dahdi_span *span, d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) - return NULL; + return -ENOMEM; d->key = key; d->id = id; @@ -214,11 +216,12 @@ static void *dahdi_dynamic_local_create(struct dahdi_span *span, } } list_add(&d->node, &dynamic_local_list); + dyn->pvt = d; spin_unlock_irqrestore(&local_lock, flags); printk(KERN_INFO "TDMoL: Added new interface for %s, " "key %d id %d\n", span->name, d->key, d->id); - return d; + return 0; CLEAR_AND_DEL_FROM_PEERS: list_for_each_entry(l, &dynamic_local_list, node) { @@ -229,11 +232,11 @@ CLEAR_AND_DEL_FROM_PEERS: } kfree(d); spin_unlock_irqrestore(&local_lock, flags); - return NULL; + return -EINVAL; INVALID_ADDRESS: printk (KERN_NOTICE "TDMoL: Invalid address %s\n", address); - return NULL; + return -EINVAL; } static struct dahdi_dynamic_driver dahdi_dynamic_local = { diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h index ff818e8..ce503d9 100644 --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -986,6 +986,25 @@ struct dahdi_transcoder { #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 { /*! Driver name (e.g. Eth) */ const char *name; @@ -994,13 +1013,13 @@ struct dahdi_dynamic_driver { const char *desc; /*! 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 */ - void (*destroy)(void *tpipe); + void (*destroy)(struct dahdi_dynamic *d); /*! 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 */ int (*flush)(void);