summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2012-03-21 20:40:29 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2012-03-21 20:40:29 +0000
commit799745d4c032b9cf1a23a841174f3d90e7afecca (patch)
tree7b36607e40dbf976fd4bffc3cb2e6e6d175726c9
parenteaebc553a48a9eb4c5fd95f07c91acf1d1ffa23c (diff)
xpp: FXS: atomic vbat_h power handling
* In do_chan_power() make vbat_h changes atomic. * As a result we can ignore duplicate requests. This will allow cleaner logic in the next commit. * Added proper debug messages. Signed-off-by: Oron Peled <oron.peled@xorcom.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10573 git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.5@10577 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/xpp/card_fxs.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index c439f00..12cc4da 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -161,15 +161,23 @@ struct FXS_priv_data {
static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
{
struct FXS_priv_data *priv;
+ unsigned long *p;
+ int was;
BUG_ON(!xbus);
BUG_ON(!xpd);
priv = xpd->priv;
- LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on) ? "up" : "down");
+ p = (unsigned long *)&priv->vbat_h;
if (on)
- BIT_SET(priv->vbat_h, chan);
+ was = test_and_set_bit(chan, p) != 0;
else
- BIT_CLR(priv->vbat_h, chan);
+ was = test_and_clear_bit(chan, p) != 0;
+ if (was == on) {
+ LINE_DBG(SIGNAL, xpd, chan,
+ "%s (same, ignored)\n", (on) ? "up" : "down");
+ return 0;
+ }
+ LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on) ? "up" : "down");
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, REG_BATTERY,
(on) ? REG_BATTERY_BATSL : 0x00);
}
@@ -1566,7 +1574,7 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
len += sprintf(page + len, "\n%-12s", "vbat_h:");
for_each_line(xpd, i) {
len += sprintf(page + len, "%4d",
- IS_SET(priv->vbat_h, i));
+ test_bit(i, (unsigned long *)&priv->vbat_h));
}
len += sprintf(page + len, "\n");
for(led = 0; led < NUM_LEDS; led++) {