[PATCH] libertas: fix error handling

Marcelo Tosatti marcelo at kvack.org
Mon Feb 26 15:24:42 EST 2007


Hi Holger,

On Sat, Feb 24, 2007 at 04:58:33PM +0100, Holger Schurig wrote:
> * renamed wlan_add/remove_XXX into libertas_add/remove_XXX
> * change libertas_remove_card() so that it can clean up even
>   half-initialized netdev/adapter/wlan_private objects
> * add some doxygen comments about this
> 
> Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>
> ---
>  drivers/net/wireless/libertas/decl.h   |    8 +-
>  drivers/net/wireless/libertas/if_usb.c |   22 +++---
>  drivers/net/wireless/libertas/main.c   |  117 +++++++++++++++++--------------
>  3 files changed, 80 insertions(+), 67 deletions(-)
> 

>  dealloc:
> +	libertas_remove_mesh(priv);
> +	libertas_remove_card(priv);
>  	if_usb_free(usb_cardp);
>  

>  
>  	adapter = priv->adapter;
> -
> -	if (!adapter)
> -		goto out;
> -
>  	dev = priv->wlan_dev.netdev;
>  
> -	netif_stop_queue(priv->wlan_dev.netdev);
> -	netif_carrier_off(priv->wlan_dev.netdev);
> +	if (adapter) {
> +		if (dev) {
> +			netif_stop_queue(dev);
> +			netif_carrier_off(dev);
> +		}
>  
> -	wake_pending_cmdnodes(priv);
> +		wake_pending_cmdnodes(priv);
>  
> -	unregister_netdev(dev);
> +		if (dev && dev->reg_state)
> +			unregister_netdev(dev);

This is a layering violation... Shouldnt poke into dev->reg_state from
driver context like this.

>  
> -	cancel_delayed_work(&priv->assoc_work);
> -	destroy_workqueue(priv->assoc_thread);
> +		cancel_delayed_work(&priv->assoc_work);
> +		if (priv->assoc_thread)
> +			destroy_workqueue(priv->assoc_thread);
>  
> -	if (adapter->psmode == wlan802_11powermodemax_psp) {
> -		adapter->psmode = wlan802_11powermodecam;
> -		libertas_ps_wakeup(priv, cmd_option_waitforrsp);
> -	}
> +		if (adapter->psmode == wlan802_11powermodemax_psp) {
> +			adapter->psmode = wlan802_11powermodecam;
> +			libertas_ps_wakeup(priv, cmd_option_waitforrsp);
> +		}
>  
> -	memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
> -	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
> -	wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
> +		memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
> +		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
> +		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);

And I really don't like to have libertas_remove_card handle "half
initialized" devices like this.

Undoing initialization steps (error handling) should be done at the
initialization sites. Having a single function for both half-initialized
and full removal/unregister cases is confusing and bug-prone.

Can you please cook a patch to handle failures at initialization instead
of this?

TIA




More information about the libertas-dev mailing list