summaryrefslogtreecommitdiff
path: root/kernel/zaptel-base.c
diff options
context:
space:
mode:
authorsruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-02-27 18:30:56 +0000
committersruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-02-27 18:30:56 +0000
commit48867670d7a7c455116edb347e479401f09a86ce (patch)
tree4cfacd17b3cc4ebb633d8cd3d0e5fb28e2c96f67 /kernel/zaptel-base.c
parenteae970701c17ffef2f536f7c5f500a7e462f1828 (diff)
Set the default tone zone to to the first loaded zone by default.
Should prevent the crash reported in issue 0012053. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3885 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/zaptel-base.c')
-rw-r--r--kernel/zaptel-base.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/kernel/zaptel-base.c b/kernel/zaptel-base.c
index 4aa2161..fbcc0c5 100644
--- a/kernel/zaptel-base.c
+++ b/kernel/zaptel-base.c
@@ -2590,6 +2590,23 @@ static ssize_t zt_write(struct file *file, const char *usrbuf, size_t count, lof
}
+static int zt_set_default_zone(int defzone)
+{
+ if ((defzone < 0) || (defzone >= ZT_TONE_ZONE_MAX))
+ return -EINVAL;
+ write_lock(&zone_lock);
+ if (!tone_zones[defzone]) {
+ write_unlock(&zone_lock);
+ return -EINVAL;
+ }
+ if ((default_zone != -1) && tone_zones[default_zone])
+ atomic_dec(&tone_zones[default_zone]->refcount);
+ atomic_inc(&tone_zones[defzone]->refcount);
+ default_zone = defzone;
+ write_unlock(&zone_lock);
+ return 0;
+}
+
/* No bigger than 32k for everything per tone zone */
#define MAX_SIZE 32768
/* No more than 128 subtones */
@@ -2737,8 +2754,13 @@ static int ioctl_load_zone(unsigned long data)
samples[x]->next = samples[next[x]];
}
- if ((res = zt_register_tone_zone(th.zone, z)))
+ if ((res = zt_register_tone_zone(th.zone, z))) {
kfree(slab);
+ } else {
+ if ( -1 == default_zone ) {
+ zt_set_default_zone(th.zone);
+ }
+ }
return res;
}
@@ -3664,19 +3686,7 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case ZT_DEFAULTZONE:
if (get_user(j,(int *)data))
return -EFAULT;
- if ((j < 0) || (j >= ZT_TONE_ZONE_MAX))
- return -EINVAL;
- write_lock(&zone_lock);
- if (!tone_zones[j]) {
- write_unlock(&zone_lock);
- return -EINVAL;
- }
- if ((default_zone != -1) && tone_zones[default_zone])
- atomic_dec(&tone_zones[default_zone]->refcount);
- atomic_inc(&tone_zones[j]->refcount);
- default_zone = j;
- write_unlock(&zone_lock);
- break;
+ return zt_set_default_zone(j);
case ZT_LOADZONE:
return ioctl_load_zone(data);
case ZT_FREEZONE: