Skip to content

Commit

Permalink
iwlwifi: fix rfkill memory error
Browse files Browse the repository at this point in the history
Do not free reference to device twice. After rfkill registration succeeds
we only need to call rfkill_unregister() and not rfkill_free().
Also add some debugging.

Signed-off-by: Mohamed Abbas <mabbas@linux.intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Mohamed Abbas authored and John W. Linville committed Apr 8, 2008
1 parent fe00b5a commit 03d29c6
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 18 deletions.
7 changes: 5 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,20 @@ EXPORT_SYMBOL(iwl_setup);
int iwlcore_low_level_notify(struct iwl_priv *priv,
enum iwlcore_card_notify notify)
{
int ret;
switch (notify) {
case IWLCORE_INIT_EVT:
iwl_rfkill_init(priv);
ret = iwl_rfkill_init(priv);
if (ret)
IWL_ERROR("Unable to initialize RFKILL system. "
"Ignoring error: %d\n", ret);
break;
case IWLCORE_START_EVT:
break;
case IWLCORE_STOP_EVT:
break;
case IWLCORE_REMOVE_EVT:
iwl_rfkill_unregister(priv);
iwl_rfkill_free(priv);
break;
}

Expand Down
31 changes: 17 additions & 14 deletions drivers/net/wireless/iwlwifi/iwl-rfkill.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)

BUG_ON(device == NULL);

IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill_mngr.rfkill) {
IWL_ERROR("Unable to allocate rfkill device.\n");
ret = -ENOMEM;
goto error;
}
Expand All @@ -92,6 +94,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)

priv->rfkill_mngr.input_dev = input_allocate_device();
if (!priv->rfkill_mngr.input_dev) {
IWL_ERROR("Unable to allocate rfkill input device.\n");
ret = -ENOMEM;
goto freed_rfkill;
}
Expand All @@ -105,27 +108,35 @@ int iwl_rfkill_init(struct iwl_priv *priv)
set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);

ret = rfkill_register(priv->rfkill_mngr.rfkill);
if (ret)
if (ret) {
IWL_ERROR("Unable to register rfkill: %d\n", ret);
goto free_input_dev;
}

ret = input_register_device(priv->rfkill_mngr.input_dev);
if (ret)
if (ret) {
IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
goto unregister_rfkill;
}

IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;

unregister_rfkill:
rfkill_unregister(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.rfkill = NULL;

free_input_dev:
input_free_device(priv->rfkill_mngr.input_dev);
priv->rfkill_mngr.input_dev = NULL;

freed_rfkill:
rfkill_free(priv->rfkill_mngr.rfkill);
if (priv->rfkill_mngr.rfkill != NULL)
rfkill_free(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.rfkill = NULL;

error:
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;
}
EXPORT_SYMBOL(iwl_rfkill_init);
Expand All @@ -138,19 +149,11 @@ void iwl_rfkill_unregister(struct iwl_priv *priv)

if (priv->rfkill_mngr.rfkill)
rfkill_unregister(priv->rfkill_mngr.rfkill);
}
EXPORT_SYMBOL(iwl_rfkill_unregister);


void iwl_rfkill_free(struct iwl_priv *priv)
{
if (priv->rfkill_mngr.input_dev)
input_free_device(priv->rfkill_mngr.input_dev);

if (priv->rfkill_mngr.rfkill)
rfkill_free(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.input_dev = NULL;
priv->rfkill_mngr.rfkill = NULL;
}
EXPORT_SYMBOL(iwl_rfkill_free);
EXPORT_SYMBOL(iwl_rfkill_unregister);

/* set rf-kill to the right state. */
void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-rfkill.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,10 @@ struct iwl_rfkill_mngr {
};

void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
void iwl_rfkill_free(struct iwl_priv *priv);
void iwl_rfkill_unregister(struct iwl_priv *priv);
int iwl_rfkill_init(struct iwl_priv *priv);
#else
static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {}
static inline void iwl_rfkill_free(struct iwl_priv *priv) {}
static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {}
static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; }
#endif
Expand Down

0 comments on commit 03d29c6

Please sign in to comment.