diff options
author | Shaun Ruffell <sruffell@digium.com> | 2010-11-17 12:09:10 -0600 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2011-04-15 14:21:13 -0500 |
commit | b3c86b81ae638d90ee27a821e962e297ab85cbe4 (patch) | |
tree | c70e2c6b0e74c5bc3a20e6c597df1f9fbc7ca891 /drivers | |
parent | 9c8aa9db7eca1c91bd37bd5b55add0cee40d7cd9 (diff) |
dahdi: register/unregister devices as opposed to 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 also 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.
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dahdi/dahdi-base.c | 224 | ||||
-rw-r--r-- | drivers/dahdi/dahdi_dynamic.c | 10 | ||||
-rw-r--r-- | drivers/dahdi/pciradio.c | 7 | ||||
-rw-r--r-- | drivers/dahdi/tor2.c | 42 | ||||
-rw-r--r-- | drivers/dahdi/voicebus/voicebus.c | 2 | ||||
-rw-r--r-- | drivers/dahdi/wcb4xxp/base.c | 44 | ||||
-rw-r--r-- | drivers/dahdi/wcb4xxp/wcb4xxp.h | 1 | ||||
-rw-r--r-- | drivers/dahdi/wcfxo.c | 26 | ||||
-rw-r--r-- | drivers/dahdi/wct1xxp.c | 22 | ||||
-rw-r--r-- | drivers/dahdi/wct4xxp/base.c | 115 | ||||
-rw-r--r-- | drivers/dahdi/wctdm.c | 29 | ||||
-rw-r--r-- | drivers/dahdi/wctdm24xxp/base.c | 89 | ||||
-rw-r--r-- | drivers/dahdi/wctdm24xxp/wctdm24xxp.h | 1 | ||||
-rw-r--r-- | drivers/dahdi/wcte11xp.c | 23 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/base.c | 52 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/wcte12xp.h | 1 | ||||
-rw-r--r-- | drivers/dahdi/xpp/card_pri.c | 2 | ||||
-rw-r--r-- | drivers/dahdi/xpp/xpd.h | 1 | ||||
-rw-r--r-- | drivers/dahdi/xpp/xpp_dahdi.c | 25 |
19 files changed, 477 insertions, 239 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 029c928..789b2af 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 @@ -423,7 +421,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]; @@ -463,7 +461,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; @@ -512,7 +510,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; } @@ -550,7 +548,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; @@ -2924,6 +2922,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; @@ -2975,8 +2983,6 @@ static struct dahdi_chan *dahdi_alloc_pseudo(struct file *file) list_add(&pseudo->node, pos); spin_unlock_irqrestore(&chan_lock, flags); - mutex_unlock(®istration_mutex); - return &pseudo->chan; } @@ -3038,7 +3044,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(®istration_mutex); chan = dahdi_alloc_pseudo(file); + mutex_unlock(®istration_mutex); if (unlikely(!chan)) return -ENOMEM; return dahdi_specchan_open(file); @@ -3602,7 +3610,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 (!is_analog_span(s) && @@ -4156,16 +4164,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)); @@ -4243,21 +4253,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, @@ -5215,7 +5222,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]; @@ -6411,9 +6418,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; @@ -6437,10 +6444,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) || @@ -6459,13 +6466,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. * - * NOTE: Must be called with the registration_mutex held. + * 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 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; @@ -6483,7 +6516,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. @@ -6529,9 +6562,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(); @@ -6556,8 +6589,62 @@ cleanup: return res; } +static const char *UNKNOWN = ""; + /** - * dahdi_register() - unregister a new DAHDI span + * _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(®istration_mutex); + ret = _dahdi_register_device(ddev, parent); + mutex_unlock(®istration_mutex); + + return ret; +} +EXPORT_SYMBOL(dahdi_register_device); + +/** + * dahdi_unregister_span() - unregister a DAHDI span * @span: the DAHDI span * @prefmaster: will the new span be preferred as a master? * @@ -6569,17 +6656,13 @@ cleanup: * master if no other span is currently the master (i.e.: it is the * first one). * + * Unregisters a span that has been previously registered with + * dahdi_register_span(). + * + * Must be called with the registration_mutex held. + * */ -int dahdi_register(struct dahdi_span *span, int prefmaster) -{ - int ret; - mutex_lock(®istration_mutex); - ret = _dahdi_register(span, prefmaster); - mutex_unlock(®istration_mutex); - return ret; -} - -static int _dahdi_unregister(struct dahdi_span *span) +static int dahdi_unregister_span(struct dahdi_span *span) { int x; struct dahdi_span *new_master, *s; @@ -6591,7 +6674,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); @@ -6616,7 +6699,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; @@ -6634,20 +6717,34 @@ static int _dahdi_unregister(struct dahdi_span *span) } /** - * 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(®istration_mutex); - ret = _dahdi_unregister(span); + list_for_each_entry(s, &ddev->spans, device_node) + dahdi_unregister_span(s); mutex_unlock(®istration_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 @@ -8943,7 +9040,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) @@ -8972,7 +9069,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) @@ -9240,6 +9337,11 @@ module_param(deftaps, int, 0644); module_param(max_pseudo_channels, int, 0644); MODULE_PARM_DESC(max_pseudo_channels, "Maximum number of pseudo channels."); +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, @@ -9282,7 +9384,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 942329a..5578532 100644 --- a/drivers/dahdi/dahdi_dynamic.c +++ b/drivers/dahdi/dahdi_dynamic.c @@ -404,6 +404,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); } @@ -473,7 +474,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); @@ -581,8 +582,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); @@ -660,8 +661,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); @@ -772,7 +774,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 1babb4f..32e8435 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 */ @@ -283,10 +284,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; @@ -320,19 +317,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 */ @@ -340,14 +349,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) @@ -363,6 +364,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); } @@ -629,7 +632,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) @@ -639,11 +641,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 4efd2f9..5e1c6e0 100644 --- a/drivers/dahdi/voicebus/voicebus.c +++ b/drivers/dahdi/voicebus/voicebus.c @@ -2026,7 +2026,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 a0b9393..581c486 100644 --- a/drivers/dahdi/wcb4xxp/base.c +++ b/drivers/dahdi/wcb4xxp/base.c @@ -2493,11 +2493,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 28c86a8..373caa5 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"); } @@ -767,13 +769,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; @@ -798,7 +807,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 97a1f3c..b4a4206 100644 --- a/drivers/dahdi/wct4xxp/base.c +++ b/drivers/dahdi/wct4xxp/base.c @@ -43,6 +43,8 @@ #include <dahdi/kernel.h> +#include <stdbool.h> + #include "wct4xxp.h" #include "vpm450m.h" @@ -339,6 +341,7 @@ struct t4 { int t1e1; /* T1/E1 select pins */ int globalconfig; /* Whether global setup has been done */ 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; @@ -2015,23 +2018,27 @@ static int t4_close(struct dahdi_chan *chan) return 0; } -static void set_span_devicetype(struct t4 *wc) +static int set_span_devicetype(struct t4 *wc) { - int x; - struct t4_span *ts; + const char *vpmstring; - for (x = 0; x < wc->numspans; x++) { - ts = wc->tspans[x]; - strlcpy(ts->span.devicetype, wc->variety, - sizeof(ts->span.devicetype)); - if (wc->vpm == T4_VPM_PRESENT) { - if (!wc->vpm450m) - strncat(ts->span.devicetype, " (VPM400M)", sizeof(ts->span.devicetype) - 1); - else - strncat(ts->span.devicetype, (wc->numspans > 2) ? " (VPMOCT128)" : " (VPMOCT064)", - sizeof(ts->span.devicetype) - 1); - } + if (wc->vpm == T4_VPM_PRESENT) { + if (!wc->vpm450m) + vpmstring = "400M"; + else if (wc->numspans > 2) + vpmstring = "OCT128"; + else + vpmstring = "OCT064"; + + wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s (VPM%s)", + wc->variety, vpmstring); + } else { + wc->ddev->devicetype = kasprintf(GFP_KERNEL, wc->variety); } + + if (!wc->ddev->devicetype) + return -ENOMEM; + return 0; } /* The number of cards we have seen with each @@ -2111,13 +2118,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 (order_index[wc->order] == 1) - 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->spantype) { case TYPE_T1: ts->span.spantype = "T1"; @@ -4579,9 +4579,12 @@ 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; + dev_info(&wc->dev->dev, "TE%dXXP: Launching card: %d\n", wc->numspans, wc->order); @@ -4589,35 +4592,33 @@ static int __devinit t4_launch(struct t4 *wc) for (x=0;x<PORTS_PER_FRAMER;x++) t4_serial_setup(wc, x); - 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 (order_index[wc->order] == 1) { + 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); @@ -4644,6 +4645,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); } @@ -4658,11 +4663,11 @@ 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; - } - memset(wc, 0x0, sizeof(*wc)); + wc->ddev = dahdi_create_device(); spin_lock_init(&wc->reglock); dt = (struct devtype *) (ent->driver_data); @@ -4884,9 +4889,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); @@ -4903,11 +4911,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 9c56865..143af0a 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; @@ -2367,10 +2368,16 @@ static int wctdm_initialize(struct wctdm *wc) /* 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) + 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; @@ -2390,7 +2397,9 @@ 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)) { + wc->ddev = dahdi_create_device(); + 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; } @@ -2679,7 +2688,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; @@ -2710,10 +2721,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 a50f67a..e4587eb 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -4147,6 +4147,30 @@ static int wctdm_dacs(struct dahdi_chan *dst, struct dahdi_chan *src) return 0; } +/** + * TODO: Add comment about this function. + * + */ +static void wctdm24xxp_registered(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)) { + dev_err(&wc->vb.pdev->dev, "HERE: %d\n", __LINE__); + return; + } + } + + if (wc) + wc->initialized = 1; + + dev_err(&wc->vb.pdev->dev, "HERE: %s %d\n", wc->board_name, __LINE__); +} + static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = { .owner = THIS_MODULE, .hooksig = wctdm_hooksig, @@ -4155,6 +4179,7 @@ static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = { .ioctl = wctdm_ioctl, .watchdog = wctdm_watchdog, .dacs = wctdm_dacs, + .registered = wctdm24xxp_registered, #ifdef VPM_SUPPORT .echocan_create = wctdm_echocan_create, .echocan_name = wctdm_echocan_name, @@ -4171,6 +4196,7 @@ static const struct dahdi_span_ops wctdm24xxp_digital_span_ops = { .spanconfig = b400m_spanconfig, .chanconfig = b400m_chanconfig, .dacs = wctdm_dacs, + .registered = wctdm24xxp_registered, #ifdef VPM_SUPPORT .echocan_create = wctdm_echocan_create, .echocan_name = wctdm_echocan_name, @@ -4255,12 +4281,6 @@ wctdm_init_span(struct wctdm *wc, int spanno, int chanoffset, int chancount, snprintf(s->span.desc, sizeof(s->span.desc) - 1, "%s Board %d", wc->desc->name, card_position + 1); - 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"; - strncpy(s->span.devicetype, wc->desc->name, sizeof(s->span.devicetype) - 1); if (wc->companding == DAHDI_LAW_DEFAULT) { if (wc->digi_mods || digital_span) @@ -4370,8 +4390,6 @@ static void wctdm_fixup_analog_span(struct wctdm *wc, int spanno) for (x = 0; x < MAX_SPANS; x++) { if (!wc->spans[x]) continue; - if (wc->vpmadt032) - strncat(wc->spans[x]->span.devicetype, " (VPMADT032)", sizeof(wc->spans[x]->span.devicetype) - 1); } } @@ -4692,9 +4710,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); } @@ -5476,21 +5495,48 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #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 { + 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); } - wc->initialized = 1; + 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", @@ -5542,12 +5588,7 @@ static void wctdm_release(struct wctdm *wc) { int i; - if (wc->initialized) { - for (i = 0; i < MAX_SPANS; i++) { - if (wc->spans[i]) - dahdi_unregister(&wc->spans[i]->span); - } - } + 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 21235f5..2fbcd79 100644 --- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h +++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h @@ -304,6 +304,7 @@ struct wctdm { int initialized; /* =1 when the entire card is ready to go */ unsigned long checkflag; /* Internal state flags and task bits */ int companding; + struct dahdi_device *ddev; }; /* Atomic flag bits for checkflag field */ diff --git a/drivers/dahdi/wcte11xp.c b/drivers/dahdi/wcte11xp.c index a0dbc79..bdf76c1 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"); } @@ -973,14 +976,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) @@ -1008,7 +1018,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 a65b279..037fc9d 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -705,6 +705,9 @@ static void free_wc(struct t1 *wc) } #endif + kfree(wc->ddev->location); + kfree(wc->ddev->devicetype); + dahdi_free_device(wc->ddev); kfree(wc); } @@ -919,14 +922,23 @@ 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; #if defined(VPM_SUPPORT) - if (wc->vpmadt032) - strncat(wc->span.devicetype, " (VPMADT032)", - sizeof(wc->span.devicetype) - 1); + bool have_vpm = (wc->vpmadt032) ? true : false; +#else + bool have_vpm = false; #endif + olddevicetype = wc->ddev->devicetype; + + wc->ddev->devicetype = kasprintf(GFP_KERNEL, + (have_vpm) ? "%s (VPMADT032)" : "%s", + wc->variety); + + /* 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 dahdi_span *span) @@ -1529,6 +1541,7 @@ static const struct dahdi_span_ops t1_span_ops = { static int t1_software_init(struct t1 *wc) { int x; + int res; int num; struct pci_dev *pdev = wc->vb.pdev; @@ -1548,12 +1561,15 @@ static int t1_software_init(struct t1 *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; @@ -1579,9 +1595,11 @@ static int t1_software_init(struct t1 *wc) wc->chans[x]->chanpos = x + 1; } 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; } set_bit(INITIALIZED, &wc->bit_flags); @@ -2256,13 +2274,13 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi return -EIO; } - if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) { + wc = kzalloc(sizeof(*wc), GFP_KERNEL); + if (!wc) return -ENOMEM; - } ifaces[index] = wc; - memset(wc, 0, sizeof(*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); @@ -2375,7 +2393,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 5f6dbce..e2d5a6b 100644 --- a/drivers/dahdi/wcte12xp/wcte12xp.h +++ b/drivers/dahdi/wcte12xp/wcte12xp.h @@ -114,6 +114,7 @@ struct t1 { unsigned long bit_flags; unsigned long alarmtimer; unsigned char ledstate; + 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/card_pri.c b/drivers/dahdi/xpp/card_pri.c index c283cbe..6780621 100644 --- a/drivers/dahdi/xpp/card_pri.c +++ b/drivers/dahdi/xpp/card_pri.c @@ -1855,7 +1855,7 @@ static void PRI_card_pcm_tospan(xpd_t *xpd, xpacket_t *pack) spin_unlock_irqrestore(&xpd->lock, flags); } -int PRI_timing_priority(xpd_t *xpd) +static int PRI_timing_priority(xpd_t *xpd) { struct PRI_priv_data *priv; diff --git a/drivers/dahdi/xpp/xpd.h b/drivers/dahdi/xpp/xpd.h index 2d4b6eb..66ba88c 100644 --- a/drivers/dahdi/xpp/xpd.h +++ b/drivers/dahdi/xpp/xpd.h @@ -154,6 +154,7 @@ const char *xpd_statename(enum xpd_state st); struct phonedev { const struct phoneops *phoneops; /* Card level operations */ + struct dahdi_device *ddev; struct dahdi_span span; struct dahdi_chan *chans[32]; #define XPD_CHAN(xpd,chan) (PHONEDEV(xpd).chans[(chan)]) diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c index 5a27f45..99fb62d 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.c +++ b/drivers/dahdi/xpp/xpp_dahdi.c @@ -513,6 +513,7 @@ static void phonedev_cleanup(xpd_t *xpd) KZFREE(phonedev->chans[x]); } } + dahdi_free_device(phonedev->ddev); } __must_check static int phonedev_init(xpd_t *xpd, const xproto_table_t *proto_table, @@ -1086,7 +1087,7 @@ int dahdi_unregister_xpd(xpd_t *xpd) CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 0); atomic_dec(&PHONEDEV(xpd).dahdi_registered); atomic_dec(&num_registered_spans); - dahdi_unregister(&PHONEDEV(xpd).span); + dahdi_unregister_device(PHONEDEV(xpd).ddev); if(xpd->card_present) CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 0); return 0; @@ -1115,6 +1116,7 @@ int dahdi_register_xpd(xpd_t *xpd) xbus_t *xbus; int cn; int i; + struct phonedev *phonedev; BUG_ON(!xpd); @@ -1124,10 +1126,16 @@ 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; } + + phonedev->ddev = dahdi_create_device(); + cn = PHONEDEV(xpd).channels; XPD_DBG(DEVICES, xpd, "Initializing span: %d channels.\n", cn); memset(&PHONEDEV(xpd).span, 0, sizeof(struct dahdi_span)); @@ -1152,7 +1160,7 @@ int dahdi_register_xpd(xpd_t *xpd) * A bunch of unrelated data exported via a modified ioctl() * What a bummer... */ - span->manufacturer = "Xorcom Inc."; /* OK, that's obvious */ + phonedev->ddev->manufacturer = "Xorcom Inc."; /* OK, that's obvious */ /* span->spantype = "...."; set in card_dahdi_preregistration() */ /* * Yes, this basically duplicates information available @@ -1160,10 +1168,14 @@ int dahdi_register_xpd(xpd_t *xpd) * why not add it there? * OK, let's add to the kernel more useless info. */ - snprintf(span->devicetype, sizeof(span->devicetype) - 1, + phonedev->ddev->devicetype = kasprintf(GFP_KERNEL, "Astribank: Unit %x Subunit %x: %s", XBUS_UNIT(xpd->xbus_idx), XBUS_SUBUNIT(xpd->xbus_idx), xpd->type_name); + + if (!phonedev->ddev->devicetype) + return -ENOMEM; + /* * location is the only usefull new data item. * For our devices it was available for ages via: @@ -1172,7 +1184,8 @@ int dahdi_register_xpd(xpd_t *xpd) * - 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); + phonedev->ddev->location = xbus->connector; + /* * Who said a span and irq have 1-1 relationship? * Also exporting this low-level detail isn't too wise. @@ -1184,7 +1197,9 @@ int dahdi_register_xpd(xpd_t *xpd) xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name); 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)) { + list_add_tail(&span->device_node, &phonedev->ddev->spans); + + if (dahdi_register_device(phonedev->ddev, &xpd->xpd_dev)) { XPD_ERR(xpd, "Failed to dahdi_register span\n"); return -ENODEV; } |