summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-ucode.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-06 13:30:58 -0800
committerJohn W. Linville <linville@tuxdriver.com>2012-03-07 13:56:32 -0500
commit4bd14dd5f77bbe3c51f50f4e86d3b8960e6a518c (patch)
tree0dbf32e6fbf047035389a09b7b1124ca769a5551 /drivers/net/wireless/iwlwifi/iwl-ucode.c
parentf47208934b2aba432722baeb86a72fcbfd26b593 (diff)
downloadop-kernel-dev-4bd14dd5f77bbe3c51f50f4e86d3b8960e6a518c.zip
op-kernel-dev-4bd14dd5f77bbe3c51f50f4e86d3b8960e6a518c.tar.gz
iwlwifi: abstract out notification wait support
This will be sharable, but needs to live in the op_mode as it is dependent on command processing. Make a library out of the notification wait code. Since I wrote all of the code originally and only Intel employees changed it, we can also relicense it to dual BSD/GPL. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-ucode.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-ucode.c81
1 files changed, 9 insertions, 72 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index 686d456..4d34327 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include "iwl-dev.h"
#include "iwl-core.h"
@@ -434,10 +433,12 @@ struct iwl_alive_data {
u8 subtype;
};
-static void iwl_alive_fn(struct iwl_priv *priv,
+static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
struct iwl_rx_packet *pkt,
void *data)
{
+ struct iwl_priv *priv =
+ container_of(notif_wait, struct iwl_priv, notif_wait);
struct iwl_alive_data *alive_data = data;
struct iwl_alive_resp *palive;
@@ -457,70 +458,6 @@ static void iwl_alive_fn(struct iwl_priv *priv,
alive_data->valid = palive->is_valid == UCODE_VALID_OK;
}
-/* notification wait support */
-void iwl_init_notification_wait(struct iwl_shared *shrd,
- struct iwl_notification_wait *wait_entry,
- u8 cmd,
- void (*fn)(struct iwl_priv *priv,
- struct iwl_rx_packet *pkt,
- void *data),
- void *fn_data)
-{
- wait_entry->fn = fn;
- wait_entry->fn_data = fn_data;
- wait_entry->cmd = cmd;
- wait_entry->triggered = false;
- wait_entry->aborted = false;
-
- spin_lock_bh(&shrd->notif_wait_lock);
- list_add(&wait_entry->list, &shrd->notif_waits);
- spin_unlock_bh(&shrd->notif_wait_lock);
-}
-
-int iwl_wait_notification(struct iwl_shared *shrd,
- struct iwl_notification_wait *wait_entry,
- unsigned long timeout)
-{
- int ret;
-
- ret = wait_event_timeout(shrd->notif_waitq,
- wait_entry->triggered || wait_entry->aborted,
- timeout);
-
- spin_lock_bh(&shrd->notif_wait_lock);
- list_del(&wait_entry->list);
- spin_unlock_bh(&shrd->notif_wait_lock);
-
- if (wait_entry->aborted)
- return -EIO;
-
- /* return value is always >= 0 */
- if (ret <= 0)
- return -ETIMEDOUT;
- return 0;
-}
-
-void iwl_remove_notification(struct iwl_shared *shrd,
- struct iwl_notification_wait *wait_entry)
-{
- spin_lock_bh(&shrd->notif_wait_lock);
- list_del(&wait_entry->list);
- spin_unlock_bh(&shrd->notif_wait_lock);
-}
-
-void iwl_abort_notification_waits(struct iwl_shared *shrd)
-{
- unsigned long flags;
- struct iwl_notification_wait *wait_entry;
-
- spin_lock_irqsave(&shrd->notif_wait_lock, flags);
- list_for_each_entry(wait_entry, &shrd->notif_waits, list)
- wait_entry->aborted = true;
- spin_unlock_irqrestore(&shrd->notif_wait_lock, flags);
-
- wake_up_all(&shrd->notif_waitq);
-}
-
#define UCODE_ALIVE_TIMEOUT HZ
#define UCODE_CALIB_TIMEOUT (2*HZ)
@@ -540,13 +477,13 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
if (!fw)
return -EINVAL;
- iwl_init_notification_wait(priv->shrd, &alive_wait, REPLY_ALIVE,
+ iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE,
iwl_alive_fn, &alive_data);
ret = iwl_trans_start_fw(trans(priv), fw);
if (ret) {
priv->shrd->ucode_type = old_type;
- iwl_remove_notification(priv->shrd, &alive_wait);
+ iwl_remove_notification(&priv->notif_wait, &alive_wait);
return ret;
}
@@ -554,7 +491,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
* Some things may run in the background now, but we
* just wait for the ALIVE notification here.
*/
- ret = iwl_wait_notification(priv->shrd, &alive_wait,
+ ret = iwl_wait_notification(&priv->notif_wait, &alive_wait,
UCODE_ALIVE_TIMEOUT);
if (ret) {
priv->shrd->ucode_type = old_type;
@@ -608,7 +545,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
if (priv->shrd->ucode_type != IWL_UCODE_NONE)
return 0;
- iwl_init_notification_wait(priv->shrd, &calib_wait,
+ iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
CALIBRATION_COMPLETE_NOTIFICATION,
NULL, NULL);
@@ -625,13 +562,13 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
* Some things may run in the background now, but we
* just wait for the calibration complete notification.
*/
- ret = iwl_wait_notification(priv->shrd, &calib_wait,
+ ret = iwl_wait_notification(&priv->notif_wait, &calib_wait,
UCODE_CALIB_TIMEOUT);
goto out;
error:
- iwl_remove_notification(priv->shrd, &calib_wait);
+ iwl_remove_notification(&priv->notif_wait, &calib_wait);
out:
/* Whatever happened, stop the device */
iwl_trans_stop_device(trans(priv));
OpenPOWER on IntegriCloud