diff options
Diffstat (limited to 'zaptel.c')
-rw-r--r-- | zaptel.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -1154,8 +1154,21 @@ static int set_tone_zone(struct zt_chan *chan, int zone) /* Assumes channel is already locked */ if ((zone >= ZT_TONE_ZONE_MAX) || (zone < -1)) return -EINVAL; - + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) + /* Since this routine is called both from IRQ as well as from userspace, + * it is possible that we could be called during an IRQ while userspace + * has locked this. However unlikely, this could possibly cause a + * deadlock. */ + if (! read_trylock(&zone_lock)) + return -EWOULDBLOCK; +#else + /* But there are no trylock macros for kernel versions before 2.6.11, + * so we do the unsafe thing anyway. Such is the problem for dealing + * with old, buggy kernels. */ read_lock(&zone_lock); +#endif + if (zone == -1) { zone = default_zone; } @@ -1166,7 +1179,7 @@ static int set_tone_zone(struct zt_chan *chan, int zone) } else { res = -ENODATA; } - + read_unlock(&zone_lock); return res; } |