mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 01:22:07 +00:00
iwlwifi: fix rfkill memory error
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>
This commit is contained in:
parent
fe00b5a5b7
commit
03d29c6849
@ -256,9 +256,13 @@ EXPORT_SYMBOL(iwl_setup);
|
|||||||
int iwlcore_low_level_notify(struct iwl_priv *priv,
|
int iwlcore_low_level_notify(struct iwl_priv *priv,
|
||||||
enum iwlcore_card_notify notify)
|
enum iwlcore_card_notify notify)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
switch (notify) {
|
switch (notify) {
|
||||||
case IWLCORE_INIT_EVT:
|
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;
|
break;
|
||||||
case IWLCORE_START_EVT:
|
case IWLCORE_START_EVT:
|
||||||
break;
|
break;
|
||||||
@ -266,7 +270,6 @@ int iwlcore_low_level_notify(struct iwl_priv *priv,
|
|||||||
break;
|
break;
|
||||||
case IWLCORE_REMOVE_EVT:
|
case IWLCORE_REMOVE_EVT:
|
||||||
iwl_rfkill_unregister(priv);
|
iwl_rfkill_unregister(priv);
|
||||||
iwl_rfkill_free(priv);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
|
|||||||
|
|
||||||
BUG_ON(device == NULL);
|
BUG_ON(device == NULL);
|
||||||
|
|
||||||
|
IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
|
||||||
priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
|
priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
|
||||||
if (!priv->rfkill_mngr.rfkill) {
|
if (!priv->rfkill_mngr.rfkill) {
|
||||||
|
IWL_ERROR("Unable to allocate rfkill device.\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -92,6 +94,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
|
|||||||
|
|
||||||
priv->rfkill_mngr.input_dev = input_allocate_device();
|
priv->rfkill_mngr.input_dev = input_allocate_device();
|
||||||
if (!priv->rfkill_mngr.input_dev) {
|
if (!priv->rfkill_mngr.input_dev) {
|
||||||
|
IWL_ERROR("Unable to allocate rfkill input device.\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto freed_rfkill;
|
goto freed_rfkill;
|
||||||
}
|
}
|
||||||
@ -105,27 +108,35 @@ int iwl_rfkill_init(struct iwl_priv *priv)
|
|||||||
set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
|
set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
|
||||||
|
|
||||||
ret = rfkill_register(priv->rfkill_mngr.rfkill);
|
ret = rfkill_register(priv->rfkill_mngr.rfkill);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
IWL_ERROR("Unable to register rfkill: %d\n", ret);
|
||||||
goto free_input_dev;
|
goto free_input_dev;
|
||||||
|
}
|
||||||
|
|
||||||
ret = input_register_device(priv->rfkill_mngr.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;
|
goto unregister_rfkill;
|
||||||
|
}
|
||||||
|
|
||||||
|
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
unregister_rfkill:
|
unregister_rfkill:
|
||||||
rfkill_unregister(priv->rfkill_mngr.rfkill);
|
rfkill_unregister(priv->rfkill_mngr.rfkill);
|
||||||
|
priv->rfkill_mngr.rfkill = NULL;
|
||||||
|
|
||||||
free_input_dev:
|
free_input_dev:
|
||||||
input_free_device(priv->rfkill_mngr.input_dev);
|
input_free_device(priv->rfkill_mngr.input_dev);
|
||||||
priv->rfkill_mngr.input_dev = NULL;
|
priv->rfkill_mngr.input_dev = NULL;
|
||||||
|
|
||||||
freed_rfkill:
|
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;
|
priv->rfkill_mngr.rfkill = NULL;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_rfkill_init);
|
EXPORT_SYMBOL(iwl_rfkill_init);
|
||||||
@ -138,20 +149,12 @@ void iwl_rfkill_unregister(struct iwl_priv *priv)
|
|||||||
|
|
||||||
if (priv->rfkill_mngr.rfkill)
|
if (priv->rfkill_mngr.rfkill)
|
||||||
rfkill_unregister(priv->rfkill_mngr.rfkill);
|
rfkill_unregister(priv->rfkill_mngr.rfkill);
|
||||||
|
|
||||||
|
priv->rfkill_mngr.input_dev = NULL;
|
||||||
|
priv->rfkill_mngr.rfkill = NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_rfkill_unregister);
|
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);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(iwl_rfkill_free);
|
|
||||||
|
|
||||||
/* set rf-kill to the right state. */
|
/* set rf-kill to the right state. */
|
||||||
void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
|
void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
|
@ -41,12 +41,10 @@ struct iwl_rfkill_mngr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
|
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);
|
void iwl_rfkill_unregister(struct iwl_priv *priv);
|
||||||
int iwl_rfkill_init(struct iwl_priv *priv);
|
int iwl_rfkill_init(struct iwl_priv *priv);
|
||||||
#else
|
#else
|
||||||
static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {}
|
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 void iwl_rfkill_unregister(struct iwl_priv *priv) {}
|
||||||
static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; }
|
static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user