OSDN Git Service

iwlagn: add support for waiting for notifications
[android-x86/kernel.git] / drivers / net / wireless / iwlwifi / iwl-agn-lib.c
index 3dee87e..29dcda0 100644 (file)
@@ -473,6 +473,11 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
        priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
                                        iwlagn_rx_calib_complete;
        priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
+
+       /* set up notification wait support */
+       spin_lock_init(&priv->_agn.notif_wait_lock);
+       INIT_LIST_HEAD(&priv->_agn.notif_waits);
+       init_waitqueue_head(&priv->_agn.notif_waitq);
 }
 
 void iwlagn_setup_deferred_work(struct iwl_priv *priv)
@@ -2389,3 +2394,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
        }
        return 0;
 }
+
+/* notification wait support */
+void iwlagn_init_notification_wait(struct iwl_priv *priv,
+                                  struct iwl_notification_wait *wait_entry,
+                                  void (*fn)(struct iwl_priv *priv,
+                                             struct iwl_rx_packet *pkt),
+                                  u8 cmd)
+{
+       wait_entry->fn = fn;
+       wait_entry->cmd = cmd;
+       wait_entry->triggered = false;
+
+       spin_lock_bh(&priv->_agn.notif_wait_lock);
+       list_add(&wait_entry->list, &priv->_agn.notif_waits);
+       spin_unlock_bh(&priv->_agn.notif_wait_lock);
+}
+
+signed long iwlagn_wait_notification(struct iwl_priv *priv,
+                                    struct iwl_notification_wait *wait_entry,
+                                    unsigned long timeout)
+{
+       int ret;
+
+       ret = wait_event_timeout(priv->_agn.notif_waitq,
+                                &wait_entry->triggered,
+                                timeout);
+
+       spin_lock_bh(&priv->_agn.notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&priv->_agn.notif_wait_lock);
+
+       return ret;
+}
+
+void iwlagn_remove_notification(struct iwl_priv *priv,
+                               struct iwl_notification_wait *wait_entry)
+{
+       spin_lock_bh(&priv->_agn.notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&priv->_agn.notif_wait_lock);
+}