summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/dahdi/dahdi-base.c229
-rw-r--r--drivers/dahdi/dahdi_dynamic.c10
-rw-r--r--drivers/dahdi/pciradio.c7
-rw-r--r--drivers/dahdi/tor2.c42
-rw-r--r--drivers/dahdi/voicebus/voicebus.c2
-rw-r--r--drivers/dahdi/wcb4xxp/base.c44
-rw-r--r--drivers/dahdi/wcb4xxp/wcb4xxp.h1
-rw-r--r--drivers/dahdi/wcfxo.c26
-rw-r--r--drivers/dahdi/wct1xxp.c22
-rw-r--r--drivers/dahdi/wct4xxp/base.c124
-rw-r--r--drivers/dahdi/wctdm.c38
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c116
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h1
-rw-r--r--drivers/dahdi/wcte11xp.c23
-rw-r--r--drivers/dahdi/wcte12xp/base.c121
-rw-r--r--drivers/dahdi/wcte12xp/wcte12xp.h8
-rw-r--r--drivers/dahdi/xpp/xbus-core.c87
-rw-r--r--drivers/dahdi/xpp/xbus-core.h1
-rw-r--r--drivers/dahdi/xpp/xbus-sysfs.c25
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.c230
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.h7
-rw-r--r--include/dahdi/kernel.h44
22 files changed, 725 insertions, 483 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 80eea41..825d1c4 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -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 @@ __for_each_channel(unsigned long (*func)(struct dahdi_chan *chan,
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 @@ static struct dahdi_chan *_chan_from_num(unsigned int channo)
/* 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 inline struct dahdi_chan *chan_from_file(struct file *file)
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 @@ static unsigned int span_count(void)
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 int can_open_timer(void)
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;
@@ -3068,8 +3076,6 @@ static struct dahdi_chan *dahdi_alloc_pseudo(struct file *file)
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) {
if (channo != p->chan.channo)
@@ -3094,8 +3100,6 @@ static struct dahdi_chan *dahdi_alloc_pseudo(struct file *file)
list_add(&pseudo->node, pos);
spin_unlock_irqrestore(&chan_lock, flags);
- mutex_unlock(&registration_mutex);
-
return &pseudo->chan;
}
@@ -3159,7 +3163,9 @@ static int dahdi_open(struct inode *inode, struct file *file)
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 @@ static void __dahdi_find_master_span(void)
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 @@ static int dahdi_ioctl_spanstat(struct file *file, unsigned long data)
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->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->devicetype) {
- strlcpy(spaninfo.devicetype, s->devicetype,
- sizeof(spaninfo.devicetype));
+ if (s->parent->location) {
+ strlcpy(spaninfo.location, s->parent->location,
+ sizeof(spaninfo.location));
}
- strlcpy(spaninfo.location, s->location,
- sizeof(spaninfo.location));
if (s->spantype) {
strlcpy(spaninfo.spantype, s->spantype,
sizeof(spaninfo.spantype));
@@ -4328,21 +4336,18 @@ static int dahdi_ioctl_spanstat_v1(struct file *file, unsigned long data)
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));
+ if (s->parent->devicetype) {
+ strlcpy(spaninfo_v1.devicetype, s->parent->devicetype,
+ sizeof(spaninfo_v1.devicetype));
}
- strlcpy(spaninfo_v1.location,
- s->location,
- sizeof(spaninfo_v1.location));
+ strlcpy(spaninfo_v1.location, s->parent->location,
+ sizeof(spaninfo_v1.location));
if (s->spantype) {
strlcpy(spaninfo_v1.spantype,
@@ -5399,7 +5404,7 @@ static int dahdi_ioctl_confdiag(struct file *file, unsigned long data)
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 long dahdi_ioctl_compat(struct file *file, unsigned int cmd,
*/
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 @@ static struct list_head *_find_spanno_and_channo(const struct dahdi_span *span,
*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,13 +6663,39 @@ static struct list_head *_find_spanno_and_channo(const struct dahdi_span *span,
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.
+ * _dahdi_register_span() - Register a new DAHDI span
+ * @span: the DAHDI span
+ * @prefmaster: will the new span be preferred as a master?
+ *
+ * Registers a span for usage with DAHDI. All the channel numbers in it
+ * will get the lowest available channel numbers.
+ *
+ * If prefmaster is set to anything > 0, span will attempt to become the
+ * master DAHDI span at registration time. If 0: it will only become
+ * master if no other span is currently the master (i.e.: it is the
+ * first one).
*
- * NOTE: Must be called with the registration_mutex held.
+ * Must be called with registration_mutex held.
*
*/
-static 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;
@@ -6689,7 +6720,7 @@ static int _dahdi_register(struct dahdi_span *span, int prefmaster)
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.
@@ -6735,9 +6766,9 @@ static int _dahdi_register(struct dahdi_span *span, int prefmaster)
spin_lock_irqsave(&chan_lock, flags);
if (loc == &span_list)
- list_add_tail(&span->node, &span_list);
+ list_add_tail(&span->spans_node, &span_list);
else
- list_add(&span->node, loc);
+ list_add(&span->spans_node, loc);
spin_unlock_irqrestore(&chan_lock, flags);
set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
__dahdi_find_master_span();
@@ -6762,30 +6793,71 @@ cleanup:
return res;
}
+static const char *UNKNOWN = "";
+
/**
- * dahdi_register() - unregister a new DAHDI span
- * @span: the DAHDI span
- * @prefmaster: will the new span be preferred as a master?
+ * _dahdi_register_device - Registers the spans of a DAHDI device.
+ * @ddev: the DAHDI device
*
- * Registers a span for usage with DAHDI. All the channel numbers in it
- * will get the lowest available channel numbers.
+ * 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.
*
- * If prefmaster is set to anything > 0, span will attempt to become the
- * master DAHDI span at registration time. If 0: it will only become
- * master if no other span is currently the master (i.e.: it is the
- * first one).
+ * 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(struct dahdi_span *span, int prefmaster)
+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;
}
+EXPORT_SYMBOL(dahdi_register_device);
-static int _dahdi_unregister(struct dahdi_span *span)
+/**
+ * _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 @@ static int _dahdi_unregister(struct dahdi_span *span)
}
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 @@ static int _dahdi_unregister(struct dahdi_span *span)
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 @@ static int _dahdi_unregister(struct dahdi_span *span)
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)
+void dahdi_unregister_device(struct dahdi_device *ddev)
{
- int ret;
+ 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 @@ static void _process_masterspan(void)
/* 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 @@ static void _process_masterspan(void)
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_PARM_DESC(max_pseudo_channels, "Maximum number of pseudo channels.");
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 @@ static void watchdog_check(unsigned long ignored)
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 */
diff --git a/drivers/dahdi/dahdi_dynamic.c b/drivers/dahdi/dahdi_dynamic.c
index 20d7246..cbcdce7 100644
--- a/drivers/dahdi/dahdi_dynamic.c
+++ b/drivers/dahdi/dahdi_dynamic.c
@@ -400,6 +400,7 @@ static void dahdi_dynamic_release(struct kref *kref)
for (x = 0; x < d->span.channels; x++)
kfree(d->chans[x]);
+ dahdi_free_device(d->ddev);
kfree(d);
}
@@ -469,7 +470,7 @@ static int _destroy_dynamic(struct dahdi_dynamic_span *dds)
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 @@ static int _create_dynamic(struct dahdi_dynamic_span *dds)
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 @@ static int _create_dynamic(struct dahdi_dynamic_span *dds)
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 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
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);
diff --git a/drivers/dahdi/pciradio.c b/drivers/dahdi/pciradio.c
index e6ff52e..0384908 100644
--- a/drivers/dahdi/pciradio.c
+++ b/drivers/dahdi/pciradio.c
@@ -146,6 +146,7 @@ struct encdec
struct pciradio {
struct pci_dev *dev;
+ struct dahdi_device *ddev;
struct dahdi_span span;
unsigned char ios;
int usecount;
@@ -1488,7 +1489,7 @@ static int pciradio_initialize(struct pciradio *rad)
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 @@ static int __devinit pciradio_init_one(struct pci_dev *pdev, const struct pci_de
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 int __devinit pciradio_init_one(struct pci_dev *pdev, const struct pci_de
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);
diff --git a/drivers/dahdi/tor2.c b/drivers/dahdi/tor2.c
index 969f569..6fc8930 100644
--- a/drivers/dahdi/tor2.c
+++ b/drivers/dahdi/tor2.c
@@ -97,6 +97,7 @@ struct tor2 {
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 @@ static void init_spans(struct tor2 *tor)
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 void init_spans(struct tor2 *tor)
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 @@ static int __devinit tor2_launch(struct tor2 *tor)
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 @@ static void free_tor(struct tor2 *tor)
if (tor->chans[x])
kfree(tor->chans[x]);
}
+ kfree(tor->ddev->location);
+ dahdi_free_device(tor->ddev);
kfree(tor);
}
@@ -631,7 +634,6 @@ static struct pci_driver tor2_driver;
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 @@ static void __devexit tor2_remove(struct pci_dev *pdev)
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);
diff --git a/drivers/dahdi/voicebus/voicebus.c b/drivers/dahdi/voicebus/voicebus.c
index d11559a..28b8e32 100644
--- a/drivers/dahdi/voicebus/voicebus.c
+++ b/drivers/dahdi/voicebus/voicebus.c
@@ -2030,7 +2030,7 @@ static int __init voicebus_module_init(void)
* 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;
}
diff --git a/drivers/dahdi/wcb4xxp/base.c b/drivers/dahdi/wcb4xxp/base.c
index 3fb5647..72744f8 100644
--- a/drivers/dahdi/wcb4xxp/base.c
+++ b/drivers/dahdi/wcb4xxp/base.c
@@ -2494,11 +2494,6 @@ static void init_spans(struct b4xxp *b4)
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 @@ static int __devinit b4xx_probe(struct pci_dev *pdev, const struct pci_device_id
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 @@ static int __devinit b4xx_probe(struct pci_dev *pdev, const struct pci_device_id
/* '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 @@ err_out_free_mem:
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 @@ err_out_disable_pdev:
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 @@ static void __devexit b4xxp_remove(struct pci_dev *pdev)
tasklet_kill(&b4->b4xxp_tlet);
+ kfree(b4->ddev->location);
+ dahdi_free_device(b4->ddev);
kfree(b4);
}
diff --git a/drivers/dahdi/wcb4xxp/wcb4xxp.h b/drivers/dahdi/wcb4xxp/wcb4xxp.h
index 56dc93b..80a28fe 100644
--- a/drivers/dahdi/wcb4xxp/wcb4xxp.h
+++ b/drivers/dahdi/wcb4xxp/wcb4xxp.h
@@ -474,6 +474,7 @@ struct b4xxp {
/* 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 */
diff --git a/drivers/dahdi/wcfxo.c b/drivers/dahdi/wcfxo.c
index d206512..948d299 100644
--- a/drivers/dahdi/wcfxo.c
+++ b/drivers/dahdi/wcfxo.c
@@ -135,6 +135,7 @@ static int wecareregs[] =
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 const struct dahdi_span_ops wcfxo_span_ops = {
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 @@ static int wcfxo_initialize(struct wcfxo *wc)
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 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
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 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
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 int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
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");
}
diff --git a/drivers/dahdi/wct1xxp.c b/drivers/dahdi/wct1xxp.c
index fc8373e..686d0a7 100644
--- a/drivers/dahdi/wct1xxp.c
+++ b/drivers/dahdi/wct1xxp.c
@@ -159,6 +159,7 @@ struct t1xxp {
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 @@ static void t1xxp_release(struct t1xxp *wc)
{
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 @@ static int t1xxp_software_init(struct t1xxp *wc)
}
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 @@ static int t1xxp_software_init(struct t1xxp *wc)
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;
}
diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c
index dab436c..4bdea1f 100644
--- a/drivers/dahdi/wct4xxp/base.c
+++ b/drivers/dahdi/wct4xxp/base.c
@@ -325,6 +325,7 @@ struct t4 {
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,34 +1699,30 @@ static int t4_close(struct dahdi_chan *chan)
return 0;
}
-#ifdef VPM_SUPPORT
-static void set_span_devicetype(struct t4 *wc)
+static int 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));
+#ifdef VPM_SUPPORT
+ const char *vpmstring;
+ if (wc->vpm450m) {
+ if (wc->numspans > 2)
+ vpmstring = "OCT128";
+ else
+ vpmstring = "OCT064";
- if (wc->vpm450m) {
- strncat(ts->span.devicetype, (wc->numspans > 2) ? " (VPMOCT128)" : " (VPMOCT064)",
- sizeof(ts->span.devicetype) - 1);
- }
+ 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));
- }
-}
+ 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 @@ static void init_spans(struct t4 *wc)
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 t4_hardware_init_2(struct t4 *wc)
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 @@ static int __devinit t4_launch(struct t4 *wc)
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;
+ 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 (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->ddev->location)
+ return -ENOMEM;
+
+ for (x = 0; x < wc->numspans; ++x) {
+ list_add_tail(&wc->tspans[x]->span.device_node,
+ &wc->ddev->spans);
}
- 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;
- }
+ 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 @@ static void free_wc(struct t4 *wc)
}
kfree(wc->tspans[x]);
}
+
+ kfree(wc->ddev->devicetype);
+ kfree(wc->ddev->location);
+ dahdi_free_device(wc->ddev);
kfree(wc);
}
@@ -4146,11 +4141,16 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
return -EIO;
}
- if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
+ wc = kzalloc(sizeof(*wc), GFP_KERNEL);
+ if (!wc)
+ return -ENOMEM;
+
+ wc->ddev = dahdi_create_device();
+ if (!wc->ddev) {
+ kfree(wc);
return -ENOMEM;
}
- memset(wc, 0x0, sizeof(*wc));
spin_lock_init(&wc->reglock);
wc->devtype = (const struct devtype *)(ent->driver_data);
@@ -4355,9 +4355,12 @@ static int t4_hardware_stop(struct t4 *wc)
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 @@ static void _t4_remove_one(struct t4 *wc)
if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN))
basesize = basesize * 2;
- for (i = 0; i < wc->numspans; ++i) {
- span = &wc->tspans[i]->span;
- if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags))
- dahdi_unregister(span);
- }
#ifdef ENABLE_WORKQUEUES
if (wc->workq) {
flush_workqueue(wc->workq);
diff --git a/drivers/dahdi/wctdm.c b/drivers/dahdi/wctdm.c
index 0e81c84..5b13fee 100644
--- a/drivers/dahdi/wctdm.c
+++ b/drivers/dahdi/wctdm.c
@@ -205,6 +205,7 @@ struct wctdm {
struct pci_dev *dev;
char *variety;
struct dahdi_span span;
+ struct dahdi_device *ddev;
unsigned char ios;
int usecount;
unsigned int intcount;
@@ -2362,13 +2363,26 @@ static int wctdm_initialize(struct wctdm *wc)
{
int x;
+ wc->ddev = dahdi_create_device();
+ if (!wc->ddev)
+ return -ENOMEM;
+
/* DAHDI stuff */
sprintf(wc->span.name, "WCTDM/%d", wc->pos);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Board %d", wc->variety, wc->pos + 1);
- 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) {
+ dahdi_free_device(wc->ddev);
+ wc->ddev = NULL;
+ return -ENOMEM;
+ }
+
+ wc->ddev->manufacturer = "Digium";
+ wc->ddev->devicetype = wc->variety;
+
if (alawoverride) {
printk(KERN_INFO "ALAW override parameter detected. Device will be operating in ALAW\n");
wc->span.deflaw = DAHDI_LAW_ALAW;
@@ -2388,8 +2402,12 @@ static int wctdm_initialize(struct wctdm *wc)
wc->span.flags = DAHDI_FLAG_RBS;
wc->span.ops = &wctdm_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");
+ kfree(wc->ddev->location);
+ dahdi_free_device(wc->ddev);
+ wc->ddev = NULL;
return -1;
}
return 0;
@@ -2677,7 +2695,9 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
release_region(wc->ioaddr, 0xff);
pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)wc->writechunk, wc->writedma);
pci_set_drvdata(pdev, NULL);
- dahdi_unregister(&wc->span);
+ dahdi_unregister_device(wc->ddev);
+ kfree(wc->ddev->location);
+ dahdi_free_device(wc->ddev);
kfree(wc);
return -EIO;
@@ -2708,10 +2728,14 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
static void wctdm_release(struct wctdm *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");
}
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++)
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index c9ae58b..78e555c 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -297,6 +297,7 @@ struct wctdm {
int not_ready; /* 0 when the entire card is ready to go */
unsigned long checkflag; /* Internal state flags and task bits */
int companding;
+ struct dahdi_device *ddev;
};
static inline bool is_initialized(struct wctdm *wc)
diff --git a/drivers/dahdi/wcte11xp.c b/drivers/dahdi/wcte11xp.c
index c8067c7..b2eab8d 100644
--- a/drivers/dahdi/wcte11xp.c
+++ b/drivers/dahdi/wcte11xp.c
@@ -174,6 +174,7 @@ struct t1 {
unsigned char ec_chunk1[32][DAHDI_CHUNKSIZE];
unsigned char ec_chunk2[32][DAHDI_CHUNKSIZE];
unsigned char tempo[33];
+ struct dahdi_device *ddev;
struct dahdi_span span; /* Span */
struct dahdi_chan *chans[32]; /* Channels */
};
@@ -340,10 +341,12 @@ static void t1xxp_release(struct t1 *wc)
{
unsigned int x;
- dahdi_unregister(&wc->span);
+ dahdi_unregister_device(wc->ddev);
for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
kfree(wc->chans[x]);
}
+ kfree(wc->ddev->location);
+ dahdi_free_device(wc->ddev);
kfree(wc);
printk(KERN_INFO "Freed a Wildcard\n");
}
@@ -976,14 +979,21 @@ static int t1xxp_software_init(struct t1 *wc)
}
if (x >= WC_MAX_CARDS)
return -1;
+
+ wc->ddev = dahdi_create_device();
+
t4_serial_setup(wc);
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;
if (wc->spantype == TYPE_E1) {
if (unchannelized)
@@ -1011,7 +1021,8 @@ static int t1xxp_software_init(struct t1 *wc)
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;
}
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 6a6bf24..f6b2a48 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -755,7 +755,7 @@ static void __t1xxp_set_clear(struct t1 *wc)
/* Calculate all states on all 24 channels using the channel
flags, then write all 3 clear channel registers at once */
- for (i = 0; i < 24; i++) {
+ for (i = 0; i < wc->span.channels; i++) {
offset = i/8;
if (wc->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
reg[offset] |= 1 << (7 - (i % 8));
@@ -783,7 +783,7 @@ static void free_wc(struct t1 *wc)
struct command *cmd;
LIST_HEAD(list);
- for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
+ for (x = 0; x < ARRAY_SIZE(wc->chans); x++) {
kfree(wc->chans[x]);
kfree(wc->ec[x]);
}
@@ -808,14 +808,14 @@ static void free_wc(struct t1 *wc)
}
#endif
+ kfree(wc->ddev->location);
+ kfree(wc->ddev->devicetype);
+ dahdi_free_device(wc->ddev);
kfree(wc);
}
static void t4_serial_setup(struct t1 *wc)
{
- t1_info(wc, "Setting up global serial parameters for %s\n",
- ((wc->spantype == TYPE_E1) ? "E1" : "T1"));
-
t1_setreg(wc, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
t1_setreg(wc, 0x08, 0x05); /* IPC: Interrupt push/pull active low */
@@ -1009,12 +1009,12 @@ static void t1_configure_e1(struct t1 *wc, int lineconfig)
t1_info(wc, "Span configured for %s/%s%s\n", framing, line, crc4);
}
-static void t1xxp_framer_start(struct t1 *wc, struct dahdi_span *span)
+static void t1xxp_framer_start(struct t1 *wc)
{
- if (wc->spantype == TYPE_E1) { /* if this is an E1 card */
- t1_configure_e1(wc, span->lineconfig);
+ if (dahdi_is_e1_span(&wc->span)) {
+ t1_configure_e1(wc, wc->span.lineconfig);
} else { /* is a T1 card */
- t1_configure_t1(wc, span->lineconfig, span->txlevel);
+ t1_configure_t1(wc, wc->span.lineconfig, wc->span.txlevel);
__t1xxp_set_clear(wc);
}
@@ -1023,18 +1023,28 @@ static void t1xxp_framer_start(struct t1 *wc, struct dahdi_span *span)
static void set_span_devicetype(struct t1 *wc)
{
- strncpy(wc->span.devicetype, wc->variety,
- sizeof(wc->span.devicetype) - 1);
+ const char *olddevicetype;
+ olddevicetype = wc->ddev->devicetype;
#if defined(VPM_SUPPORT)
if (wc->vpmadt032) {
- strncat(wc->span.devicetype, " (VPMADT032)",
- sizeof(wc->span.devicetype) - 1);
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL,
+ "%s (VPMADT032)", wc->variety);
} else if (wc->vpmoct) {
- strncat(wc->span.devicetype, " (VPMOCT032)",
- sizeof(wc->span.devicetype) - 1);
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL,
+ "%s (VPMOCT032)", wc->variety);
+ } else {
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s", wc->variety);
}
+#else
+ wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s", wc->variety);
#endif
+
+ /* On the off chance that we were able to allocate it previously. */
+ if (!wc->ddev->devicetype)
+ wc->ddev->devicetype = olddevicetype;
+ else
+ kfree(olddevicetype);
}
static int t1xxp_startup(struct file *file, struct dahdi_span *span)
@@ -1055,7 +1065,7 @@ static int t1xxp_startup(struct file *file, struct dahdi_span *span)
#endif
/* Reset framer with proper parameters and start */
- t1xxp_framer_start(wc, span);
+ t1xxp_framer_start(wc);
debug_printk(wc, 1, "Calling startup (flags is %lu)\n", span->flags);
return 0;
@@ -1095,7 +1105,7 @@ static int t1xxp_chanconfig(struct file *file,
}
if (test_bit(DAHDI_FLAGBIT_RUNNING, &chan->span->flags) &&
- (wc->spantype != TYPE_E1)) {
+ dahdi_is_t1_span(&wc->span)) {
__t1xxp_set_clear(wc);
}
return 0;
@@ -1110,7 +1120,7 @@ static int t1xxp_rbsbits(struct dahdi_chan *chan, int bits)
debug_printk(wc, 2, "Setting bits to %d on channel %s\n",
bits, chan->name);
- if (wc->spantype == TYPE_E1) { /* do it E1 way */
+ if (dahdi_is_e1_span(&wc->span)) { /* do it E1 way */
if (chan->chanpos == 16)
return 0;
@@ -1163,7 +1173,7 @@ static inline void t1_check_sigbits(struct t1 *wc)
if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &wc->span.flags)))
return;
- if (wc->spantype == TYPE_E1) {
+ if (dahdi_is_e1_span(&wc->span)) {
for (i = 0; i < 15; i++) {
a = t1_getreg(wc, 0x71 + i);
if (a > -1) {
@@ -1258,7 +1268,7 @@ static void t1xxp_maint_work(struct work_struct *work)
int reg = 0;
int cmd = w->cmd;
- if (wc->spantype == TYPE_E1) {
+ if (dahdi_is_e1_span(&wc->span)) {
switch (cmd) {
case DAHDI_MAINT_NONE:
t1_info(wc, "Clearing all maint modes\n");
@@ -1330,7 +1340,7 @@ static int t1xxp_maint(struct dahdi_span *span, int cmd)
struct maint_work_struct *work;
struct t1 *wc = container_of(span, struct t1, span);
- if (wc->spantype == TYPE_E1) {
+ if (dahdi_is_e1_span(&wc->span)) {
switch (cmd) {
case DAHDI_MAINT_NONE:
case DAHDI_MAINT_LOCALLOOP:
@@ -1625,7 +1635,7 @@ static void check_and_load_vpm(struct t1 *wc)
options.vpmnlptype = vpmnlptype;
options.vpmnlpthresh = vpmnlpthresh;
options.vpmnlpmaxsupp = vpmnlpmaxsupp;
- options.channels = (TYPE_T1 == wc->spantype) ? 24 : 32;
+ options.channels = dahdi_is_t1_span(&wc->span) ? 24 : 32;
/* We do not want to check that the VPM is alive until after we're
* done setting it up here, an hour should cover it... */
@@ -1685,7 +1695,7 @@ static void t1_chan_set_sigcap(struct dahdi_span *span, int x)
struct dahdi_chan *chan = wc->chans[x];
chan->sigcap = DAHDI_SIG_CLEAR;
/* E&M variant supported depends on span type */
- if (wc->spantype == TYPE_E1) {
+ if (dahdi_is_e1_span(&wc->span)) {
/* E1 sigcap setup */
if (span->lineconfig & DAHDI_CONFIG_CCS) {
/* CCS setup */
@@ -1784,9 +1794,19 @@ static const struct dahdi_span_ops t1_span_ops = {
#endif
};
-static int t1_software_init(struct t1 *wc)
+/**
+ * t1_software_init - Initialize the board for the given type.
+ * @wc: The board to initialize.
+ * @type: The type of board we are, T1 / E1
+ *
+ * This function is called at startup and when the type of the span is changed
+ * via the dahdi_device before the span is assigned a number.
+ *
+ */
+static int t1_software_init(struct t1 *wc, enum linemode type)
{
int x;
+ int res;
int num;
struct pci_dev *pdev = wc->vb.pdev;
@@ -1801,21 +1821,23 @@ static int t1_software_init(struct t1 *wc)
if (x == ARRAY_SIZE(ifaces))
return -1;
- t4_serial_setup(wc);
num = x;
sprintf(wc->span.name, "WCT1/%d", num);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, num);
- wc->span.manufacturer = "Digium";
+ wc->ddev->manufacturer = "Digium";
set_span_devicetype(wc);
- snprintf(wc->span.location, sizeof(wc->span.location) - 1,
- "PCI Bus %02d Slot %02d", pdev->bus->number,
- PCI_SLOT(pdev->devfn) + 1);
+ wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
+ pdev->bus->number,
+ PCI_SLOT(pdev->devfn) + 1);
+
+ if (!wc->ddev->location)
+ return -ENOMEM;
wc->span.irq = pdev->irq;
- if (wc->spantype == TYPE_E1) {
+ if (type == E1) {
wc->span.channels = 31;
wc->span.spantype = "E1";
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3 |
@@ -1828,6 +1850,11 @@ static int t1_software_init(struct t1 *wc)
DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
wc->span.deflaw = DAHDI_LAW_MULAW;
}
+
+ t1_info(wc, "Setting up global serial parameters for %s\n",
+ (dahdi_is_e1_span(&wc->span) ? "E1" : "T1"));
+
+ t4_serial_setup(wc);
wc->span.chans = wc->chans;
set_bit(DAHDI_FLAGBIT_RBS, &wc->span.flags);
for (x = 0; x < wc->span.channels; x++) {
@@ -1840,9 +1867,11 @@ static int t1_software_init(struct t1 *wc)
check_and_load_vpm(wc);
wc->span.ops = &t1_span_ops;
- if (dahdi_register(&wc->span, 0)) {
- t1_info(wc, "Unable to register span with DAHDI\n");
- return -1;
+ list_add_tail(&wc->span.device_node, &wc->ddev->spans);
+ res = dahdi_register_device(wc->ddev, &wc->vb.pdev->dev);
+ if (res) {
+ t1_info(wc, "Unable to register with DAHDI\n");
+ return res;
}
return 0;
@@ -1864,7 +1893,7 @@ static inline unsigned char t1_vpm_out(struct t1 *wc, int unit, const unsigned i
#endif
#endif
-static int t1_hardware_post_init(struct t1 *wc)
+static int t1_hardware_post_init(struct t1 *wc, enum linemode *type)
{
int res;
int reg;
@@ -1872,22 +1901,22 @@ static int t1_hardware_post_init(struct t1 *wc)
/* T1 or E1 */
if (-1 != t1e1override) {
- pr_info("t1e1override is deprecated. Please use 'spantype'.\n");
- wc->spantype = (t1e1override) ? TYPE_E1 : TYPE_T1;
+ pr_info("t1e1override is deprecated. Please use 'default_linemode'.\n");
+ *type = (t1e1override) ? E1 : T1;
} else {
if (!strcasecmp(default_linemode, "e1")) {
- wc->spantype = TYPE_E1;
+ *type = E1;
} else if (!strcasecmp(default_linemode, "t1")) {
- wc->spantype = TYPE_T1;
+ *type = T1;
} else {
u8 pins;
res = t1_getpins(wc, &pins);
if (res)
return res;
- wc->spantype = (pins & 0x01) ? TYPE_T1 : TYPE_E1;
+ *type = (pins & 0x01) ? T1 : E1;
}
}
- debug_printk(wc, 1, "linemode: %s\n", 1 == wc->spantype ? "T1" : "E1");
+ debug_printk(wc, 1, "linemode: %s\n", (*type == T1) ? "T1" : "E1");
/* what version of the FALC are we using? */
reg = t1_setreg(wc, 0x4a, 0xaa);
@@ -1938,7 +1967,7 @@ static inline void t1_check_alarms(struct t1 *wc)
/* And consider only carrier alarms */
wc->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
- if (wc->spantype == TYPE_E1) {
+ if (dahdi_is_e1_span(&wc->span)) {
if (c & 0x04) {
/* No multiframe found, force RAI high after 400ms only if
we haven't found a multiframe since last loss
@@ -2555,6 +2584,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
unsigned int x;
int res;
unsigned int index = -1;
+ enum linemode type;
for (x = 0; x < ARRAY_SIZE(ifaces); x++) {
if (!ifaces[x]) {
@@ -2582,6 +2612,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
ifaces[index] = wc;
wc->ledstate = -1;
+ wc->ddev = dahdi_create_device();
spin_lock_init(&wc->reglock);
INIT_LIST_HEAD(&wc->active_cmds);
INIT_LIST_HEAD(&wc->pending_cmds);
@@ -2656,14 +2687,14 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
return -EIO;
}
- res = t1_hardware_post_init(wc);
+ res = t1_hardware_post_init(wc, &type);
if (res) {
voicebus_release(&wc->vb);
free_wc(wc);
return res;
}
- for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
+ for (x = 0; x < ((E1 == type) ? 31 : 24); x++) {
wc->chans[x] = kzalloc(sizeof(*wc->chans[x]), GFP_KERNEL);
if (!wc->chans[x]) {
free_wc(wc);
@@ -2679,7 +2710,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
}
}
- res = t1_software_init(wc);
+ res = t1_software_init(wc, type);
if (res) {
voicebus_release(&wc->vb);
free_wc(wc);
@@ -2710,7 +2741,7 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev)
if (!wc)
return;
- dahdi_unregister(&wc->span);
+ dahdi_unregister_device(wc->ddev);
remove_sysfs_files(wc);
diff --git a/drivers/dahdi/wcte12xp/wcte12xp.h b/drivers/dahdi/wcte12xp/wcte12xp.h
index 507a43e..8ef4753 100644
--- a/drivers/dahdi/wcte12xp/wcte12xp.h
+++ b/drivers/dahdi/wcte12xp/wcte12xp.h
@@ -74,8 +74,10 @@
#define CMD_BYTE(slot, a, is_vpm) (slot*6)+(a*2)+is_vpm /* only even slots */
//TODO: make a separate macro
-#define TYPE_T1 1
-#define TYPE_E1 2
+enum linemode {
+ T1 = 1,
+ E1,
+};
struct command {
struct list_head node;
@@ -94,7 +96,6 @@ struct t1 {
unsigned char txident;
unsigned char rxident;
unsigned char statreg; /* bit 0 = vpmadt032 int */
- int spantype;
struct {
unsigned int nmf:1;
unsigned int sendingyellow:1;
@@ -116,6 +117,7 @@ struct t1 {
unsigned long alarmtimer;
unsigned char ledstate;
unsigned char vpm_check_count;
+ struct dahdi_device *ddev;
struct dahdi_span span; /* Span */
struct dahdi_chan *chans[32]; /* Channels */
struct dahdi_echocan_state *ec[32]; /* Echocan state for channels */
diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index 0734892..39fe67c 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -871,6 +871,86 @@ err:
goto out;
}
+static int xbus_register_dahdi_device(xbus_t *xbus)
+{
+ int i;
+ int offset = 0;
+
+ XBUS_NOTICE(xbus, "Entering %s\n", __func__);
+ xbus->ddev = dahdi_create_device();
+ /*
+ * This actually describe the dahdi_spaninfo version 3
+ * A bunch of unrelated data exported via a modified ioctl()
+ * What a bummer...
+ */
+ xbus->ddev->manufacturer = "Xorcom Inc."; /* OK, that's obvious */
+ /* span->spantype = "...."; set in card_dahdi_preregistration() */
+ /*
+ * Yes, this basically duplicates information available
+ * from the description field. If some more is needed
+ * why not add it there?
+ * OK, let's add to the kernel more useless info.
+ */
+ xbus->ddev->devicetype = kasprintf(GFP_KERNEL, "Astribank2");
+ if (!xbus->ddev->devicetype)
+ return -ENOMEM;
+
+ /*
+ * location is the only usefull new data item.
+ * For our devices it was available for ages via:
+ * - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...)
+ * - The same info in "/proc/xpp/xbuses"
+ * - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute
+ * So let's also export it via the newfangled "location" field.
+ */
+ xbus->ddev->location = xbus->connector;
+
+ /*
+ * Prepare the span list
+ */
+ for (i = 0; i < MAX_XPDS; i++) {
+ xpd_t *xpd = xpd_of(xbus, i);
+ if (xpd && IS_PHONEDEV(xpd)) {
+ XPD_DBG(DEVICES, xpd, "offset=%d\n", offset);
+ xpd_dahdi_preregister(xpd, offset++);
+ }
+ }
+ if (dahdi_register_device(xbus->ddev, &xbus->astribank)) {
+ XBUS_ERR(xbus, "Failed to dahdi_register_device()\n");
+ return -ENODEV;
+ }
+ for (i = 0; i < MAX_XPDS; i++) {
+ xpd_t *xpd = xpd_of(xbus, i);
+ if (xpd && IS_PHONEDEV(xpd)) {
+ XPD_DBG(DEVICES, xpd, "\n");
+ xpd_dahdi_postregister(xpd);
+ }
+ }
+ return 0;
+}
+
+static void xbus_unregister_dahdi_device(xbus_t *xbus)
+{
+ int i;
+
+ XBUS_NOTICE(xbus, "%s\n", __func__);
+ for(i = 0; i < MAX_XPDS; i++) {
+ xpd_t *xpd = xpd_of(xbus, i);
+ xpd_dahdi_preunregister(xpd);
+ }
+ dahdi_unregister_device(xbus->ddev);
+ XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n", __func__);
+ kfree(xbus->ddev->devicetype);
+ xbus->ddev->devicetype = NULL;
+ xbus->ddev->location = NULL;
+ dahdi_free_device(xbus->ddev);
+ xbus->ddev = NULL;
+ for(i = 0; i < MAX_XPDS; i++) {
+ xpd_t *xpd = xpd_of(xbus, i);
+ xpd_dahdi_postunregister(xpd);
+ }
+}
+
/*
* This must be called from synchronous (non-interrupt) context
* it returns only when all XPD's on the bus are detected and
@@ -934,6 +1014,7 @@ void xbus_populate(void *data)
*/
xbus_request_sync(xbus, SYNC_MODE_PLL);
elect_syncer("xbus_populate(end)"); /* FIXME: try to do it later */
+ xbus_register_dahdi_device(xbus);
out:
XBUS_DBG(DEVICES, xbus, "Leaving\n");
wake_up_interruptible_all(&worker->wait_for_xpd_initialization);
@@ -1206,12 +1287,12 @@ void xbus_deactivate(xbus_t *xbus)
xbus_request_sync(xbus, SYNC_MODE_NONE); /* no more ticks */
elect_syncer("deactivate");
xbus_echocancel(xbus, 0);
- xbus_request_removal(xbus);
XBUS_DBG(DEVICES, xbus, "[%s] Waiting for queues\n", xbus->label);
xbus_command_queue_clean(xbus);
xbus_command_queue_waitempty(xbus);
xbus_setstate(xbus, XBUS_STATE_DEACTIVATED);
worker_reset(xbus);
+ xbus_unregister_dahdi_device(xbus);
xbus_release_xpds(xbus); /* taken in xpd_alloc() [kref_init] */
}
@@ -1788,10 +1869,6 @@ err:
void xbus_core_shutdown(void)
{
- int i;
-
- for(i = 0; i < MAX_BUSES; i++)
- BUG_ON(xbus_num(i));
xbus_core_cleanup();
xpp_driver_exit();
}
diff --git a/drivers/dahdi/xpp/xbus-core.h b/drivers/dahdi/xpp/xbus-core.h
index 2149a38..6f4c672 100644
--- a/drivers/dahdi/xpp/xbus-core.h
+++ b/drivers/dahdi/xpp/xbus-core.h
@@ -188,6 +188,7 @@ struct xbus {
char label[LABEL_SIZE];
byte revision; /* Protocol revision */
struct xbus_transport transport;
+ struct dahdi_device *ddev;
int num;
struct xpd *xpds[MAX_XPDS];
diff --git a/drivers/dahdi/xpp/xbus-sysfs.c b/drivers/dahdi/xpp/xbus-sysfs.c
index daf16fc..c9f78f9 100644
--- a/drivers/dahdi/xpp/xbus-sysfs.c
+++ b/drivers/dahdi/xpp/xbus-sysfs.c
@@ -623,29 +623,6 @@ static DEVICE_ATTR_READER(span_show, dev, buf)
return len;
}
-static DEVICE_ATTR_WRITER(span_store, dev, buf, count)
-{
- xpd_t *xpd;
- int dahdi_reg;
- int ret;
-
- BUG_ON(!dev);
- xpd = dev_to_xpd(dev);
- if(!xpd)
- return -ENODEV;
- ret = sscanf(buf, "%d", &dahdi_reg);
- if(ret != 1)
- return -EINVAL;
- if(!XBUS_IS(xpd->xbus, READY))
- return -ENODEV;
- XPD_DBG(GENERAL, xpd, "%s\n", (dahdi_reg) ? "register" : "unregister");
- if(dahdi_reg)
- ret = dahdi_register_xpd(xpd);
- else
- ret = dahdi_unregister_xpd(xpd);
- return (ret < 0) ? ret : count;
-}
-
static DEVICE_ATTR_READER(type_show, dev, buf)
{
xpd_t *xpd;
@@ -728,7 +705,7 @@ static int xpd_match(struct device *dev, struct device_driver *driver)
static struct device_attribute xpd_dev_attrs[] = {
__ATTR(chipregs, S_IRUGO | S_IWUSR, chipregs_show, chipregs_store),
__ATTR(blink, S_IRUGO | S_IWUSR, blink_show, blink_store),
- __ATTR(span, S_IRUGO | S_IWUSR, span_show, span_store),
+ __ATTR_RO(span),
__ATTR_RO(type),
__ATTR_RO(offhook),
__ATTR_RO(timing_priority),
diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index 0f186ef..f2c7314 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -256,8 +256,8 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
void xpd_post_init(xpd_t *xpd)
{
XPD_DBG(DEVICES, xpd, "\n");
- if(dahdi_autoreg)
- dahdi_register_xpd(xpd);
+ /* DEBUG if(dahdi_autoreg) */
+ /* DEBUG dahdi_register_xpd(xpd); */
}
#ifdef CONFIG_PROC_FS
@@ -569,53 +569,12 @@ err:
}
/*
- * Try our best to make asterisk close all channels related to
- * this Astribank:
- * - Set span state to DAHDI_ALARM_NOTOPEN in all relevant spans.
- * - Notify dahdi afterwards about spans (so it can see all changes at once).
- * - Also send DAHDI_EVENT_REMOVED on all channels.
- */
-void xbus_request_removal(xbus_t *xbus)
-{
- unsigned long flags;
- int i;
-
- for(i = 0; i < MAX_XPDS; i++) {
- xpd_t *xpd = xpd_of(xbus, i);
- if(xpd) {
- XPD_DBG(DEVICES, xpd, "\n");
- spin_lock_irqsave(&xpd->lock, flags);
- xpd->card_present = 0;
- xpd_setstate(xpd, XPD_STATE_NOHW);
- PHONEDEV(xpd).span.alarms = DAHDI_ALARM_NOTOPEN;
- spin_unlock_irqrestore(&xpd->lock, flags);
- }
- }
- /* Now notify dahdi */
- for(i = 0; i < MAX_XPDS; i++) {
- xpd_t *xpd = xpd_of(xbus, i);
- if(xpd) {
- if(SPAN_REGISTERED(xpd)) {
- int j;
-
- dahdi_alarm_notify(&PHONEDEV(xpd).span);
- XPD_DBG(DEVICES, xpd, "Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n");
- for (j=0; j<PHONEDEV(xpd).span.channels; j++) {
- dahdi_qevent_lock(XPD_CHAN(xpd, j),DAHDI_EVENT_REMOVED);
- }
- }
- }
- }
-}
-
-/*
* The xpd isn't open by anyone, we can unregister it and free it
*/
void xpd_remove(xpd_t *xpd)
{
BUG_ON(!xpd);
XPD_INFO(xpd, "Remove\n");
- dahdi_unregister_xpd(xpd);
CALL_XMETHOD(card_remove, xpd);
xpd_free(xpd);
}
@@ -992,48 +951,6 @@ int xpp_echocan_create(struct dahdi_chan *chan,
}
EXPORT_SYMBOL(xpp_echocan_create);
-
-/**
- * Unregister an xpd from dahdi and release related resources
- * @xpd The xpd to be unregistered
- * @returns 0 on success, errno otherwise
- *
- * Checks that nobody holds an open channel.
- *
- * Called by:
- * - User action through /proc
- * - During xpd_remove()
- */
-int dahdi_unregister_xpd(xpd_t *xpd)
-{
- unsigned long flags;
-
- BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
-
- if (!IS_PHONEDEV(xpd)) {
- XPD_ERR(xpd, "Not a telephony device\n");
- spin_unlock_irqrestore(&xpd->lock, flags);
- return -EBADF;
- }
- if(!SPAN_REGISTERED(xpd)) {
- XPD_NOTICE(xpd, "Already unregistered\n");
- spin_unlock_irqrestore(&xpd->lock, flags);
- return -EIDRM;
- }
- update_xpd_status(xpd, DAHDI_ALARM_NOTOPEN);
- mdelay(2); // FIXME: This is to give chance for transmit/receiveprep to finish.
- spin_unlock_irqrestore(&xpd->lock, flags);
- if(xpd->card_present)
- CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 0);
- atomic_dec(&PHONEDEV(xpd).dahdi_registered);
- atomic_dec(&num_registered_spans);
- dahdi_unregister(&PHONEDEV(xpd).span);
- if(xpd->card_present)
- CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 0);
- return 0;
-}
-
static const struct dahdi_span_ops xpp_span_ops = {
.owner = THIS_MODULE,
.open = xpp_open,
@@ -1055,12 +972,39 @@ static const struct dahdi_span_ops xpp_rbs_span_ops = {
.echocan_name = xpp_echocan_name,
};
-int dahdi_register_xpd(xpd_t *xpd)
+static void xpd_init_span(xpd_t *xpd, unsigned offset, int cn)
{
struct dahdi_span *span;
+ int i;
+
+ XPD_NOTICE(xpd, "Initializing span(offset=%d): %d channels.\n", offset, cn);
+ memset(&PHONEDEV(xpd).span, 0, sizeof(struct dahdi_span));
+ for (i = 0; i < cn; i++)
+ memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan));
+
+ span = &PHONEDEV(xpd).span;
+ snprintf(span->name, MAX_SPANNAME, "%s/%s", xpd->xbus->busname, xpd->xpdname);
+ span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */
+ span->channels = cn;
+ span->chans = PHONEDEV(xpd).chans;
+
+ span->flags = DAHDI_FLAG_RBS;
+ span->offset = offset;
+ if (PHONEDEV(xpd).phoneops->card_hooksig)
+ span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */
+ else
+ span->ops = &xpp_span_ops;
+
+ snprintf(PHONEDEV(xpd).span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s",
+ xpd->xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name);
+ list_add_tail(&span->device_node, &xpd->xbus->ddev->spans);
+}
+
+int xpd_dahdi_preregister(xpd_t *xpd, unsigned offset)
+{
xbus_t *xbus;
int cn;
- int i;
+ struct phonedev *phonedev;
BUG_ON(!xpd);
@@ -1070,70 +1014,25 @@ int dahdi_register_xpd(xpd_t *xpd)
XPD_ERR(xpd, "Not a telephony device\n");
return -EBADF;
}
+
+ phonedev = &PHONEDEV(xpd);
+
if (SPAN_REGISTERED(xpd)) {
XPD_ERR(xpd, "Already registered\n");
return -EEXIST;
}
- cn = PHONEDEV(xpd).channels;
- XPD_DBG(DEVICES, xpd, "Initializing span: %d channels.\n", cn);
- memset(&PHONEDEV(xpd).span, 0, sizeof(struct dahdi_span));
- for(i = 0; i < cn; i++) {
- memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan));
- }
- span = &PHONEDEV(xpd).span;
- snprintf(span->name, MAX_SPANNAME, "%s/%s", xbus->busname, xpd->xpdname);
- span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */
- span->channels = cn;
- span->chans = PHONEDEV(xpd).chans;
-
- span->flags = DAHDI_FLAG_RBS;
- if(PHONEDEV(xpd).phoneops->card_hooksig)
- span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */
- else
- span->ops = &xpp_span_ops;
-
- /*
- * This actually describe the dahdi_spaninfo version 3
- * A bunch of unrelated data exported via a modified ioctl()
- * What a bummer...
- */
- span->manufacturer = "Xorcom Inc."; /* OK, that's obvious */
- /* span->spantype = "...."; set in card_dahdi_preregistration() */
- /*
- * Yes, this basically duplicates information available
- * from the description field. If some more is needed
- * why not add it there?
- * OK, let's add to the kernel more useless info.
- */
- snprintf(span->devicetype, sizeof(span->devicetype) - 1,
- "Astribank: Unit %x Subunit %x: %s",
- XBUS_UNIT(xpd->xbus_idx), XBUS_SUBUNIT(xpd->xbus_idx),
- xpd->type_name);
- /*
- * location is the only usefull new data item.
- * For our devices it was available for ages via:
- * - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...)
- * - The same info in "/proc/xpp/xbuses"
- * - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute
- * So let's also export it via the newfangled "location" field.
- */
- snprintf(span->location, sizeof(span->location) - 1, "%s", xbus->connector);
- /*
- * Who said a span and irq have 1-1 relationship?
- * Also exporting this low-level detail isn't too wise.
- * No irq's for you today!
- */
- span->irq = 0;
-
- snprintf(PHONEDEV(xpd).span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s",
- xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name);
+ cn = PHONEDEV(xpd).channels;
+ xpd_init_span(xpd, offset, cn);
XPD_DBG(GENERAL, xpd, "Registering span '%s'\n", PHONEDEV(xpd).span.desc);
CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 1);
- if(dahdi_register(&PHONEDEV(xpd).span, prefmaster)) {
- XPD_ERR(xpd, "Failed to dahdi_register span\n");
- return -ENODEV;
- }
+ return 0;
+}
+
+int xpd_dahdi_postregister(xpd_t *xpd)
+{
+ int cn;
+
atomic_inc(&num_registered_spans);
atomic_inc(&PHONEDEV(xpd).dahdi_registered);
CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 1);
@@ -1153,6 +1052,48 @@ int dahdi_register_xpd(xpd_t *xpd)
return 0;
}
+/*
+ * Try our best to make asterisk close all channels related to
+ * this Astribank:
+ * - Set span state to DAHDI_ALARM_NOTOPEN in all relevant spans.
+ * - Notify dahdi afterwards about spans (so it can see all changes at once).
+ * - Also send DAHDI_EVENT_REMOVED on all channels.
+ */
+void xpd_dahdi_preunregister(xpd_t *xpd)
+{
+ unsigned long flags;
+ if (!xpd)
+ return;
+ XPD_DBG(DEVICES, xpd, "\n");
+ spin_lock_irqsave(&xpd->lock, flags);
+ xpd->card_present = 0;
+ xpd_setstate(xpd, XPD_STATE_NOHW);
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ update_xpd_status(xpd, DAHDI_ALARM_NOTOPEN);
+ if(xpd->card_present)
+ CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 0);
+ /* Now notify dahdi */
+ if(SPAN_REGISTERED(xpd)) {
+ int j;
+
+ dahdi_alarm_notify(&PHONEDEV(xpd).span);
+ XPD_DBG(DEVICES, xpd, "Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n");
+ for (j=0; j<PHONEDEV(xpd).span.channels; j++) {
+ dahdi_qevent_lock(XPD_CHAN(xpd, j),DAHDI_EVENT_REMOVED);
+ }
+ }
+}
+
+void xpd_dahdi_postunregister(xpd_t *xpd)
+{
+ if (!xpd)
+ return;
+ atomic_dec(&PHONEDEV(xpd).dahdi_registered);
+ atomic_dec(&num_registered_spans);
+ if(xpd->card_present)
+ CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 0);
+}
+
/*------------------------- Initialization -------------------------*/
static void do_cleanup(void)
@@ -1217,7 +1158,6 @@ EXPORT_SYMBOL(get_xpd);
EXPORT_SYMBOL(put_xpd);
EXPORT_SYMBOL(xpd_alloc);
EXPORT_SYMBOL(xpd_free);
-EXPORT_SYMBOL(xbus_request_removal);
EXPORT_SYMBOL(update_xpd_status);
EXPORT_SYMBOL(oht_pcm);
EXPORT_SYMBOL(mark_offhook);
diff --git a/drivers/dahdi/xpp/xpp_dahdi.h b/drivers/dahdi/xpp/xpp_dahdi.h
index 01f4a24..cb76846 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.h
+++ b/drivers/dahdi/xpp/xpp_dahdi.h
@@ -25,9 +25,10 @@
#include "xpd.h"
#include "xproto.h"
-int dahdi_register_xpd(xpd_t *xpd);
-int dahdi_unregister_xpd(xpd_t *xpd);
-void xbus_request_removal(xbus_t *xbus);
+int xpd_dahdi_preregister(xpd_t *xpd, unsigned offset);
+int xpd_dahdi_postregister(xpd_t *xpd);
+void xpd_dahdi_preunregister(xpd_t *xpd);
+void xpd_dahdi_postunregister(xpd_t *xpd);
int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
int unit, int subunit, byte type, byte subtype, int subunits, int subunit_ports, byte port_dir);
void xpd_post_init(xpd_t *xpd);
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index 9ae9d1e..9dec702 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -42,7 +42,7 @@
#include <linux/config.h>
#endif
#include <linux/fs.h>
-#include <linux/kobject.h>
+#include <linux/device.h>
#include <linux/ioctl.h>
#ifdef CONFIG_DAHDI_NET
@@ -885,6 +885,26 @@ struct dahdi_span_ops {
/*! Opt: Provide the name of the echo canceller on a channel */
const char *(*echocan_name)(const struct dahdi_chan *chan);
+
+ /*! When using "pinned_spans", this function is called back when this
+ * span has been assigned with the system. */
+ void (*assigned)(struct dahdi_span *span);
+};
+
+/**
+ * dahdi_device - Represents a device that can contain one or more spans.
+ *
+ * @spans: List of child spans.
+ * @manufacturer: Device manufacturer.
+ * @location: The location of this device
+ * @devicetype: What type of device this is.
+ *
+ */
+struct dahdi_device {
+ struct list_head spans;
+ const char *manufacturer;
+ const char *location;
+ const char *devicetype;
};
struct dahdi_span {
@@ -892,9 +912,6 @@ struct dahdi_span {
char name[40]; /*!< Span name */
char desc[80]; /*!< Span description */
const char *spantype; /*!< span type in text form */
- const char *manufacturer; /*!< span's device manufacturer */
- char devicetype[80]; /*!< span's device type */
- char location[40]; /*!< span device's location in system */
int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
int alarms; /*!< Pending alarms on span */
unsigned long flags;
@@ -933,7 +950,10 @@ struct dahdi_span {
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
#endif
- struct list_head node;
+ struct list_head spans_node;
+
+ struct dahdi_device *parent;
+ struct list_head device_node;
};
struct dahdi_transcoder_channel {
@@ -1031,6 +1051,7 @@ struct dahdi_dynamic {
long rxjif;
unsigned short txcnt;
unsigned short rxcnt;
+ struct dahdi_device *ddev;
struct dahdi_span span;
struct dahdi_chan *chans[256];
struct dahdi_dynamic_driver *driver;
@@ -1038,6 +1059,7 @@ struct dahdi_dynamic {
int timing;
int master;
unsigned char *msgbuf;
+ struct device *dev;
struct list_head list;
};
@@ -1131,10 +1153,11 @@ void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int bytes);
* and 1 if the currently transmitted message is now done */
int dahdi_hdlc_getbuf(struct dahdi_chan *ss, unsigned char *bufptr, unsigned int *size);
-
-/*! Register a span. Returns 0 on success, -1 on failure. Pref-master is non-zero if
- we should have preference in being the master device */
-int dahdi_register(struct dahdi_span *span, int prefmaster);
+/*! Register a device. Returns 0 on success, -1 on failure. */
+struct dahdi_device *dahdi_create_device(void);
+int dahdi_register_device(struct dahdi_device *ddev, struct device *parent);
+void dahdi_unregister_device(struct dahdi_device *ddev);
+void dahdi_free_device(struct dahdi_device *ddev);
/*! Allocate / free memory for a transcoder */
struct dahdi_transcoder *dahdi_transcoder_alloc(int numchans);
@@ -1149,9 +1172,6 @@ int dahdi_transcoder_unregister(struct dahdi_transcoder *tc);
/*! \brief Alert a transcoder */
int dahdi_transcoder_alert(struct dahdi_transcoder_channel *ztc);
-/*! \brief Unregister a span */
-int dahdi_unregister(struct dahdi_span *span);
-
/*! \brief Gives a name to an LBO */
const char *dahdi_lboname(int lbo);