[svn-commits] sruffell: linux/trunk r9578 - in /linux/trunk: drivers/dahdi/ include/dahdi/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jan 3 18:25:59 UTC 2011


Author: sruffell
Date: Mon Jan  3 12:25:56 2011
New Revision: 9578

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9578
Log:
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 at digium.com>
Acked-by: Kinsey Moore <kmoore at digium.com>

Modified:
    linux/trunk/drivers/dahdi/dahdi_dynamic.c
    linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c
    linux/trunk/drivers/dahdi/dahdi_dynamic_ethmf.c
    linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c
    linux/trunk/include/dahdi/kernel.h

Modified: linux/trunk/drivers/dahdi/dahdi_dynamic.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic.c?view=diff&rev=9578&r1=9577&r2=9578
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic.c Mon Jan  3 12:25:56 2011
@@ -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)
@@ -92,25 +89,6 @@
 
 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 @@
 		msglen += DAHDI_CHUNKSIZE;
 	}
 	
-	d->driver->transmit(d->pvt, d->msgbuf, msglen);
+	d->driver->transmit(d, d->msgbuf, msglen);
 	
 }
 
@@ -413,7 +391,7 @@
 	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 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 @@
 			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 @@
 	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 @@
 			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);
 				}

Modified: linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c?view=diff&rev=9578&r1=9577&r2=9578
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic_eth.c Mon Jan  3 12:25:56 2011
@@ -140,7 +140,7 @@
 	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 @@
 	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 @@
 	return tmp;
 }
 
-static void ztdeth_destroy(void *pvt)
-{
-	struct ztdeth *z = pvt;
+static void ztdeth_destroy(struct dahdi_dynamic *dyn)
+{
+	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_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 @@
 		} 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 @@
 			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 @@
 				} else {
 					printk(KERN_NOTICE "TDMoE: Invalid subaddress\n");
 					kfree(z);
-					return NULL;
+					return -EINVAL;
 				}
 				mul *= 10;
 				tmp3--;
@@ -376,7 +377,7 @@
 		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 @@
 		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 = {

Modified: linux/trunk/drivers/dahdi/dahdi_dynamic_ethmf.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic_ethmf.c?view=diff&rev=9578&r1=9577&r2=9578
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic_ethmf.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic_ethmf.c Mon Jan  3 12:25:56 2011
@@ -388,9 +388,9 @@
 	return 0;
 }
 
-static void ztdethmf_transmit(void *pvt, unsigned char *msg, int msglen)
-{
-	struct ztdeth *z = pvt, *ready_spans[ETHMF_MAX_PER_SPAN_GROUP];
+static void ztdethmf_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
+{
+	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 @@
 	.func = ztdethmf_rcv,			/* Receiver */
 };
 
-static void ztdethmf_destroy(void *pvt)
-{
-	struct ztdeth *z = pvt;
+static void ztdethmf_destroy(struct dahdi_dynamic *dyn)
+{
+	struct ztdeth *z = dyn->pvt;
 	unsigned long flags;
 
 	atomic_set(&shutdown, 1);
@@ -581,20 +581,21 @@
 	}
 }
 
-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 @@
 		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 @@
 	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 @@
 	/* 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 = {

Modified: linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c?view=diff&rev=9578&r1=9577&r2=9578
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic_loc.c Mon Jan  3 12:25:56 2011
@@ -76,17 +76,17 @@
 static LIST_HEAD(dynamic_local_list);
 
 static void
-dahdi_dynamic_local_transmit(void *pvt, unsigned char *msg, int msglen)
-{
-	struct dahdi_dynamic_local *const d = pvt;
+dahdi_dynamic_local_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
+{
+	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 @@
 	return -1;
 }
 
-static void dahdi_dynamic_local_destroy(void *pvt)
-{
-	struct dahdi_dynamic_local *d = pvt;
+static void dahdi_dynamic_local_destroy(struct dahdi_dynamic *dyn)
+{
+	struct dahdi_dynamic_local *d = dyn->pvt;
 	unsigned long flags;
 	struct dahdi_dynamic_local *cur;
 
@@ -142,6 +142,7 @@
 			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 @@
 	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 @@
 
 	d = kzalloc(sizeof(*d), GFP_KERNEL);
 	if (!d)
-		return NULL;
+		return -ENOMEM;
 
 	d->key = key;
 	d->id = id;
@@ -214,11 +216,12 @@
 		}
 	}
 	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 @@
 	}
 	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 = {

Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=9578&r1=9577&r2=9578
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Mon Jan  3 12:25:56 2011
@@ -986,6 +986,25 @@
 #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 @@
 	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);




More information about the svn-commits mailing list