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 <span offset>:<span type string> 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 <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10277 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
8d23f878d4
commit
f9c52bb271
@ -624,6 +624,75 @@ dahdi_device_unassign_span(struct device *dev, struct device_attribute *attr,
|
|||||||
return (ret < 0) ? ret : count;
|
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[] = {
|
static struct device_attribute dahdi_device_attrs[] = {
|
||||||
__ATTR(manufacturer, S_IRUGO, dahdi_device_manufacturer_show, NULL),
|
__ATTR(manufacturer, S_IRUGO, dahdi_device_manufacturer_show, NULL),
|
||||||
__ATTR(type, S_IRUGO, dahdi_device_type_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(auto_assign, S_IWUSR, NULL, dahdi_device_auto_assign),
|
||||||
__ATTR(assign_span, S_IWUSR, NULL, dahdi_device_assign_span),
|
__ATTR(assign_span, S_IWUSR, NULL, dahdi_device_assign_span),
|
||||||
__ATTR(unassign_span, S_IWUSR, NULL, dahdi_device_unassign_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,
|
__ATTR_NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -891,6 +891,10 @@ struct dahdi_span_ops {
|
|||||||
/*! When using "pinned_spans", this function is called back when this
|
/*! When using "pinned_spans", this function is called back when this
|
||||||
* span has been assigned with the system. */
|
* span has been assigned with the system. */
|
||||||
void (*assigned)(struct dahdi_span *span);
|
void (*assigned)(struct dahdi_span *span);
|
||||||
|
|
||||||
|
/*! Called when the spantype / linemode is changed before the span is
|
||||||
|
* assigned a number. */
|
||||||
|
int (*set_spantype)(struct dahdi_span *span, const char *spantype);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user