summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp/base.c
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2011-10-26 18:58:14 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2011-10-26 18:58:14 +0000
commit003582d221276735233c1155d5d64e3ee7eec4ac (patch)
tree66494feaba4f8cec822069d61c1ff46f136764ca /drivers/dahdi/wctdm24xxp/base.c
parent2ee9529e22a0c0ba57f01afebe86cdf2e6c72566 (diff)
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@digium.com> Signed-off-by: Oron Peled <oron.peled@xorcom.com> Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10273 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wctdm24xxp/base.c')
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c116
1 files changed, 72 insertions, 44 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 034a908..aabee02 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -4366,6 +4366,32 @@ wctdm_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
return wctdm_wait_for_ready(wc);
}
+/*
+ * wctdm24xxp_assigned - Called when span is assigned.
+ * @span: The span that is now assigned.
+ *
+ * This function is called by the core of DAHDI after the span number and
+ * channel numbers have been assigned.
+ *
+ */
+static void wctdm24xxp_assigned(struct dahdi_span *span)
+{
+ struct dahdi_span *s;
+ struct dahdi_device *ddev = span->parent;
+ struct wctdm *wc = NULL;
+
+ list_for_each_entry(s, &ddev->spans, device_node) {
+ wc = (container_of(s, struct wctdm_span, span))->wc;
+ if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &s->flags))
+ return;
+ }
+
+ if (wc) {
+ WARN_ON(0 == wc->not_ready);
+ --wc->not_ready;
+ }
+}
+
static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
.owner = THIS_MODULE,
.hooksig = wctdm_hooksig,
@@ -4375,6 +4401,7 @@ static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
.watchdog = wctdm_watchdog,
.chanconfig = wctdm_chanconfig,
.dacs = wctdm_dacs,
+ .assigned = wctdm24xxp_assigned,
#ifdef VPM_SUPPORT
.enable_hw_preechocan = wctdm_enable_hw_preechocan,
.disable_hw_preechocan = wctdm_disable_hw_preechocan,
@@ -4393,6 +4420,7 @@ static const struct dahdi_span_ops wctdm24xxp_digital_span_ops = {
.spanconfig = b400m_spanconfig,
.chanconfig = b400m_chanconfig,
.dacs = wctdm_dacs,
+ .assigned = wctdm24xxp_assigned,
#ifdef VPM_SUPPORT
.enable_hw_preechocan = wctdm_enable_hw_preechocan,
.disable_hw_preechocan = wctdm_disable_hw_preechocan,
@@ -4473,11 +4501,6 @@ wctdm_init_span(struct wctdm *wc, int spanno, int chanoffset, int chancount,
sprintf(s->span.name, "WCTDM/%d", card_position);
snprintf(s->span.desc, sizeof(s->span.desc) - 1, "%s", wc->desc->name);
- snprintf(s->span.location, sizeof(s->span.location) - 1,
- "PCI%s Bus %02d Slot %02d",
- (wc->desc->flags & FLAG_EXPRESS) ? " Express" : "",
- pdev->bus->number, PCI_SLOT(pdev->devfn) + 1);
- s->span.manufacturer = "Digium";
if (wc->companding == DAHDI_LAW_DEFAULT) {
if (wc->digi_mods || digital_span)
@@ -4966,9 +4989,10 @@ static void wctdm_back_out_gracefully(struct wctdm *wc)
kfree(frame);
}
-
-
kfree(wc->board_name);
+ kfree(wc->ddev->devicetype);
+ kfree(wc->ddev->location);
+ dahdi_free_device(wc->ddev);
kfree(wc);
}
@@ -5564,27 +5588,6 @@ static void wctdm_allocate_irq_commands(struct wctdm *wc, unsigned int count)
spin_unlock_irqrestore(&wc->reglock, flags);
}
-static void set_span_devicetype_string(struct wctdm *wc)
-{
- unsigned int x;
-
- for (x = 0; x < ARRAY_SIZE(wc->spans); x++) {
- struct dahdi_span *const s = &wc->spans[x]->span;
- if (!s)
- continue;
-
- strlcpy(s->devicetype, wc->desc->name, sizeof(s->devicetype));
-
- if (wc->vpmadt032) {
- strlcat(s->devicetype, " (VPMADT032)",
- sizeof(s->devicetype));
- } else if (wc->vpmoct) {
- strlcat(s->devicetype, " (VPMOCT032)",
- sizeof(s->devicetype));
- }
- }
-}
-
#ifdef USE_ASYNC_INIT
struct async_data {
struct pci_dev *pdev;
@@ -5852,27 +5855,56 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
wc->avchannels = curchan;
- set_span_devicetype_string(wc);
-
#ifdef USE_ASYNC_INIT
async_synchronize_cookie(cookie);
#endif
+ wc->ddev = dahdi_create_device();
+ wc->ddev->manufacturer = "Digium";
+ wc->ddev->location = kasprintf(GFP_KERNEL, "PCI%s Bus %02d Slot %02d",
+ (wc->desc->flags & FLAG_EXPRESS) ?
+ " Express" : "",
+ pdev->bus->number,
+ PCI_SLOT(pdev->devfn) + 1);
+ if (!wc->ddev->location) {
+ wctdm_back_out_gracefully(wc);
+ return -ENOMEM;
+ }
+
+ if (wc->vpmadt032) {
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s (VPMADT032)",
+ wc->desc->name);
+ } else if (wc->vpmoct) {
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s (VPMOCT032)",
+ wc->desc->name);
+ } else {
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s",
+ wc->desc->name);
+ }
+
+ if (!wc->ddev->devicetype) {
+ wctdm_back_out_gracefully(wc);
+ return -ENOMEM;
+ }
+
/* We should be ready for DAHDI to come in now. */
for (i = 0; i < MAX_SPANS; ++i) {
+ struct dahdi_span *span;
+
if (!wc->spans[i])
continue;
- if (dahdi_register(&wc->spans[i]->span, 0)) {
- dev_notice(&wc->vb.pdev->dev, "Unable to register span %d with DAHDI\n", i);
- while (i)
- dahdi_unregister(&wc->spans[i--]->span);
- wctdm_back_out_gracefully(wc);
- return -1;
- }
+ span = &wc->spans[i]->span;
+
+ list_add_tail(&span->device_node, &wc->ddev->spans);
}
wctdm_allocate_irq_commands(wc, anamods * latency * 4);
- wc->not_ready--;
+
+ if (dahdi_register_device(wc->ddev, &wc->vb.pdev->dev)) {
+ dev_notice(&wc->vb.pdev->dev, "Unable to register device with DAHDI\n");
+ wctdm_back_out_gracefully(wc);
+ return -1;
+ }
dev_info(&wc->vb.pdev->dev,
"Found a %s: %s (%d BRI spans, %d analog %s)\n",
@@ -5924,12 +5956,8 @@ static void wctdm_release(struct wctdm *wc)
{
int i;
- if (is_initialized(wc)) {
- for (i = 0; i < MAX_SPANS; i++) {
- if (wc->spans[i])
- dahdi_unregister(&wc->spans[i]->span);
- }
- }
+ if (is_initialized(wc))
+ dahdi_unregister_device(wc->ddev);
down(&ifacelock);
for (i = 0; i < WC_MAX_IFACES; i++)