Bug 40772

Summary: p54pci fails to load firmware on resume from standby
Product: Drivers Reporter: David Leemans (d_leemans)
Component: network-wirelessAssignee: drivers_network-wireless (drivers_network-wireless)
Status: NEEDINFO ---    
Severity: normal CC: alan, chunkeey, linville
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 3.0.1 Subsystem:
Regression: No Bisected commit-id:
Attachments: dmesg from kernel 3.0.1
dmesg from kernel 3.2.1
resume test patch

Description David Leemans 2011-08-09 16:59:11 UTC
Hi,

The card is an SMC 2835W v2 (cardbus adapter). In general, it works fine with the p54pci driver. However, each time the laptop resumes from S3, the card stays dead. In dmesg, I find messages about the driver not being able to find the firmware file (isl3886pci). The driver then seems to crash.

The only thing I can do then to make the card work again is to eject and reinsert it (either manually or with pccardctl).
Comment 1 Christian Lamparter 2011-08-10 04:42:46 UTC
We know!

http://www.spinics.net/lists/linux-wireless/msg49956.html

The reason are a more complicated though since it affects other
drivers as well. The original post also had a patch, but I doubt
it will still apply without serious complains. Anyway, if you're
just looking for a fix the easiest option would be to include
the firmware blob into the kernel. Just follow the config menu
options

Device Drivers  ---> 
  Generic Driver Options  --->
     -*- Userspace firmware loading support
      [*]   Include in-kernel firmware blobs in kernel binary 
      External firmware blobs to build into the kernel binary (path to isl3886pci)

(and you are good to go).
Comment 2 David Leemans 2011-08-10 09:51:14 UTC
(In reply to comment #1)
> We know!
> 
> http://www.spinics.net/lists/linux-wireless/msg49956.html
> 
> The reason are a more complicated though since it affects other
> drivers as well. The original post also had a patch, but I doubt
> it will still apply without serious complains. Anyway, if you're
> just looking for a fix the easiest option would be to include
> the firmware blob into the kernel. Just follow the config menu
> options
> 
> Device Drivers  ---> 
>   Generic Driver Options  --->
>      -*- Userspace firmware loading support
>       [*]   Include in-kernel firmware blobs in kernel binary 
>       External firmware blobs to build into the kernel binary (path to
> isl3886pci)
> 
> (and you are good to go).

I will give this a try and report back.
Comment 3 David Leemans 2011-08-10 14:03:36 UTC
(In reply to comment #2)

> 
> I will give this a try and report back.

Hmm, this doesn't seem to work, unless I'm doing something wrong. 
My kernel image seems to have grown approx. the size of the firmware blob, so that looks OK. However, upon resume from S3, the driver still crashes and complains about not finding the firmware.
Is there a way to verify that the driver is now loading the firmware from the kernel rather then from the filesystem ?
I have attached dmesg from right after resuming.
Comment 4 David Leemans 2011-08-10 14:07:58 UTC
Created attachment 68352 [details]
dmesg from kernel 3.0.1

The most relevant information is most likely at the end. You will also notice that I ejected and inserted the card after resume.
Comment 5 John W. Linville 2012-01-13 19:05:36 UTC
Does this problem persist with kernel 3.2 or later?
Comment 6 David Leemans 2012-01-20 16:27:40 UTC
(In reply to comment #5)
> Does this problem persist with kernel 3.2 or later?

No, problem seems to be solved on kernel 3.2.1. The card works fine after resume from S3 (tried it several times). 
However, dmesg shows the driver crashes, during the resume process ? I attached the dmesg. This doesn't seem to hurt, as the card just works, and immediately reconnects upon resume.
Comment 7 David Leemans 2012-01-20 16:29:35 UTC
Created attachment 72136 [details]
dmesg from kernel 3.2.1
Comment 8 John W. Linville 2012-01-26 17:21:49 UTC
That warning indicates freeing an irq that is already free...

p54pci calls free_irq in two places, in p54p_stop and (in case of a failure after request_irq) in p54p_open.  At first glance that looks fine.

p54p_open is called in p54p_resume _except_ if the device is in NL80211_IFTYPE_UNSPECIFIED mode.  I'm not sure what the basis for the concern is here?  Anyway, if p54p_resume is called while the device is in NL80211_IFTYPE_UNSPECIFIED mode and then p54p_stop is called then this error would occur.  I'm not sure if that is what is happening or not.

Chr, can you comment?
Comment 9 Christian Lamparter 2012-01-26 18:11:45 UTC
Oh, well. I think the idea to check whenever the the device was still active/running while the pc/laptop was going to suspend. So on resume, the
device could be restored to its "previous" state.

However, the dmesg tells a different story. On resume, the pcmcia subsystem decided to unbind the device from the bus BEFORE calling p54p_resume.
In this case, p54p_stop gets called twice simply because it is also called when all interfaces are brought down by p54_stop during the unbind procedure.

the easiest way out would be to add a flag to prevent the warning from
__free_irq.
Comment 10 Christian Lamparter 2012-01-26 18:13:54 UTC
Created attachment 72207 [details]
resume test patch

Hopefully, this will silence the warning and won't break the other pci resume path.
Comment 11 Alan 2012-05-12 13:54:34 UTC
Was a suitable fix merged ?
Comment 12 Christian Lamparter 2012-05-22 20:12:18 UTC
(In reply to comment #11)
> Was a suitable fix merged ?

Partially. Testing patches (RFT) have been posted long ago:
[RFT 1/2] p54pci: convert driver to use asynchronous firmware loading
[RFT 2/2] p54: only unregister ieee80211_hw when it has been registered
(and no reply)

But unfortunately they sort of depend on another this particular patch: <http://lkml.indiana.edu/hypermail/linux/kernel/1203.0/01161.html> to work
in the first place and I never got any word from the pcmcia list.