diff options
Diffstat (limited to 'drivers/staging/cw1200/wsm.c')
-rw-r--r-- | drivers/staging/cw1200/wsm.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/drivers/staging/cw1200/wsm.c b/drivers/staging/cw1200/wsm.c index 5c52cdbb1c2..bb94d19da08 100644 --- a/drivers/staging/cw1200/wsm.c +++ b/drivers/staging/cw1200/wsm.c @@ -1083,9 +1083,15 @@ void wsm_lock_tx(struct cw1200_common *priv) { wsm_cmd_lock(priv); if (atomic_add_return(1, &priv->tx_lock) == 1) { - WARN_ON(wait_event_timeout(priv->bh_evt_wq, - !priv->hw_bufs_used, WSM_CMD_LAST_CHANCE_TIMEOUT) <= 0); - wsm_printk(KERN_DEBUG "[WSM] TX is locked.\n"); + if (priv->bh_error) { + wsm_printk(KERN_ERR "fatal error occured, " + "could not take lock\n"); + } else { + WARN_ON(wait_event_timeout(priv->bh_evt_wq, + !priv->hw_bufs_used, + WSM_CMD_LAST_CHANCE_TIMEOUT) <= 0); + wsm_printk(KERN_DEBUG "[WSM] TX is locked.\n"); + } } wsm_cmd_unlock(priv); } @@ -1098,20 +1104,29 @@ void wsm_lock_tx_async(struct cw1200_common *priv) void wsm_flush_tx(struct cw1200_common *priv) { - BUG_ON(!atomic_read(&priv->tx_lock)); - WARN_ON(wait_event_timeout(priv->bh_evt_wq, - !priv->hw_bufs_used, WSM_CMD_LAST_CHANCE_TIMEOUT) <= 0); + if (priv->bh_error) + wsm_printk(KERN_ERR "fatal error occured, will not flush\n"); + else { + BUG_ON(!atomic_read(&priv->tx_lock)); + WARN_ON(wait_event_timeout(priv->bh_evt_wq, + !priv->hw_bufs_used, + WSM_CMD_LAST_CHANCE_TIMEOUT) <= 0); + } } void wsm_unlock_tx(struct cw1200_common *priv) { int tx_lock; - tx_lock = atomic_sub_return(1, &priv->tx_lock); - if (tx_lock < 0) { - BUG_ON(1); - } else if (tx_lock == 0) { - cw1200_bh_wakeup(priv); - wsm_printk(KERN_DEBUG "[WSM] TX is unlocked.\n"); + if (priv->bh_error) + wsm_printk(KERN_ERR "fatal error occured, unlock is unsafe\n"); + else { + tx_lock = atomic_sub_return(1, &priv->tx_lock); + if (tx_lock < 0) { + BUG_ON(1); + } else if (tx_lock == 0) { + cw1200_bh_wakeup(priv); + wsm_printk(KERN_DEBUG "[WSM] TX is unlocked.\n"); + } } } @@ -1133,6 +1148,12 @@ int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len) "unknown error", }; +#if defined(CONFIG_CW1200_USE_STE_EXTENSIONS) + /* Send the event upwards on the FW exception */ + cw1200_pm_stay_awake(&priv->pm_state, 3*HZ); + ieee80211_driver_hang_notify(priv->vif, GFP_KERNEL); +#endif + buf.begin = buf.data = data; buf.end = &buf.begin[len]; |