aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-ucode.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-15 16:26:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-09 16:37:15 -0400
commitdb662d478695a967b9d0a4c9893278e797b73f6c (patch)
tree3a5cf5c45c1bf241eb5dbf354c5122d53c55a14a /drivers/net/wireless/iwlwifi/iwl-ucode.c
parent0c19744c344cf1bfda04f681ff4e1e46455577bd (diff)
iwlwifi: extend notification wait
Sometimes, for example when we ask the uCode for calibration, we wait for the "complete" response while we also need the results that are sent in other, interim, notifications. Currently we handle this by installing an RX handler globally, but that isn't needed as this is the only time we want to use these notifications. So in order to be able to simplify at least future code that does the same, extend the notification wait framework to allow you to wait for multiple commands and decide based on the command whether the wait finished. While at it, also fix a race that can then become relevant -- if the wait function has returned true once it shouldn't be called again, today this can happen due to races between the triggering and the wakeup. 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.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index 252828728837..44b0e72ca7fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -417,9 +417,8 @@ struct iwl_alive_data {
417 u8 subtype; 417 u8 subtype;
418}; 418};
419 419
420static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, 420static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
421 struct iwl_rx_packet *pkt, 421 struct iwl_rx_packet *pkt, void *data)
422 void *data)
423{ 422{
424 struct iwl_priv *priv = 423 struct iwl_priv *priv =
425 container_of(notif_wait, struct iwl_priv, notif_wait); 424 container_of(notif_wait, struct iwl_priv, notif_wait);
@@ -440,6 +439,8 @@ static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
440 439
441 alive_data->subtype = palive->ver_subtype; 440 alive_data->subtype = palive->ver_subtype;
442 alive_data->valid = palive->is_valid == UCODE_VALID_OK; 441 alive_data->valid = palive->is_valid == UCODE_VALID_OK;
442
443 return true;
443} 444}
444 445
445#define UCODE_ALIVE_TIMEOUT HZ 446#define UCODE_ALIVE_TIMEOUT HZ
@@ -453,6 +454,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
453 const struct fw_img *fw; 454 const struct fw_img *fw;
454 int ret; 455 int ret;
455 enum iwl_ucode_type old_type; 456 enum iwl_ucode_type old_type;
457 static const u8 alive_cmd[] = { REPLY_ALIVE };
456 458
457 old_type = priv->shrd->ucode_type; 459 old_type = priv->shrd->ucode_type;
458 priv->shrd->ucode_type = ucode_type; 460 priv->shrd->ucode_type = ucode_type;
@@ -463,8 +465,9 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
463 if (!fw) 465 if (!fw)
464 return -EINVAL; 466 return -EINVAL;
465 467
466 iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE, 468 iwl_init_notification_wait(&priv->notif_wait, &alive_wait,
467 iwl_alive_fn, &alive_data); 469 alive_cmd, ARRAY_SIZE(alive_cmd),
470 iwl_alive_fn, &alive_data);
468 471
469 ret = iwl_trans_start_fw(trans(priv), fw); 472 ret = iwl_trans_start_fw(trans(priv), fw);
470 if (ret) { 473 if (ret) {
@@ -522,6 +525,9 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
522int iwl_run_init_ucode(struct iwl_priv *priv) 525int iwl_run_init_ucode(struct iwl_priv *priv)
523{ 526{
524 struct iwl_notification_wait calib_wait; 527 struct iwl_notification_wait calib_wait;
528 static const u8 calib_complete[] = {
529 CALIBRATION_COMPLETE_NOTIFICATION
530 };
525 int ret; 531 int ret;
526 532
527 lockdep_assert_held(&priv->mutex); 533 lockdep_assert_held(&priv->mutex);
@@ -534,8 +540,8 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
534 return 0; 540 return 0;
535 541
536 iwl_init_notification_wait(&priv->notif_wait, &calib_wait, 542 iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
537 CALIBRATION_COMPLETE_NOTIFICATION, 543 calib_complete, ARRAY_SIZE(calib_complete),
538 NULL, NULL); 544 NULL, NULL);
539 545
540 /* Will also start the device */ 546 /* Will also start the device */
541 ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); 547 ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);