iwlwifi: move ucode notification from iwl_priv to iwl_shared

Move the notification structures for ucode operations from the
iwl_priv structure to the iwl_shared structure, with associated
code changes.

Signed-off-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index 1b23b99..b365de4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -571,6 +571,70 @@
 	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)
 
@@ -587,7 +651,7 @@
 	if (ret)
 		return ret;
 
-	iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE,
+	iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
 				      iwl_alive_fn, &alive_data);
 
 	old_type = trans->shrd->ucode_type;
@@ -596,7 +660,7 @@
 	ret = iwl_load_given_ucode(trans, ucode_type);
 	if (ret) {
 		trans->shrd->ucode_type = old_type;
-		iwlagn_remove_notification(priv, &alive_wait);
+		iwl_remove_notification(trans->shrd, &alive_wait);
 		return ret;
 	}
 
@@ -606,7 +670,8 @@
 	 * Some things may run in the background now, but we
 	 * just wait for the ALIVE notification here.
 	 */
-	ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT);
+	ret = iwl_wait_notification(trans->shrd, &alive_wait,
+					UCODE_ALIVE_TIMEOUT);
 	if (ret) {
 		trans->shrd->ucode_type = old_type;
 		return ret;
@@ -659,7 +724,7 @@
 	if (priv->shrd->ucode_type != IWL_UCODE_NONE)
 		return 0;
 
-	iwlagn_init_notification_wait(priv, &calib_wait,
+	iwl_init_notification_wait(priv->shrd, &calib_wait,
 				      CALIBRATION_COMPLETE_NOTIFICATION,
 				      NULL, NULL);
 
@@ -676,12 +741,13 @@
 	 * Some things may run in the background now, but we
 	 * just wait for the calibration complete notification.
 	 */
-	ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT);
+	ret = iwl_wait_notification(priv->shrd, &calib_wait,
+					UCODE_CALIB_TIMEOUT);
 
 	goto out;
 
  error:
-	iwlagn_remove_notification(priv, &calib_wait);
+	iwl_remove_notification(priv->shrd, &calib_wait);
  out:
 	/* Whatever happened, stop the device */
 	iwl_trans_stop_device(trans(priv));