From patchwork Mon Nov 9 09:30:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhu Yi X-Patchwork-Id: 58683 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA99UPaW018639 for ; Mon, 9 Nov 2009 09:30:25 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755101AbZKIJaJ (ORCPT ); Mon, 9 Nov 2009 04:30:09 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755048AbZKIJaI (ORCPT ); Mon, 9 Nov 2009 04:30:08 -0500 Received: from mga02.intel.com ([134.134.136.20]:19858 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752694AbZKIJaH (ORCPT ); Mon, 9 Nov 2009 04:30:07 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 09 Nov 2009 01:16:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.44,707,1249282800"; d="scan'208";a="465578977" Received: from debian.sh.intel.com (HELO [10.239.13.180]) ([10.239.13.180]) by orsmga002.jf.intel.com with ESMTP; 09 Nov 2009 01:47:21 -0800 Subject: Re: BUG: oops when "rmmod ipw2200" From: Zhu Yi To: "John W. Linville" Cc: Holger Schurig , "linux-wireless@vger.kernel.org" In-Reply-To: <20091105153329.GB2817@tuxdriver.com> References: <20091105153329.GB2817@tuxdriver.com> Date: Mon, 09 Nov 2009 17:30:07 +0800 Message-Id: <1257759007.5538.1010.camel@debian> Mime-Version: 1.0 X-Mailer: Evolution 2.26.1 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 240cff1..faec9d3 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -6325,8 +6325,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, fail: if (dev) { - if (registered) + if (registered) { unregister_netdev(dev); + unregister_ieee80211(priv->ieee); + } ipw2100_hw_stop_adapter(priv); @@ -6384,6 +6386,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) * being called if the device is open. If we free storage * first, then close() will crash. */ unregister_netdev(dev); + unregister_ieee80211(priv->ieee); /* ipw2100_down will ensure that there is no more pending work * in the workqueue's, so we can safely remove them now. */ diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 827824d..ae846a7 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11823,6 +11823,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, IPW_ERROR("Failed to register promiscuous network " "device (error %d).\n", err); unregister_netdev(priv->net_dev); + unregister_ieee80211(priv->ieee); goto out_remove_sysfs; } } @@ -11873,6 +11874,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) mutex_unlock(&priv->mutex); unregister_netdev(priv->net_dev); + unregister_ieee80211(priv->ieee); if (priv->rxq) { ipw_rx_queue_free(priv, priv->rxq); diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index bf45391..f42ade6 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -1020,6 +1020,7 @@ static inline int libipw_is_cck_rate(u8 rate) /* ieee80211.c */ extern void free_ieee80211(struct net_device *dev, int monitor); extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); +extern void unregister_ieee80211(struct libipw_device *ieee); extern int libipw_change_mtu(struct net_device *dev, int new_mtu); extern void libipw_networks_age(struct libipw_device *ieee, diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index a0e9f6a..be5b809 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -235,16 +235,19 @@ void free_ieee80211(struct net_device *dev, int monitor) libipw_networks_free(ieee); /* free cfg80211 resources */ - if (!monitor) { - wiphy_unregister(ieee->wdev.wiphy); - kfree(ieee->a_band.channels); - kfree(ieee->bg_band.channels); + if (!monitor) wiphy_free(ieee->wdev.wiphy); - } free_netdev(dev); } +void unregister_ieee80211(struct libipw_device *ieee) +{ + wiphy_unregister(ieee->wdev.wiphy); + kfree(ieee->a_band.channels); + kfree(ieee->bg_band.channels); +} + #ifdef CONFIG_LIBIPW_DEBUG static int debug = 0; @@ -330,3 +333,4 @@ module_init(libipw_init); EXPORT_SYMBOL(alloc_ieee80211); EXPORT_SYMBOL(free_ieee80211); +EXPORT_SYMBOL(unregister_ieee80211);