2009-10-13 13:54:34

by Ferenc Wagner

[permalink] [raw]
Subject: 2.6.32-rc4 ipw2200: oops on missing firmware

Hi,

See the screenshot at http://apt.niif.hu/ipw_oops.png. During bootup,
initramfs-tools tried to load the ipw2200 module, but nobody fed it
the necessary firmware, so request_firmware timed out and the module
unload cleanup oopsed in device_pm_remove:

void device_pm_remove(struct device *dev)
{
pr_debug("PM: Removing info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
mutex_lock(&dpm_list_mtx);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
pm_runtime_remove(dev);
}

00000a0a <device_pm_remove>:
a0a: 55 push %ebp
a0b: 89 e5 mov %esp,%ebp
a0d: 53 push %ebx
a0e: 89 c3 mov %eax,%ebx
a10: b8 08 00 00 00 mov $0x8,%eax
a15: e8 fc ff ff ff call a16 <device_pm_remove+0xc>
a1a: 8d 4b 5c lea 0x5c(%ebx),%ecx
a1d: 8b 53 5c mov 0x5c(%ebx),%edx
a20: 8b 43 60 mov 0x60(%ebx),%eax
a23: 89 42 04 mov %eax,0x4(%edx)
a26: 89 10 mov %edx,(%eax)
a28: 89 4b 5c mov %ecx,0x5c(%ebx)
a2b: 89 4b 60 mov %ecx,0x60(%ebx)
a2e: b8 08 00 00 00 mov $0x8,%eax
a33: e8 fc ff ff ff call a34 <device_pm_remove+0x2a>
a38: 89 d8 mov %ebx,%eax
a3a: e8 fc ff ff ff call a3b <device_pm_remove+0x31>
a3f: 5b pop %ebx
a40: 5d pop %ebp
a41: c3 ret

The offending IP translates to line a23, so the problem is edx being 0
at that point. I'm not sure which struct device field has offset
0x5c, maybe power, but I'm lost at this point anyway.

I don't know whether it's a new bug or not, never did such insane
things previously. rmmod ipw2200 definitely worked under 2.6.31, and
it's possible that it works under 2.6.32-rc4 too, I forgot to check
that (but will do so tonight).
--
Regards,
Feri.


2009-10-13 16:56:05

by Frans Pop

[permalink] [raw]
Subject: Re: 2.6.32-rc4 ipw2200: oops on missing firmware

Adding relevant CCs. Original message follows.

==============
Hi,

See the screenshot at http://apt.niif.hu/ipw_oops.png. During bootup,
initramfs-tools tried to load the ipw2200 module, but nobody fed it
the necessary firmware, so request_firmware timed out and the module
unload cleanup oopsed in device_pm_remove:

void device_pm_remove(struct device *dev)
{
pr_debug("PM: Removing info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
mutex_lock(&dpm_list_mtx);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
pm_runtime_remove(dev);
}

00000a0a <device_pm_remove>:
a0a: 55 push %ebp
a0b: 89 e5 mov %esp,%ebp
a0d: 53 push %ebx
a0e: 89 c3 mov %eax,%ebx
a10: b8 08 00 00 00 mov $0x8,%eax
a15: e8 fc ff ff ff call a16 <device_pm_remove+0xc>
a1a: 8d 4b 5c lea 0x5c(%ebx),%ecx
a1d: 8b 53 5c mov 0x5c(%ebx),%edx
a20: 8b 43 60 mov 0x60(%ebx),%eax
a23: 89 42 04 mov %eax,0x4(%edx)
a26: 89 10 mov %edx,(%eax)
a28: 89 4b 5c mov %ecx,0x5c(%ebx)
a2b: 89 4b 60 mov %ecx,0x60(%ebx)
a2e: b8 08 00 00 00 mov $0x8,%eax
a33: e8 fc ff ff ff call a34 <device_pm_remove+0x2a>
a38: 89 d8 mov %ebx,%eax
a3a: e8 fc ff ff ff call a3b <device_pm_remove+0x31>
a3f: 5b pop %ebx
a40: 5d pop %ebp
a41: c3 ret

The offending IP translates to line a23, so the problem is edx being 0
at that point. I'm not sure which struct device field has offset
0x5c, maybe power, but I'm lost at this point anyway.

I don't know whether it's a new bug or not, never did such insane
things previously. rmmod ipw2200 definitely worked under 2.6.31, and
it's possible that it works under 2.6.32-rc4 too, I forgot to check
that (but will do so tonight).

--
Regards,
Feri.

2009-10-13 20:22:47

by Ferenc Wagner

[permalink] [raw]
Subject: Re: 2.6.32-rc4 ipw2200: oops on missing firmware

Frans Pop <[email protected]> writes:

> Adding relevant CCs.

Thanks. Meanwhile I checked that the ipw2200 module can indeed be
removed and reinserted into the running system without problems,
here's the relevant part of dmesg:

[ 5837.082811] ipw2200: Firmware error detected. Restarting.
[ 5840.507981] ipw2200: Firmware error detected. Restarting.
[ 5886.248174] ipw2200 0000:02:02.0: PCI INT A disabled
[ 5919.283775] ipw2200: Intel(R) PRO/Wireless 2200/2915 Network Driver, 1.2.2kmprq
[ 5919.283782] ipw2200: Copyright(c) 2003-2006 Intel Corporation
[ 5919.283879] ipw2200 0000:02:02.0: PCI INT A -> Link[LNKF] -> GSI 11 (level, low) -> IRQ 11
[ 5919.285697] ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
[ 5919.285771] ipw2200 0000:02:02.0: firmware: requesting ipw2200-bss.fw
[ 5919.466323] ipw2200: Detected geography ZZR (14 802.11bg channels, 0 802.11a channels)
[ 5919.477923] udev: renamed network interface eth0 to wlan
[ 5982.543067] ipw2200: Firmware error detected. Restarting.
[ 5985.850947] ipw2200: Firmware error detected. Restarting.
[ 5989.170633] ipw2200: Firmware error detected. Restarting.
[ 5992.479084] ipw2200: Firmware error detected. Restarting.
[ 5995.786495] ipw2200: Firmware error detected. Restarting.
[ 5999.099022] ipw2200: Firmware error detected. Restarting.
[ 6003.193188] QoS Error need to parse QOS_PARAMETER IE
[ 6029.106407] ipw2200: Firmware error detected. Restarting.
[ 6032.415272] ipw2200: Firmware error detected. Restarting.

Yes, I continuously get firmware errors, and occasionally the QoS
error. I'm using firmware version 3.1, but these are probably
irrelevant for this bug report.

> Original message follows.
> ==============
> Hi,
>
> See the screenshot at http://apt.niif.hu/ipw_oops.png. During bootup,
> initramfs-tools tried to load the ipw2200 module, but nobody fed it
> the necessary firmware, so request_firmware timed out and the module
> unload cleanup oopsed in device_pm_remove:
>
> void device_pm_remove(struct device *dev)
> {
> pr_debug("PM: Removing info for %s:%s\n",
> dev->bus ? dev->bus->name : "No Bus",
> kobject_name(&dev->kobj));
> mutex_lock(&dpm_list_mtx);
> list_del_init(&dev->power.entry);
> mutex_unlock(&dpm_list_mtx);
> pm_runtime_remove(dev);
> }
>
> 00000a0a <device_pm_remove>:
> a0a: 55 push %ebp
> a0b: 89 e5 mov %esp,%ebp
> a0d: 53 push %ebx
> a0e: 89 c3 mov %eax,%ebx
> a10: b8 08 00 00 00 mov $0x8,%eax
> a15: e8 fc ff ff ff call a16 <device_pm_remove+0xc>
> a1a: 8d 4b 5c lea 0x5c(%ebx),%ecx
> a1d: 8b 53 5c mov 0x5c(%ebx),%edx
> a20: 8b 43 60 mov 0x60(%ebx),%eax
> a23: 89 42 04 mov %eax,0x4(%edx)
> a26: 89 10 mov %edx,(%eax)
> a28: 89 4b 5c mov %ecx,0x5c(%ebx)
> a2b: 89 4b 60 mov %ecx,0x60(%ebx)
> a2e: b8 08 00 00 00 mov $0x8,%eax
> a33: e8 fc ff ff ff call a34 <device_pm_remove+0x2a>
> a38: 89 d8 mov %ebx,%eax
> a3a: e8 fc ff ff ff call a3b <device_pm_remove+0x31>
> a3f: 5b pop %ebx
> a40: 5d pop %ebp
> a41: c3 ret
>
> The offending IP translates to line a23, so the problem is edx being 0
> at that point. I'm not sure which struct device field has offset
> 0x5c, maybe power, but I'm lost at this point anyway.
>
> I don't know whether it's a new bug or not, never did such insane
> things previously. rmmod ipw2200 definitely worked under 2.6.31, and
> it's possible that it works under 2.6.32-rc4 too, I forgot to check
> that (but will do so tonight).
>
> --
> Regards,
> Feri.

2009-10-15 06:51:09

by Zhu Yi

[permalink] [raw]
Subject: Re: [Ipw2100-devel] 2.6.32-rc4 ipw2200: oops on missing firmware

On Wed, 2009-10-14 at 00:55 +0800, Frans Pop wrote:
> Adding relevant CCs. Original message follows.
>
> ==============
> Hi,
>
> See the screenshot at http://apt.niif.hu/ipw_oops.png. During bootup,
> initramfs-tools tried to load the ipw2200 module, but nobody fed it
> the necessary firmware, so request_firmware timed out and the module
> unload cleanup oopsed in device_pm_remove:
>
> void device_pm_remove(struct device *dev)
> {
> pr_debug("PM: Removing info for %s:%s\n",
> dev->bus ? dev->bus->name : "No Bus",
> kobject_name(&dev->kobj));
> mutex_lock(&dpm_list_mtx);
> list_del_init(&dev->power.entry);
> mutex_unlock(&dpm_list_mtx);
> pm_runtime_remove(dev);
> }
>
> 00000a0a <device_pm_remove>:
> a0a: 55 push %ebp
> a0b: 89 e5 mov %esp,%ebp
> a0d: 53 push %ebx
> a0e: 89 c3 mov %eax,%ebx
> a10: b8 08 00 00 00 mov $0x8,%eax
> a15: e8 fc ff ff ff call a16 <device_pm_remove+0xc>
> a1a: 8d 4b 5c lea 0x5c(%ebx),%ecx
> a1d: 8b 53 5c mov 0x5c(%ebx),%edx
> a20: 8b 43 60 mov 0x60(%ebx),%eax
> a23: 89 42 04 mov %eax,0x4(%edx)
> a26: 89 10 mov %edx,(%eax)
> a28: 89 4b 5c mov %ecx,0x5c(%ebx)
> a2b: 89 4b 60 mov %ecx,0x60(%ebx)
> a2e: b8 08 00 00 00 mov $0x8,%eax
> a33: e8 fc ff ff ff call a34 <device_pm_remove+0x2a>
> a38: 89 d8 mov %ebx,%eax
> a3a: e8 fc ff ff ff call a3b <device_pm_remove+0x31>
> a3f: 5b pop %ebx
> a40: 5d pop %ebp
> a41: c3 ret
>
> The offending IP translates to line a23, so the problem is edx being 0
> at that point. I'm not sure which struct device field has offset
> 0x5c, maybe power, but I'm lost at this point anyway.

OK. The rfkill device is removed without being added before! The root
cause is, for non-monitor interfaces, the syntax for
alloc_ieee80211/free_80211 is wrong. Because alloc_ieee80211 only
creates (wiphy_new) a wiphy, but free_80211() does wiphy_unregister()
also. This is only correct when the later wiphy_register() is called
successfully, which apparently is not the case for your fw doesn't exist
one. Please see if this patch fix the problem.

Signed-off-by: Zhu Yi <[email protected]>

diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 240cff1..a741d37 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_ieee80211(priv->ieee);
unregister_netdev(dev);
+ }

ipw2100_hw_stop_adapter(priv);

@@ -6383,6 +6385,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
/* Unregister the device first - this results in close()
* being called if the device is open. If we free storage
* first, then close() will crash. */
+ unregister_ieee80211(priv->ieee);
unregister_netdev(dev);

/* ipw2100_down will ensure that there is no more pending work
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 7f169e1..e2af22b 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,
if (err) {
IPW_ERROR("Failed to register promiscuous network "
"device (error %d).\n", err);
+ unregister_ieee80211(priv->ieee);
unregister_netdev(priv->net_dev);
goto out_remove_sysfs;
}
@@ -11873,6 +11874,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)

mutex_unlock(&priv->mutex);

+ unregister_ieee80211(priv->ieee);
unregister_netdev(priv->net_dev);

if (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);

2009-10-15 13:02:04

by John W. Linville

[permalink] [raw]
Subject: Re: [Ipw2100-devel] 2.6.32-rc4 ipw2200: oops on missing firmware

On Thu, Oct 15, 2009 at 02:50:28PM +0800, Zhu Yi wrote:

> OK. The rfkill device is removed without being added before! The root
> cause is, for non-monitor interfaces, the syntax for
> alloc_ieee80211/free_80211 is wrong. Because alloc_ieee80211 only
> creates (wiphy_new) a wiphy, but free_80211() does wiphy_unregister()
> also. This is only correct when the later wiphy_register() is called
> successfully, which apparently is not the case for your fw doesn't exist
> one. Please see if this patch fix the problem.
>
> Signed-off-by: Zhu Yi <[email protected]>

Thanks, Zhu! That certainly looks better than what I had.

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2009-10-17 02:13:47

by Ferenc Wagner

[permalink] [raw]
Subject: Re: [Ipw2100-devel] 2.6.32-rc4 ipw2200: oops on missing firmware

Zhu Yi <[email protected]> writes:

> OK. The rfkill device is removed without being added before! The root
> cause is, for non-monitor interfaces, the syntax for
> alloc_ieee80211/free_80211 is wrong. Because alloc_ieee80211 only
> creates (wiphy_new) a wiphy, but free_80211() does wiphy_unregister()
> also. This is only correct when the later wiphy_register() is called
> successfully, which apparently is not the case for your fw doesn't exist
> one. Please see if this patch fix the problem.

I confirm that your patch fixes the problem for me. With it, the
kernel doesn't oops and modprobe isn't killed after the firmware load
timeout. Without firmware, the loaded module is nonfunctional, as
expected.
--
Thanks,
Feri.