[svn-commits] tzafrir: linux/trunk r10273 - in /linux/trunk: drivers/dahdi/ drivers/dahdi/v...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Oct 26 13:58:20 CDT 2011


Author: tzafrir
Date: Wed Oct 26 13:58:14 2011
New Revision: 10273

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10273
Log:
dahdi: Register devices instead of individual spans.

Increasingly, spans are implemented by devices that support more than a
single span. Introduce a 'struct dahdi_device' object which explicitly
contains multiple spans. This will allow a cleaner representation of
spans and devices in sysfs since order of arrival will not determine the
layout of the devices. This also gives the core of dahdi a way to know
the relationship between spans.

This generalizes similar concepts that were previously xpp specific. The
conversion of the xpp code was almost entirely done by Oron and Tzafrir.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Signed-off-by: Oron Peled <oron.peled at xorcom.com>
Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c
    linux/trunk/drivers/dahdi/dahdi_dynamic.c
    linux/trunk/drivers/dahdi/pciradio.c
    linux/trunk/drivers/dahdi/tor2.c
    linux/trunk/drivers/dahdi/voicebus/voicebus.c
    linux/trunk/drivers/dahdi/wcb4xxp/base.c
    linux/trunk/drivers/dahdi/wcb4xxp/wcb4xxp.h
    linux/trunk/drivers/dahdi/wcfxo.c
    linux/trunk/drivers/dahdi/wct1xxp.c
    linux/trunk/drivers/dahdi/wct4xxp/base.c
    linux/trunk/drivers/dahdi/wctdm.c
    linux/trunk/drivers/dahdi/wctdm24xxp/base.c
    linux/trunk/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
    linux/trunk/drivers/dahdi/wcte11xp.c
    linux/trunk/drivers/dahdi/wcte12xp/base.c
    linux/trunk/drivers/dahdi/wcte12xp/wcte12xp.h
    linux/trunk/drivers/dahdi/xpp/xbus-core.c
    linux/trunk/drivers/dahdi/xpp/xbus-core.h
    linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c
    linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c
    linux/trunk/drivers/dahdi/xpp/xpp_dahdi.h
    linux/trunk/include/dahdi/kernel.h

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Wed Oct 26 13:58:14 2011
@@ -108,8 +108,6 @@
 EXPORT_SYMBOL(dahdi_transcode_fops);
 EXPORT_SYMBOL(dahdi_init_tone_state);
 EXPORT_SYMBOL(dahdi_mf_tone);
-EXPORT_SYMBOL(dahdi_register);
-EXPORT_SYMBOL(dahdi_unregister);
 EXPORT_SYMBOL(__dahdi_mulaw);
 EXPORT_SYMBOL(__dahdi_alaw);
 #ifdef CONFIG_CALC_XLAW
@@ -399,7 +397,7 @@
 	struct dahdi_span *s;
 	struct pseudo_chan *pseudo;
 
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		unsigned long x;
 		for (x = 0; x < s->channels; x++) {
 			struct dahdi_chan *const chan = s->chans[x];
@@ -439,7 +437,7 @@
 	/* When searching for the channel amongst the spans, we can use the
 	 * fact that channels on a span must be numbered consecutively to skip
 	 * checking each individual channel. */
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		unsigned int basechan;
 		struct dahdi_chan *chan;
 
@@ -488,7 +486,7 @@
 static struct dahdi_span *_find_span(int spanno)
 {
 	struct dahdi_span *s;
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		if (s->spanno == spanno) {
 			return s;
 		}
@@ -526,7 +524,7 @@
 	struct dahdi_span *s;
 	unsigned long flags;
 	spin_lock_irqsave(&chan_lock, flags);
-	list_for_each_entry(s, &span_list, node)
+	list_for_each_entry(s, &span_list, spans_node)
 		++count;
 	spin_unlock_irqrestore(&chan_lock, flags);
 	return count;
@@ -3043,6 +3041,16 @@
 static unsigned int max_pseudo_channels = 512;
 static unsigned int num_pseudo_channels;
 
+static int pinned_spans = 1;
+
+/**
+ * dahdi_alloc_pseudo() - Returns a new pseudo channel.
+ *
+ * Call with the registration_mutex held since this function will determine a
+ * channel number, and must be protected from additional registrations while
+ * that is happening.
+ *
+ */
 static struct dahdi_chan *dahdi_alloc_pseudo(struct file *file)
 {
 	struct pseudo_chan *pseudo;
@@ -3067,8 +3075,6 @@
 	pseudo->chan.sigcap = DAHDI_SIG_CLEAR;
 	pseudo->chan.flags = DAHDI_FLAG_AUDIO;
 	pseudo->chan.span = NULL; /* No span == psuedo channel */
-
-	mutex_lock(&registration_mutex);
 
 	channo = FIRST_PSEUDO_CHANNEL;
 	list_for_each_entry(p, &pseudo_chans, node) {
@@ -3093,8 +3099,6 @@
 	++num_pseudo_channels;
 	list_add(&pseudo->node, pos);
 	spin_unlock_irqrestore(&chan_lock, flags);
-
-	mutex_unlock(&registration_mutex);
 
 	return &pseudo->chan;
 }
@@ -3159,7 +3163,9 @@
 	if (unit == DAHDI_CHANNEL)
 		return dahdi_chan_open(file);
 	if (unit == DAHDI_PSEUDO) {
+		mutex_lock(&registration_mutex);
 		chan = dahdi_alloc_pseudo(file);
+		mutex_unlock(&registration_mutex);
 		if (unlikely(!chan))
 			return -ENOMEM;
 		return dahdi_specchan_open(file);
@@ -3719,7 +3725,7 @@
 
 	spin_lock_irqsave(&chan_lock, flags);
 	old_master = master;
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		if (s->alarms)
 			continue;
 		if (dahdi_is_digital_span(s) &&
@@ -4241,16 +4247,18 @@
 	spaninfo.linecompat = s->linecompat;
 	strlcpy(spaninfo.lboname, dahdi_lboname(s->lbo),
 			  sizeof(spaninfo.lboname));
-	if (s->manufacturer) {
-		strlcpy(spaninfo.manufacturer, s->manufacturer,
-				  sizeof(spaninfo.manufacturer));
-	}
-	if (s->devicetype) {
-		strlcpy(spaninfo.devicetype, s->devicetype,
-				  sizeof(spaninfo.devicetype));
-	}
-	strlcpy(spaninfo.location, s->location,
-			  sizeof(spaninfo.location));
+	if (s->parent->manufacturer) {
+		strlcpy(spaninfo.manufacturer, s->parent->manufacturer,
+			sizeof(spaninfo.manufacturer));
+	}
+	if (s->parent->devicetype) {
+		strlcpy(spaninfo.devicetype, s->parent->devicetype,
+			sizeof(spaninfo.devicetype));
+	}
+	if (s->parent->location) {
+		strlcpy(spaninfo.location, s->parent->location,
+			sizeof(spaninfo.location));
+	}
 	if (s->spantype) {
 		strlcpy(spaninfo.spantype, s->spantype,
 				  sizeof(spaninfo.spantype));
@@ -4328,21 +4336,18 @@
 			  dahdi_lboname(s->lbo),
 			  sizeof(spaninfo_v1.lboname));
 
-	if (s->manufacturer) {
-		strlcpy(spaninfo_v1.manufacturer,
-			s->manufacturer,
+	if (s->parent->manufacturer) {
+		strlcpy(spaninfo_v1.manufacturer, s->parent->manufacturer,
 			sizeof(spaninfo_v1.manufacturer));
 	}
 
-	if (s->devicetype) {
-		strlcpy(spaninfo_v1.devicetype,
-				  s->devicetype,
-				  sizeof(spaninfo_v1.devicetype));
-	}
-
-	strlcpy(spaninfo_v1.location,
-			  s->location,
-			  sizeof(spaninfo_v1.location));
+	if (s->parent->devicetype) {
+		strlcpy(spaninfo_v1.devicetype, s->parent->devicetype,
+			sizeof(spaninfo_v1.devicetype));
+	}
+
+	strlcpy(spaninfo_v1.location, s->parent->location,
+		sizeof(spaninfo_v1.location));
 
 	if (s->spantype) {
 		strlcpy(spaninfo_v1.spantype,
@@ -5399,7 +5404,7 @@
 		struct pseudo_chan *pseudo;
 		c = 0;
 		spin_lock_irqsave(&chan_lock, flags);
-		list_for_each_entry(s, &span_list, node) {
+		list_for_each_entry(s, &span_list, spans_node) {
 			int k;
 			for (k = 0; k < s->channels; k++) {
 				chan = s->chans[k];
@@ -6610,9 +6615,9 @@
  */
 static int _get_next_channo(const struct dahdi_span *span)
 {
-	const struct list_head *pos = &span->node;
+	const struct list_head *pos = &span->spans_node;
 	while (pos != &span_list) {
-		span = list_entry(pos, struct dahdi_span, node);
+		span = list_entry(pos, struct dahdi_span, spans_node);
 		if (span->channels)
 			return span->chans[0]->channo;
 		pos = pos->next;
@@ -6636,10 +6641,10 @@
 	*spanno = 1;
 	*channo = 1;
 
-	list_for_each_entry(pos, &span_list, node) {
+	list_for_each_entry(pos, &span_list, spans_node) {
 		bool skip_span;
 
-		loc = &pos->node;
+		loc = &pos->spans_node;
 		next_channo = _get_next_channo(pos);
 
 		skip_span = (pos->spanno == *spanno) ||
@@ -6658,112 +6663,24 @@
 	return loc;
 }
 
+struct dahdi_device *dahdi_create_device(void)
+{
+	struct dahdi_device *ddev;
+	ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
+	if (!ddev)
+		return NULL;
+	return ddev;
+}
+EXPORT_SYMBOL(dahdi_create_device);
+
+void dahdi_free_device(struct dahdi_device *ddev)
+{
+	kfree(ddev);
+}
+EXPORT_SYMBOL(dahdi_free_device);
+
 /**
- * _dahdi_register - Register the span.
- *
- * NOTE: Must be called with the registration_mutex held.
- *
- */
-static int _dahdi_register(struct dahdi_span *span, int prefmaster)
-{
-	unsigned int spanno;
-	unsigned int x;
-	struct list_head *loc = &span_list;
-	unsigned long flags;
-	unsigned int channo;
-	int res = 0;
-
-	if (!span || !span->ops || !span->ops->owner)
-		return -EINVAL;
-
-	if (span->ops->enable_hw_preechocan ||
-	    span->ops->disable_hw_preechocan) {
-		if ((NULL == span->ops->enable_hw_preechocan) ||
-		    (NULL == span->ops->disable_hw_preechocan))
-			return -EINVAL;
-	}
-
-	if (!span->deflaw) {
-		module_printk(KERN_NOTICE, "Span %s didn't specify default law.  "
-				"Assuming mulaw, please fix driver!\n", span->name);
-		span->deflaw = DAHDI_LAW_MULAW;
-	}
-
-
-	spin_lock_init(&span->lock);
-
-	/* Look through the span list to find the first available span number.
-	 * The spans are kept on this list in sorted order. We'll also save
-	 * off the next available channel number to use. */
-
-	loc = _find_spanno_and_channo(span, &spanno, &channo, loc);
-
-	if (unlikely(channo >= FIRST_PSEUDO_CHANNEL))
-		return -EINVAL;
-
-	span->spanno = spanno;
-	for (x = 0; x < span->channels; x++) {
-		span->chans[x]->span = span;
-		span->chans[x]->channo = channo + x;
-		dahdi_chan_reg(span->chans[x]);
-	}
-
-#ifdef CONFIG_PROC_FS
-	{
-		char tempfile[17];
-		snprintf(tempfile, sizeof(tempfile), "%d", span->spanno);
-		span->proc_entry = create_proc_entry(tempfile, 0444,
-					root_proc_entry);
-		if (!span->proc_entry) {
-			res = -EFAULT;
-			span_err(span, "Error creating procfs entry\n");
-			goto cleanup;
-		}
-		span->proc_entry->data = (void *)(long)span->spanno;
-		span->proc_entry->proc_fops = &dahdi_proc_ops;
-	}
-#endif
-
-	res = span_sysfs_create(span);
-	if (res)
-		goto cleanup;
-
-	if (debug & DEBUG_MAIN) {
-		module_printk(KERN_NOTICE, "Registered Span %d ('%s') with "
-				"%d channels\n", span->spanno, span->name, span->channels);
-	}
-
-	spin_lock_irqsave(&chan_lock, flags);
-	if (loc == &span_list)
-		list_add_tail(&span->node, &span_list);
-	else
-		list_add(&span->node, loc);
-	spin_unlock_irqrestore(&chan_lock, flags);
-	set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
-	__dahdi_find_master_span();
-
-	return 0;
-
-cleanup:
-#ifdef CONFIG_PROC_FS
-	if (span->proc_entry) {
-		char tempfile[17];
-
-		snprintf(tempfile, sizeof(tempfile), "dahdi/%d", span->spanno);
-		remove_proc_entry(tempfile, NULL);
-		span->proc_entry = NULL;
-	}
-#endif
-	for (x = 0; x < span->channels; x++) {
-		struct dahdi_chan *chan = span->chans[x];
-		if (test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags))
-			dahdi_chan_unreg(chan);
-	}
-	return res;
-}
-
-/**
- * dahdi_register() - unregister a new DAHDI span
+ * _dahdi_register_span() - Register a new DAHDI span
  * @span:	the DAHDI span
  * @prefmaster:	will the new span be preferred as a master?
  *
@@ -6775,17 +6692,172 @@
  * master if no other span is currently the master (i.e.: it is the
  * first one).
  *
+ * Must be called with registration_mutex held.
+ *
  */
-int dahdi_register(struct dahdi_span *span, int prefmaster)
+static int _dahdi_register_span(struct dahdi_span *span, int prefmaster)
+{
+	unsigned int spanno;
+	unsigned int x;
+	struct list_head *loc = &span_list;
+	unsigned long flags;
+	unsigned int channo;
+	int res = 0;
+
+	if (!span || !span->ops || !span->ops->owner)
+		return -EINVAL;
+
+	if (span->ops->enable_hw_preechocan ||
+	    span->ops->disable_hw_preechocan) {
+		if ((NULL == span->ops->enable_hw_preechocan) ||
+		    (NULL == span->ops->disable_hw_preechocan))
+			return -EINVAL;
+	}
+
+	if (!span->deflaw) {
+		module_printk(KERN_NOTICE, "Span %s didn't specify default law.  "
+				"Assuming mulaw, please fix driver!\n", span->name);
+		span->deflaw = DAHDI_LAW_MULAW;
+	}
+
+	INIT_LIST_HEAD(&span->spans_node);
+	spin_lock_init(&span->lock);
+
+	/* Look through the span list to find the first available span number.
+	 * The spans are kept on this list in sorted order. We'll also save
+	 * off the next available channel number to use. */
+
+	loc = _find_spanno_and_channo(span, &spanno, &channo, loc);
+
+	if (unlikely(channo >= FIRST_PSEUDO_CHANNEL))
+		return -EINVAL;
+
+	span->spanno = spanno;
+	for (x = 0; x < span->channels; x++) {
+		span->chans[x]->span = span;
+		span->chans[x]->channo = channo + x;
+		dahdi_chan_reg(span->chans[x]);
+	}
+
+#ifdef CONFIG_PROC_FS
+	{
+		char tempfile[17];
+		snprintf(tempfile, sizeof(tempfile), "%d", span->spanno);
+		span->proc_entry = create_proc_entry(tempfile, 0444,
+					root_proc_entry);
+		if (!span->proc_entry) {
+			res = -EFAULT;
+			span_err(span, "Error creating procfs entry\n");
+			goto cleanup;
+		}
+		span->proc_entry->data = (void *)(long)span->spanno;
+		span->proc_entry->proc_fops = &dahdi_proc_ops;
+	}
+#endif
+
+	res = span_sysfs_create(span);
+	if (res)
+		goto cleanup;
+
+	if (debug & DEBUG_MAIN) {
+		module_printk(KERN_NOTICE, "Registered Span %d ('%s') with "
+				"%d channels\n", span->spanno, span->name, span->channels);
+	}
+
+	spin_lock_irqsave(&chan_lock, flags);
+	if (loc == &span_list)
+		list_add_tail(&span->spans_node, &span_list);
+	else
+		list_add(&span->spans_node, loc);
+	spin_unlock_irqrestore(&chan_lock, flags);
+	set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
+	__dahdi_find_master_span();
+
+	return 0;
+
+cleanup:
+#ifdef CONFIG_PROC_FS
+	if (span->proc_entry) {
+		char tempfile[17];
+
+		snprintf(tempfile, sizeof(tempfile), "dahdi/%d", span->spanno);
+		remove_proc_entry(tempfile, NULL);
+		span->proc_entry = NULL;
+	}
+#endif
+	for (x = 0; x < span->channels; x++) {
+		struct dahdi_chan *chan = span->chans[x];
+		if (test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags))
+			dahdi_chan_unreg(chan);
+	}
+	return res;
+}
+
+static const char *UNKNOWN = "";
+
+/**
+ * _dahdi_register_device - Registers the spans of a DAHDI device.
+ * @ddev:	the DAHDI device
+ *
+ * If pinned_spans is defined add the device to the device list and wait for
+ * userspace to finish registration. Otherwise, go ahead and register the
+ * spans in order as was done historically since the beginning of the zaptel
+ * days.
+ *
+ * Must hold registration_mutex when this function is called.
+ *
+ */
+static int _dahdi_register_device(struct dahdi_device *ddev,
+				  struct device *parent)
+{
+	struct dahdi_span *s;
+	int ret = 0;
+
+	ddev->manufacturer	= (ddev->manufacturer) ?: UNKNOWN;
+	ddev->location		= (ddev->location) ?: UNKNOWN;
+	ddev->devicetype	= (ddev->devicetype) ?: UNKNOWN;
+
+	list_for_each_entry(s, &ddev->spans, device_node) {
+		s->parent = ddev;
+		ret = _dahdi_register_span(s, 1);
+	}
+
+	return ret;
+}
+
+/**
+ * dahdi_register_device() - unregister a new DAHDI device
+ * @ddev:	the DAHDI device
+ *
+ * Registers a device for usage with DAHDI.
+ *
+ */
+int dahdi_register_device(struct dahdi_device *ddev, struct device *parent)
 {
 	int ret;
+
+	if (!ddev)
+		return -EINVAL;
+
 	mutex_lock(&registration_mutex);
-	ret = _dahdi_register(span, prefmaster);
+	ret = _dahdi_register_device(ddev, parent);
 	mutex_unlock(&registration_mutex);
+
 	return ret;
 }
-
-static int _dahdi_unregister(struct dahdi_span *span)
+EXPORT_SYMBOL(dahdi_register_device);
+
+/**
+ * _dahdi_unregister_span() - unregister a DAHDI span
+ * @span:	the DAHDI span
+ *
+ * Unregisters a span that has been previously registered with
+ * dahdi_register_span().
+ *
+ * Must be called with the registration_mutex held.
+ *
+ */
+static int _dahdi_unregister_span(struct dahdi_span *span)
 {
 	int x;
 	struct dahdi_span *new_master, *s;
@@ -6797,7 +6869,7 @@
 	}
 
 	spin_lock_irqsave(&chan_lock, flags);
-	list_del_init(&span->node);
+	list_del_init(&span->spans_node);
 	spin_unlock_irqrestore(&chan_lock, flags);
 	span->spanno = 0;
 	clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
@@ -6822,7 +6894,7 @@
 		new_master = NULL;
 
 	spin_lock_irqsave(&chan_lock, flags);
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		if ((s == new_master) || !can_provide_timing(s))
 			continue;
 		new_master = s;
@@ -6839,21 +6911,45 @@
 	return 0;
 }
 
+int dahdi_unregister_span(struct dahdi_span *span)
+{
+	module_printk(KERN_NOTICE, "%s: %s\n", __func__, span->name);
+	mutex_lock(&registration_mutex);
+	_dahdi_unregister_span(span);
+	list_del_init(&span->device_node);
+	mutex_unlock(&registration_mutex);
+	return 0;
+}
+
 /**
- * dahdi_unregister() - unregister a DAHDI span
+ * dahdi_unregister_device() - unregister a DAHDI device
  * @span:	the DAHDI span
  *
- * Unregisters a span that has been previously registered with
- * dahdi_register().
+ * Unregisters a device that has been previously registered with
+ * dahdi_register_device().
+ *
  */
-int dahdi_unregister(struct dahdi_span *span)
-{
-	int ret;
+void dahdi_unregister_device(struct dahdi_device *ddev)
+{
+	struct dahdi_span *s;
+	WARN_ON(!ddev);
+	might_sleep();
+	if (unlikely(!ddev))
+		return;
+
 	mutex_lock(&registration_mutex);
-	ret = _dahdi_unregister(span);
+	list_for_each_entry(s, &ddev->spans, device_node)
+		_dahdi_unregister_span(s);
 	mutex_unlock(&registration_mutex);
-	return ret;
-}
+
+	if (UNKNOWN == ddev->location)
+		ddev->location = NULL;
+	if (UNKNOWN == ddev->manufacturer)
+		ddev->manufacturer = NULL;
+	if (UNKNOWN == ddev->devicetype)
+		ddev->devicetype = NULL;
+}
+EXPORT_SYMBOL(dahdi_unregister_device);
 
 /*
 ** This routine converts from linear to ulaw
@@ -9152,7 +9248,7 @@
 	/* Process any timers */
 	process_timers();
 
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		for (x = 0; x < s->channels; ++x) {
 			struct dahdi_chan *const chan = s->chans[x];
 			if (!chan->confmode)
@@ -9181,7 +9277,7 @@
 		pseudo_rx_audio(&pseudo->chan);
 	}
 
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		for (x = 0; x < s->channels; x++) {
 			struct dahdi_chan *const chan = s->chans[x];
 			if (!chan->confmode)
@@ -9452,6 +9548,11 @@
 module_param(hwec_overrides_swec, int, 0644);
 MODULE_PARM_DESC(hwec_overrides_swec, "When true, a hardware echo canceller is used instead of configured SWEC.");
 
+module_param(pinned_spans, int, 0644);
+MODULE_PARM_DESC(pinned_spans, "If 1, span/channel numbers can be statically "
+		 "defined. If 0, spans/channels are numbered in first come "
+		 "first serve order. Default 1");
+
 static const struct file_operations dahdi_fops = {
 	.owner   = THIS_MODULE,
 	.open    = dahdi_open,
@@ -9494,7 +9595,7 @@
 	struct dahdi_span *s;
 
 	spin_lock_irqsave(&span_list_lock, flags);
-	list_for_each_entry(s, &span_list, node) {
+	list_for_each_entry(s, &span_list, spans_node) {
 		if (s->flags & DAHDI_FLAG_RUNNING) {
 			if (s->watchcounter == DAHDI_WATCHDOG_INIT) {
 				/* Whoops, dead card */

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=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic.c Wed Oct 26 13:58:14 2011
@@ -400,6 +400,7 @@
 	for (x = 0; x < d->span.channels; x++)
 		kfree(d->chans[x]);
 
+	dahdi_free_device(d->ddev);
 	kfree(d);
 }
 
@@ -469,7 +470,7 @@
 		return -EBUSY;
 	}
 
-	dahdi_unregister(&d->span);
+	dahdi_unregister_device(d->ddev);
 
 	spin_lock_irqsave(&dspan_lock, flags);
 	list_del_rcu(&d->list);
@@ -578,8 +579,8 @@
 	d = kzalloc(sizeof(*d), GFP_KERNEL);
 	if (!d)
 		return -ENOMEM;
-
 	kref_init(&d->kref);
+	d->ddev = dahdi_create_device();
 
 	for (x = 0; x < dds->numchans; x++) {
 		d->chans[x] = kzalloc(sizeof(*d->chans[x]), GFP_KERNEL);
@@ -657,8 +658,9 @@
 		return res;
 	}
 
+	list_add_tail(&d->span.device_node, &d->ddev->spans);
 	/* Whee!  We're created.  Now register the span */
-	if (dahdi_register(&d->span, 0)) {
+	if (dahdi_register_device(d->ddev, d->dev)) {
 		printk(KERN_NOTICE "Unable to register span '%s'\n",
 			d->span.name);
 		dynamic_put(d);
@@ -769,7 +771,7 @@
 					WARN_ON(1);
 				}
 			}
-			dahdi_unregister(&d->span);
+			dahdi_unregister_device(d->ddev);
 			spin_lock_irqsave(&dspan_lock, flags);
 			list_del_rcu(&d->list);
 			spin_unlock_irqrestore(&dspan_lock, flags);

Modified: linux/trunk/drivers/dahdi/pciradio.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/pciradio.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/pciradio.c (original)
+++ linux/trunk/drivers/dahdi/pciradio.c Wed Oct 26 13:58:14 2011
@@ -146,6 +146,7 @@
 
 struct pciradio {
 	struct pci_dev *dev;
+	struct dahdi_device *ddev;
 	struct dahdi_span span;
 	unsigned char ios;
 	int usecount;
@@ -1488,7 +1489,7 @@
 	rad->span.flags = DAHDI_FLAG_RBS;
 	rad->span.ops = &pciradio_span_ops;
 
-	if (dahdi_register(&rad->span, 0)) {
+	if (dahdi_register_device(rad->ddev, &rad->dev->dev)) {
 		printk(KERN_NOTICE "Unable to register span with DAHDI\n");
 		return -1;
 	}
@@ -1777,7 +1778,7 @@
 					release_region(rad->ioaddr, 0xff);
 				pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)rad->writechunk, rad->writedma);
 				pci_set_drvdata(pdev, NULL);
-				dahdi_unregister(&rad->span);
+				dahdi_free_device(rad->ddev);
 				kfree(rad);
 				return -EIO;
 
@@ -1810,7 +1811,7 @@
 
 static void pciradio_release(struct pciradio *rad)
 {
-	dahdi_unregister(&rad->span);
+	dahdi_unregister_device(rad->ddev);
 	if (rad->freeregion)
 		release_region(rad->ioaddr, 0xff);
 	kfree(rad);

Modified: linux/trunk/drivers/dahdi/tor2.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/tor2.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/tor2.c (original)
+++ linux/trunk/drivers/dahdi/tor2.c Wed Oct 26 13:58:14 2011
@@ -97,6 +97,7 @@
 	unsigned long xilinx8_region;	/* 8 bit Region allocated to Xilinx */
 	unsigned long xilinx8_len;	/* Length of 8 bit Xilinx region */
 	__iomem volatile unsigned char *mem8;	/* Virtual representation of 8 bit Xilinx memory area */
+	struct dahdi_device *ddev;
 	struct tor2_span tspans[SPANS_PER_CARD];	/* Span data */
 	struct dahdi_chan **chans[SPANS_PER_CARD]; /* Pointers to card channels */
 	struct tor2_chan tchans[32 * SPANS_PER_CARD];	/* Channel user data */
@@ -285,10 +286,6 @@
 		snprintf(s->desc, sizeof(s->desc) - 1,
 			 "Tormenta 2 (PCI) Quad %s Card %d Span %d",
 			 (tor->cardtype == TYPE_T1)  ?  "T1"  :  "E1", tor->num, x + 1);
-		s->manufacturer = "Digium";
-		strlcpy(s->devicetype, tor->type, sizeof(s->devicetype));
-		snprintf(s->location, sizeof(s->location) - 1,
-			 "PCI Bus %02d Slot %02d", tor->pci->bus->number, PCI_SLOT(tor->pci->devfn) + 1);
 		if (tor->cardtype == TYPE_T1) {
 			s->channels = 24;
 			s->deflaw = DAHDI_LAW_MULAW;
@@ -322,19 +319,31 @@
 
 static int __devinit tor2_launch(struct tor2 *tor)
 {
+	int res;
 	struct dahdi_span *s;
 	int i;
 
 	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &tor->tspans[0].dahdi_span.flags))
 		return 0;
+
+	tor->ddev = dahdi_create_device();
+	tor->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
+				       tor->pci->bus->number,
+				       PCI_SLOT(tor->pci->devfn) + 1);
+
+	if (!tor->ddev->location)
+		return -ENOMEM;
 
 	printk(KERN_INFO "Tor2: Launching card: %d\n", tor->order);
 	for (i = 0; i < SPANS_PER_CARD; ++i) {
 		s = &tor->tspans[i].dahdi_span;
-		if (dahdi_register(s, 0)) {
-			printk(KERN_ERR "Unable to register span %s\n", s->name);
-			goto error_exit;
-		}
+		list_add_tail(&s->device_node, &tor->ddev->spans);
+	}
+
+	res = dahdi_register_device(tor->ddev, &tor->pci->dev);
+	if (res) {
+		dev_err(&tor->pci->dev, "Unable to register with DAHDI.\n");
+		return res;
 	}
 	writew(PLX_INTENA, &tor->plx[INTCSR]); /* enable PLX interrupt */
 
@@ -342,14 +351,6 @@
 	tasklet_init(&tor->tor2_tlet, tor2_tasklet, (unsigned long)tor);
 #endif
 	return 0;
-
-error_exit:
-	for (i = 0; i < SPANS_PER_CARD; ++i) {
-		s = &tor->tspans[i].dahdi_span;
-		if (test_bit(DAHDI_FLAGBIT_REGISTERED, &s->flags))
-			dahdi_unregister(s);
-	}
-	return -1;
 }
 
 static void free_tor(struct tor2 *tor)
@@ -365,6 +366,8 @@
 		if (tor->chans[x])
 			kfree(tor->chans[x]);
 	}
+	kfree(tor->ddev->location);
+	dahdi_free_device(tor->ddev);
 	kfree(tor);
 }
 
@@ -631,7 +634,6 @@
 static void __devexit tor2_remove(struct pci_dev *pdev)
 {
 	struct tor2 *tor;
-	int i;
 
 	tor = pci_get_drvdata(pdev);
 	if (!tor)
@@ -641,11 +643,7 @@
 	writeb(0, &tor->mem8[LEDREG]);
 	writew(0, &tor->plx[INTCSR]);
 	free_irq(tor->irq, tor);
-	for (i = 0; i < SPANS_PER_CARD; ++i) {
-		struct dahdi_span *s = &tor->tspans[i].dahdi_span;
-		if (test_bit(DAHDI_FLAGBIT_REGISTERED, &s->flags))
-			dahdi_unregister(s);
-	}
+	dahdi_unregister_device(tor->ddev);
 	release_mem_region(tor->plx_region, tor->plx_len);
 	release_mem_region(tor->xilinx32_region, tor->xilinx32_len);
 	release_mem_region(tor->xilinx8_region, tor->xilinx8_len);

Modified: linux/trunk/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/trunk/drivers/dahdi/voicebus/voicebus.c Wed Oct 26 13:58:14 2011
@@ -2030,7 +2030,7 @@
 	 * defined, but it will make sure that this module is a dependency of
 	 * dahdi.ko, so that when it is being unloded, this module will be
 	 * unloaded as well. */
-	dahdi_register(NULL, 0);
+	dahdi_register_device(NULL, NULL);
 	spin_lock_init(&loader_list_lock);
 	return 0;
 }

Modified: linux/trunk/drivers/dahdi/wcb4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcb4xxp/base.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/wcb4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wcb4xxp/base.c Wed Oct 26 13:58:14 2011
@@ -2494,11 +2494,6 @@
 
 		sprintf(bspan->span.name, "B4/%d/%d", b4->cardno, i+1);
 		sprintf(bspan->span.desc, "B4XXP (PCI) Card %d Span %d", b4->cardno, i+1);
-		bspan->span.manufacturer = "Digium";
-		strlcpy(bspan->span.devicetype, b4->variety,
-			sizeof(bspan->span.devicetype));
-		sprintf(bspan->span.location, "PCI Bus %02d Slot %02d",
-			b4->pdev->bus->number, PCI_SLOT(b4->pdev->devfn) + 1);
 
 		bspan->span.ops = &b4xxp_span_ops;
 /* HDLC stuff */
@@ -2930,14 +2925,27 @@
 	hfc_init_all_st(b4);
 
 /* initialize the DAHDI structures, and let DAHDI know it has some new hardware to play with */
+	b4->ddev = dahdi_create_device();
 	init_spans(b4);
+
 	for (x=0; x < b4->numspans; x++) {
-		if (dahdi_register(&b4->spans[x].span, 0)) {
-			dev_err(&b4->pdev->dev,
-				"Unable to register span %s\n",
-				b4->spans[x].span.name);
-			goto err_out_unreg_spans;
-		}
+		struct dahdi_span *const s = &b4->spans[x].span;
+		list_add_tail(&s->device_node, &b4->ddev->spans);
+	}
+
+	b4->ddev->manufacturer = "Digium";
+	b4->ddev->devicetype = b4->variety;
+	b4->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
+				       b4->pdev->bus->number,
+				       PCI_SLOT(b4->pdev->devfn) + 1);
+	if (!b4->ddev->location) {
+		ret = -ENOMEM;
+		goto err_out_del_from_card_array;
+	}
+
+	if (dahdi_register_device(b4->ddev, &b4->pdev->dev)) {
+		dev_err(&b4->pdev->dev, "Unable to register device.\n");
+		goto err_out_unreg_spans;
 	}
 
 
@@ -2973,10 +2981,7 @@
 
 /* 'x' will have the failing span #. (0-3).  We need to unregister everything before it. */
 err_out_unreg_spans:
-	while (x) {
-		dahdi_unregister(&b4->spans[x].span);
-		x--;
-	};
+	dahdi_unregister_device(b4->ddev);
 
 	b4xxp_init_stage1(b4);			/* full reset, re-init to "no-irq" state */
 	free_irq(pdev->irq, b4);
@@ -2997,6 +3002,8 @@
 	pci_set_drvdata(pdev, NULL);
 	pci_iounmap(pdev, b4->ioaddr);
 	pci_iounmap(pdev, b4->addr);
+	kfree(b4->ddev->location);
+	dahdi_free_device(b4->ddev);
 	kfree(b4);
 
 err_out_release_regions:
@@ -3011,14 +3018,11 @@
 static void __devexit b4xxp_remove(struct pci_dev *pdev)
 {
 	struct b4xxp *b4 = pci_get_drvdata(pdev);
-	int i;
 
 	if (b4) {
 		b4->shutdown = 1;
 
-		for (i=b4->numspans - 1; i >= 0; i--) {
-			dahdi_unregister(&b4->spans[i].span);
-		}
+		dahdi_unregister_device(b4->ddev);
 
 		b4xxp_init_stage1(b4);
 		remove_sysfs_files(b4);
@@ -3033,6 +3037,8 @@
 
 		tasklet_kill(&b4->b4xxp_tlet);
 
+		kfree(b4->ddev->location);
+		dahdi_free_device(b4->ddev);
 		kfree(b4);
 	}
 

Modified: linux/trunk/drivers/dahdi/wcb4xxp/wcb4xxp.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcb4xxp/wcb4xxp.h?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/wcb4xxp/wcb4xxp.h (original)
+++ linux/trunk/drivers/dahdi/wcb4xxp/wcb4xxp.h Wed Oct 26 13:58:14 2011
@@ -474,6 +474,7 @@
 	/* Flags for our bottom half */
 	unsigned int shutdown;			/* 1=bottom half doesn't process anything, just returns */
 	struct tasklet_struct b4xxp_tlet;
+	struct dahdi_device *ddev;
 };
 
 /* CPLD access bits */

Modified: linux/trunk/drivers/dahdi/wcfxo.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcfxo.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/wcfxo.c (original)
+++ linux/trunk/drivers/dahdi/wcfxo.c Wed Oct 26 13:58:14 2011
@@ -135,6 +135,7 @@
 struct wcfxo {
 	struct pci_dev *dev;
 	char *variety;
+	struct dahdi_device *ddev;
 	struct dahdi_span span;
 	struct dahdi_chan _chan;
 	struct dahdi_chan *chan;
@@ -647,14 +648,20 @@
 
 static int wcfxo_initialize(struct wcfxo *wc)
 {
+	wc->ddev = dahdi_create_device();
+
 	/* DAHDI stuff */
 	sprintf(wc->span.name, "WCFXO/%d", wc->pos);
 	snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Board %d", wc->variety, wc->pos + 1);
 	sprintf(wc->chan->name, "WCFXO/%d/%d", wc->pos, 0);
-	snprintf(wc->span.location, sizeof(wc->span.location) - 1,
-		 "PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
-	wc->span.manufacturer = "Digium";
-	strlcpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
+	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
+				      wc->dev->bus->number,
+				      PCI_SLOT(wc->dev->devfn) + 1);
+	if (!wc->ddev->location)
+		return -ENOMEM;
+
+	wc->ddev->manufacturer = "Digium";
+	wc->ddev->devicetype = wc->variety;
 	wc->chan->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF;
 	wc->chan->chanpos = 1;
 	wc->span.chans = &wc->chan;
@@ -668,7 +675,8 @@
 
 	wc->chan->pvt = wc;
 	wc->span.ops = &wcfxo_span_ops;
-	if (dahdi_register(&wc->span, 0)) {
+	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
+	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
 		printk(KERN_NOTICE "Unable to register span with DAHDI\n");
 		return -1;
 	}
@@ -976,7 +984,7 @@
 		printk(KERN_NOTICE "Failed to initailize DAA, giving up...\n");
 		wcfxo_stop_dma(wc);
 		wcfxo_disable_interrupts(wc);
-		dahdi_unregister(&wc->span);
+		dahdi_unregister_device(wc->ddev);
 		free_irq(pdev->irq, wc);
 
 		/* Reset PCI chip and registers */
@@ -984,6 +992,8 @@
 
 		if (wc->freeregion)
 			release_region(wc->ioaddr, 0xff);
+		kfree(wc->ddev->location);
+		dahdi_free_device(wc->ddev);
 		kfree(wc);
 		return -EIO;
 	}
@@ -995,9 +1005,11 @@
 
 static void wcfxo_release(struct wcfxo *wc)
 {
-	dahdi_unregister(&wc->span);
+	dahdi_unregister_device(wc->ddev);
 	if (wc->freeregion)
 		release_region(wc->ioaddr, 0xff);
+	kfree(wc->ddev->location);
+	dahdi_free_device(wc->ddev);
 	kfree(wc);
 	printk(KERN_INFO "Freed a Wildcard\n");
 }

Modified: linux/trunk/drivers/dahdi/wct1xxp.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wct1xxp.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/wct1xxp.c (original)
+++ linux/trunk/drivers/dahdi/wct1xxp.c Wed Oct 26 13:58:14 2011
@@ -159,6 +159,7 @@
 	unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE];
 	unsigned char tempo[32];
 	struct dahdi_span span;						/* Span */
+	struct dahdi_device *ddev;
 	struct dahdi_chan *chans[31];					/* Channels */
 };
 
@@ -272,10 +273,11 @@
 {
 	unsigned int x;
 
-	dahdi_unregister(&wc->span);
+	dahdi_unregister_device(wc->ddev);
 	for (x = 0; x < (wc->ise1 ? 31 : 24); x++) {
 		kfree(wc->chans[x]);
 	}
+	dahdi_free_device(wc->ddev);
 	kfree(wc);
 	printk(KERN_INFO "Freed a Wildcard\n");
 }
@@ -770,13 +772,20 @@
 	}
 	if (x >= WC_MAX_CARDS)
 		return -1;
+
+	wc->ddev = dahdi_create_device();
+
 	wc->num = x;
 	sprintf(wc->span.name, "WCT1/%d", wc->num);
 	snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, wc->num);
-	wc->span.manufacturer = "Digium";
-	strlcpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
-	snprintf(wc->span.location, sizeof(wc->span.location) - 1,
-		 "PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
+	wc->ddev->manufacturer = "Digium";
+	wc->ddev->devicetype = wc->variety;
+	wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
+				      wc->dev->bus->number,
+				      PCI_SLOT(wc->dev->devfn) + 1);
+	if (!wc->ddev->location)
+		return -ENOMEM;
+
 	wc->span.irq = wc->dev->irq;
 	wc->span.chans = wc->chans;
 	wc->span.flags = DAHDI_FLAG_RBS;
@@ -801,7 +810,8 @@
 		wc->chans[x]->chanpos = x + 1;
 	}
 	wc->span.ops = &t1xxp_span_ops;
-	if (dahdi_register(&wc->span, 0)) {
+	list_add_tail(&wc->span.device_node, &wc->ddev->spans);
+	if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
 		printk(KERN_NOTICE "Unable to register span with DAHDI\n");
 		return -1;
 	}

Modified: linux/trunk/drivers/dahdi/wct4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wct4xxp/base.c?view=diff&rev=10273&r1=10272&r2=10273
==============================================================================
--- linux/trunk/drivers/dahdi/wct4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wct4xxp/base.c Wed Oct 26 13:58:14 2011
@@ -325,6 +325,7 @@
 	int num;			/* Which card we are */
 	int t1e1;			/* T1/E1 select pins */
 	int syncsrc;			/* active sync source */
+	struct dahdi_device *ddev;
 	struct t4_span *tspans[4];	/* Individual spans */
 	int numspans;			/* Number of spans on the card */
 	int blinktimer;
@@ -1698,33 +1699,29 @@
 	return 0;
 }
 
+static int set_span_devicetype(struct t4 *wc)
+{
 #ifdef VPM_SUPPORT
-static void set_span_devicetype(struct t4 *wc)
-{
-	int x;
-
-	for (x = 0; x < wc->numspans; x++) {
-		struct t4_span *const ts = wc->tspans[x];
-		strlcpy(ts->span.devicetype, wc->devtype->desc,
-			sizeof(ts->span.devicetype));
-
-		if (wc->vpm450m) {
-			strncat(ts->span.devicetype, (wc->numspans > 2) ? " (VPMOCT128)" : " (VPMOCT064)",
-				sizeof(ts->span.devicetype) - 1);
-		}
-	}
-}
+	const char *vpmstring;
+	if (wc->vpm450m) {
+		if (wc->numspans > 2)
+			vpmstring = "OCT128";
+		else
+			vpmstring = "OCT064";
+
+		wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s (VPM%s)",
+						wc->devtype->desc, vpmstring);
+	} else {
+		wc->ddev->devicetype = kasprintf(GFP_KERNEL, wc->devtype->desc);
+	}
 #else
-static void set_span_devicetype(struct t4 *wc)
-{
-	int x;
-	for (x = 0; x < wc->numspans; x++) {
-		struct t4_span *const ts = wc->tspans[x];
-		strlcpy(ts->span.devicetype, wc->devtype->desc,
-			sizeof(ts->span.devicetype));
-	}
-}
-#endif
+	wc->ddev->devicetype = kasprintf(GFP_KERNEL, wc->devtype->desc);
+#endif
+
+	if (!wc->ddev->devicetype)
+		return -ENOMEM;
+	return 0;
+}
 
 /* The number of cards we have seen with each
    possible 'order' switch setting.
@@ -1805,13 +1802,6 @@
 		sprintf(ts->span.name, "TE%d/%d/%d", wc->numspans, wc->num, x + 1);
 		snprintf(ts->span.desc, sizeof(ts->span.desc) - 1,
 			 "T%dXXP (PCI) Card %d Span %d", wc->numspans, wc->num, x+1);
-		ts->span.manufacturer = "Digium";
-		if (!ignore_rotary && (1 == order_index[wc->order]))
-			snprintf(ts->span.location, sizeof(ts->span.location) - 1, "Board ID Switch %d", wc->order);
-		else
-			snprintf(ts->span.location, sizeof(ts->span.location) - 1,
-				 "PCI%s Bus %02d Slot %02d", (ts->spanflags & FLAG_EXPRESS) ? " Express" : " ",
-				 wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
 		switch (ts->linemode) {
 		case T1:
 			ts->span.spantype = "T1";
@@ -4043,7 +4033,10 @@
 
 static int __devinit t4_launch(struct t4 *wc)
 {
+	int x;
+	int res;
 	unsigned long flags;
+
 	if (test_bit(DAHDI_FLAGBIT_REGISTERED, &wc->tspans[0]->span.flags))
 		return 0;
 
@@ -4055,35 +4048,33 @@
 
 	t4_serial_setup(wc);
 
-	if (dahdi_register(&wc->tspans[0]->span, 0)) {
-		dev_err(&wc->dev->dev, "Unable to register span %s\n",
-				wc->tspans[0]->span.name);
-		return -1;
-	}
-	if (dahdi_register(&wc->tspans[1]->span, 0)) {
-		dev_err(&wc->dev->dev, "Unable to register span %s\n",
-				wc->tspans[1]->span.name);
-		dahdi_unregister(&wc->tspans[0]->span);
-		return -1;
-	}
-
-	if (wc->numspans == 4) {
-		if (dahdi_register(&wc->tspans[2]->span, 0)) {
-			dev_err(&wc->dev->dev, "Unable to register span %s\n",
-					wc->tspans[2]->span.name);
-			dahdi_unregister(&wc->tspans[0]->span);
-			dahdi_unregister(&wc->tspans[1]->span);
-			return -1;
-		}
-		if (dahdi_register(&wc->tspans[3]->span, 0)) {
-			dev_err(&wc->dev->dev, "Unable to register span %s\n",
-					wc->tspans[3]->span.name);
-			dahdi_unregister(&wc->tspans[0]->span);
-			dahdi_unregister(&wc->tspans[1]->span);
-			dahdi_unregister(&wc->tspans[2]->span);
-			return -1;
-		}
-	}
+	wc->ddev->manufacturer = "Digium";
+	if (!ignore_rotary && (1 == order_index[wc->order])) {
+		wc->ddev->location = kasprintf(GFP_KERNEL,
+					      "Board ID Switch %d", wc->order);
+	} else {
+		bool express = ((wc->tspans[0]->spanflags & FLAG_EXPRESS) > 0);
+		wc->ddev->location = kasprintf(GFP_KERNEL,
+					      "PCI%s Bus %02d Slot %02d",
+					      (express) ?  " Express" : "",
+					      wc->dev->bus->number,
+					      PCI_SLOT(wc->dev->devfn) + 1);
+	}
+
+	if (!wc->ddev->location)
+		return -ENOMEM;
+
+	for (x = 0; x < wc->numspans; ++x) {
+		list_add_tail(&wc->tspans[x]->span.device_node,
+			      &wc->ddev->spans);
+	}
+
+	res = dahdi_register_device(wc->ddev, &wc->dev->dev);
+	if (res) {
+		dev_err(&wc->dev->dev, "Failed to register with DAHDI.\n");
+		return res;
+	}
+
 	set_bit(T4_CHECK_TIMING, &wc->checkflag);
 	spin_lock_irqsave(&wc->reglock, flags);
 	__t4_set_sclk_src(wc, WC_SELF, 0, 0);
@@ -4105,6 +4096,10 @@
 		}
 		kfree(wc->tspans[x]);
 	}
+
+	kfree(wc->ddev->devicetype);
+	kfree(wc->ddev->location);
+	dahdi_free_device(wc->ddev);
 	kfree(wc);
 }
 
@@ -4146,11 +4141,16 @@
 		return -EIO;
 	}
 
-	if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
+	wc = kzalloc(sizeof(*wc), GFP_KERNEL);
+	if (!wc)
 		return -ENOMEM;
-	}
-
-	memset(wc, 0x0, sizeof(*wc));
+
+	wc->ddev = dahdi_create_device();
+	if (!wc->ddev) {
+		kfree(wc);
+		return -ENOMEM;
+	}
+
 	spin_lock_init(&wc->reglock);
 	wc->devtype = (const struct devtype *)(ent->driver_data);
 
@@ -4355,9 +4355,12 @@
 
 static void _t4_remove_one(struct t4 *wc)
 {
-	struct dahdi_span *span;
 	int basesize;
-	int i;
+
+	if (!wc)
+		return;
+
+	dahdi_unregister_device(wc->ddev);
 
 	remove_sysfs_files(wc);
 
@@ -4376,11 +4379,6 @@
 	if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN))
 		basesize = basesize * 2;
 

[... 1358 lines stripped ...]



More information about the svn-commits mailing list