summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp/base.c
diff options
context:
space:
mode:
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++)