[dahdi-commits] tzafrir: linux/trunk r10285 - /linux/trunk/drivers/dahdi/dahdi-base.c
SVN commits to the DAHDI project
dahdi-commits at lists.digium.com
Wed Oct 26 14:08:02 CDT 2011
Author: tzafrir
Date: Wed Oct 26 14:07:59 2011
New Revision: 10285
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10285
Log:
dahdi: Give userspace a chance to respond to surprise removal.
* We try very hard to help asterisk understand that we unassign spans.
* Implement disable_span():
- Set span + channels to DAHDI_ALARM_NOTOPEN
- qevent DAHDI_EVENT_REMOVED
* Use disable_span():
- in dahdi_unassign_span() and dahdi_unregister_device()
- with long msleep() so asterisk has a chance to get the message
- Out of the registration_mutex so we actually context switch.
* Also return more POLLERR variants (POLLRDHUP is not portable,
should be tested).
* Also improve printk(), fix rate_limit increment (was missing)
Signed-off-by: Oron Peled <oron.peled at xorcom.com>
Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Modified:
linux/trunk/drivers/dahdi/dahdi-base.c
Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=10285&r1=10284&r2=10285
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Wed Oct 26 14:07:59 2011
@@ -2160,7 +2160,9 @@
* file handles to this channel are disassociated with the actual
* dahdi_chan. */
if (chan->file) {
- module_printk(KERN_NOTICE, "%s: surprise removal\n", __func__);
+ module_printk(KERN_NOTICE,
+ "%s: surprise removal: chan %d\n",
+ __func__, chan->channo);
chan->file->private_data = NULL;
}
@@ -5499,8 +5501,10 @@
if (unlikely(!chan->file->private_data)) {
static int rate_limit;
- if ((rate_limit % 1000) == 0)
- module_printk(KERN_NOTICE, "%s: surprise removal\n", __func__);
+ if ((rate_limit++ % 1000) == 0)
+ module_printk(KERN_NOTICE,
+ "%s: (%d) nodev\n",
+ __func__, rate_limit);
msleep(5);
ret = -ENODEV;
break;
@@ -7022,6 +7026,25 @@
}
EXPORT_SYMBOL(dahdi_register_device);
+static void disable_span(struct dahdi_span *span)
+{
+ int x;
+ unsigned long flags;
+
+ spin_lock_irqsave(&span->lock, flags);
+ span->alarms = DAHDI_ALARM_NOTOPEN;
+ for (x = 0; x < span->channels; x++) {
+ /*
+ * This event may not make it to user space before the channel
+ * is gone, but let's try.
+ */
+ dahdi_qevent_lock(span->chans[x], DAHDI_EVENT_REMOVED);
+ }
+ dahdi_alarm_notify(span);
+ spin_unlock_irqrestore(&span->lock, flags);
+ module_printk(KERN_INFO, "%s: span %d\n", __func__, span->spanno);
+}
+
/**
* _dahdi_unassign_span() - unassign a DAHDI span
* @span: the DAHDI span
@@ -7088,11 +7111,28 @@
return 0;
}
+static int open_channel_count(const struct dahdi_span *span)
+{
+ int i;
+ int open_channels = 0;
+ struct dahdi_chan *chan;
+
+ for (i = 0; i < span->channels; ++i) {
+ chan = span->chans[i];
+ if (test_bit(DAHDI_FLAGBIT_OPEN, &chan->flags))
+ ++open_channels;
+ }
+ return open_channels;
+}
+
int dahdi_unassign_span(struct dahdi_span *span)
{
int ret;
module_printk(KERN_NOTICE, "%s: %s\n", __func__, span->name);
+ disable_span(span);
+ if (open_channel_count(span) > 0)
+ msleep(1000); /* Give user space a chance to read this */
mutex_lock(®istration_mutex);
ret = _dahdi_unassign_span(span);
mutex_unlock(®istration_mutex);
@@ -7111,10 +7151,21 @@
{
struct dahdi_span *s;
struct dahdi_span *next;
+ unsigned int spans_with_open_channels = 0;
+
WARN_ON(!ddev);
might_sleep();
if (unlikely(!ddev))
return;
+
+ list_for_each_entry_safe(s, next, &ddev->spans, device_node) {
+ disable_span(s);
+ if (open_channel_count(s) > 0)
+ ++spans_with_open_channels;
+ }
+
+ if (spans_with_open_channels > 0)
+ msleep(1000); /* give user space a chance to read this */
mutex_lock(®istration_mutex);
list_for_each_entry_safe(s, next, &ddev->spans, device_node) {
@@ -9095,10 +9146,11 @@
} else {
static int rate_limit;
- if ((rate_limit % 1000) == 0)
- module_printk(KERN_NOTICE, "%s: nodev\n", __func__);
+ if ((rate_limit++ % 1000) == 0)
+ module_printk(KERN_NOTICE, "%s: (%d) nodev\n",
+ __func__, rate_limit);
msleep(5);
- return POLLERR | POLLHUP;
+ return POLLERR | POLLHUP | POLLRDHUP | POLLNVAL | POLLPRI;
}
return ret;
}
@@ -9114,10 +9166,11 @@
if (unlikely(!c)) {
static int rate_limit;
- if ((rate_limit % 1000) == 0)
- module_printk(KERN_NOTICE, "%s: nodev\n", __func__);
- msleep(5);
- return POLLERR | POLLHUP;
+ if ((rate_limit++ % 1000) == 0)
+ module_printk(KERN_NOTICE, "%s: (%d) nodev\n",
+ __func__, rate_limit);
+ msleep(20);
+ return POLLERR | POLLHUP | POLLRDHUP | POLLNVAL | POLLPRI;
}
poll_wait(file, &c->waitq, wait_table);
More information about the dahdi-commits
mailing list