From 7f136e308d607a9b3e1d82137dbdee0b36c90de7 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Wed, 26 Oct 2011 19:01:19 +0000 Subject: dahdi: Allow 'spantype' to be changed before span assignement via sysfs. For some boards, the linemode (E1/T1/J1) is software selectable but needs to be configured before the spans were historically registered since the line mode determines the channel count available on the span. This change exports a "spantype" attribute from the dahdi_device that can be used to set E1/T1/J1 before the spans are assigned. When userspace writes to this attribute (in a : format), and if the board driver has implemented a set_spantype function in it's dahdi_span_ops, then the board driver can optionally change it's mode before registration. Also part of this change is breaking out the raw data structure initialization of the spans / channels via the dahdi_init_device_spans function since the board drivers may need to reallocate channels / spans as part of this callback. For example, changing from T1 to E1 mode will require allocating 7 new channels. Signed-off-by: Shaun Ruffell git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10277 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/dahdi-sysfs.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'drivers/dahdi/dahdi-sysfs.c') diff --git a/drivers/dahdi/dahdi-sysfs.c b/drivers/dahdi/dahdi-sysfs.c index 20c83dd..5dcd6b8 100644 --- a/drivers/dahdi/dahdi-sysfs.c +++ b/drivers/dahdi/dahdi-sysfs.c @@ -624,6 +624,75 @@ dahdi_device_unassign_span(struct device *dev, struct device_attribute *attr, return (ret < 0) ? ret : count; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) +static ssize_t dahdi_spantype_show(struct device *dev, char *buf) +#else +static ssize_t +dahdi_spantype_show(struct device *dev, + struct device_attribute *attr, char *buf) +#endif +{ + struct dahdi_device *ddev = to_ddev(dev); + int count = 0; + ssize_t total = 0; + struct dahdi_span *span; + + /* TODO: Make sure this doesn't overflow the page. */ + list_for_each_entry(span, &ddev->spans, device_node) { + count = sprintf(buf, "%d:%s\n", local_spanno(span), span->spantype); + buf += count; + total += count; + } + + return total; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) +static ssize_t +dahdi_spantype_store(struct device *dev, const char *buf, size_t count) +#else +static ssize_t +dahdi_spantype_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +#endif +{ + struct dahdi_device *const ddev = to_ddev(dev); + int ret; + struct dahdi_span *span; + unsigned int local_span_number; + char desired_spantype[80]; + + ret = sscanf(buf, "%u:%70s", &local_span_number, desired_spantype); + if (ret != 2) + return -EINVAL; + + list_for_each_entry(span, &ddev->spans, device_node) { + if (local_spanno(span) == local_span_number) + break; + } + + if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) { + module_printk(KERN_WARNING, "Span %s is already assigned.\n", + span->name); + return -EINVAL; + } + + if (local_spanno(span) != local_span_number) { + module_printk(KERN_WARNING, "%d is not a valid local span number " + "for this device.\n", local_span_number); + return -EINVAL; + } + + if (!span->ops->set_spantype) { + module_printk(KERN_WARNING, "Span %s does not support " + "setting type.\n", span->name); + return -EINVAL; + } + + ret = span->ops->set_spantype(span, &desired_spantype[0]); + return (ret < 0) ? ret : count; +} + static struct device_attribute dahdi_device_attrs[] = { __ATTR(manufacturer, S_IRUGO, dahdi_device_manufacturer_show, NULL), __ATTR(type, S_IRUGO, dahdi_device_type_show, NULL), @@ -632,6 +701,8 @@ static struct device_attribute dahdi_device_attrs[] = { __ATTR(auto_assign, S_IWUSR, NULL, dahdi_device_auto_assign), __ATTR(assign_span, S_IWUSR, NULL, dahdi_device_assign_span), __ATTR(unassign_span, S_IWUSR, NULL, dahdi_device_unassign_span), + __ATTR(spantype, S_IWUSR | S_IRUGO, dahdi_spantype_show, + dahdi_spantype_store), __ATTR_NULL, }; -- cgit v1.2.3