2.6.0-test9 Fix oops in quirk_via_bridge
PATCH 1/1 2.6.0-test9 Fix oops in quirk_via_bridge
I have a VIA cardbus 1394 controller which oops on insertion after an APM suspend/resume cycle (without card inserted):
bounds: 0000 [#1] CPU: 0 EIP: 0060:[<c0300060>] Tainted: PF EFLAGS: 00010206
EIP is at quirk_via_bridge+0x4/0x1c
eax: 0000ffff ebx: c02982e0 ecx: d1958000 edx: 000c0010
esi: d1958000 edi: 00000001 ebp: 00000000 esp: da401ee8
ds: 007b es: 007b ss: 0068
Process pccardd (pid: 1093, threadinfo=da400000 task=da4c8780)
Stack: c019fb85 d1958000 00000001 d1958000 00000000 c019fbc2 d1958000 00000001
c02980a0 d1958000 dfdebf14 c019d828 00000001 d1958000 00000000 dec2802c
dfdebf00 dfdebf14 00000000 e3dfe7c7 dfdebf00 00000000 dec2802c da401f48
Call Trace:
[<c019fb85>] pci_do_fixups+0x52/0x54
[<c019fbc2>] pci_fixup_device+0x3b/0x49
[<c019d828>] pci_scan_slot+0x46/0x8f
[<e3dfe7c7>] cb_alloc+0x29/0xf7 [pcmcia_core]
[<e3dfb9aa>] socket_insert+0x90/0x102 [pcmcia_core]
[<e3dfbc0d>] socket_detect_change+0x54/0x7e [pcmcia_core]
[<e3dfbdbc>] pccardd+0x185/0x1f9 [pcmcia_core]quirk_via_bridge (which is marked device PCI_ANY_ID) triggers on my 1394 controller which vendor=VIA but is not a bridge.
Strangely making the quirk and its data __devinit solves the problem (as is most of the other stuff in pci/quirks.c). Not sure if it is the correct fix but it works for me. ie. why did I get the oops in the first place? as the quirks data was global and not marked for an __init section.
$ lspci -d 1106: 07:00.0 FireWire (IEEE 1394): VIA Technologies, Inc. IEEE 1394 Host Controller (rev 46)
~mc
drivers/pci/quirks.c +2 -2
@@ -644,9 +644,9 @@* VIA northbridges care about PCI_INTERRUPT_LINE */ -int interrupt_line_quirk; +__devinitdata int interrupt_line_quirk; -static void __init quirk_via_bridge (struct pci_dev *pdev) +static void __devinit quirk_via_bridge (struct pci_dev *pdev) {if (pdev->devfn ==0 ) interrupt_line_quirk =1 ;
Quoted 5 lines · Michael Clark
Strangely making the quirk and its data
__devinitsolves the problem (as is most of the other stuff inpci/quirks.c). Not sure if it is the correct fix but it works for me. ie. why did I get the oops in the first place? as the quirks data was global and not marked for an__initsection.
The function was marked as __init. I'd strongly recommend against marking the data with __devinitdata since its used elsewhere in the kernel by non-init code.
Quoted 15 lines
drivers/pci/quirks.c +2
-2@@ -644,9 +644,9 @@* VIA northbridges care about PCI_INTERRUPT_LINE */ -int interrupt_line_quirk; +__devinitdata int interrupt_line_quirk; -static void __init quirk_via_bridge (struct pci_dev *pdev) +static void __devinit quirk_via_bridge (struct pci_dev *pdev) {if (pdev->devfn ==0 ) interrupt_line_quirk =1 ;
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 9 lines · Russell King
Quoted 5 lines · Michael Clark
Strangely making the quirk and its data
__devinitsolves the problem (as is most of the other stuff inpci/quirks.c). Not sure if it is the correct fix but it works for me. ie. why did I get the oops in the first place? as the quirks data was global and not marked for an__initsection.
Quoted 3 lines
The function was marked as
__init. I'd strongly recommend against marking the data with__devinitdatasince its used elsewhere in the kernel by non-init code.
Sure, okay. So just consider my post a bug report then as i'm not sure what the correct fix is (i'll stick with my patch so I can continue to use firewire on my laptop in the meantime).
Quoted 15 lines
Quoted 15 lines
drivers/pci/quirks.c +2
-2@@ -644,9 +644,9 @@* VIA northbridges care about PCI_INTERRUPT_LINE */ -int interrupt_line_quirk; +__devinitdata int interrupt_line_quirk; -static void __init quirk_via_bridge (struct pci_dev *pdev) +static void __devinit quirk_via_bridge (struct pci_dev *pdev) {if (pdev->devfn ==0 ) interrupt_line_quirk =1 ;
Quoted 3 lines · Michael Clark
Sure, okay. So just consider my post a bug report then as i'm not sure what the correct fix is (i'll stick with my patch so I can continue to use firewire on my laptop in the meantime).
Your fix looks 99% correct, except for the "__devinitdata" part - if you drop this and resubmit the patch, I'm sure gregkh will take it.
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 4 lines · Russell King
On Fri, Oct 31, 2003 at 05:58:39PM +0800, Michael Clark wrote:
Your fix looks 99% correct, except for the "
__devinitdata" part - if you drop this and resubmit the patch, I'm sure gregkh will take it.
Cool. dropped __devinitdata, tested and works. Now I can suspend and resume then insert my ieee1394 cardbus controller with no oops.
~mc
drivers/pci/quirks.c +1 -1
@@ -646,7 +646,7 @@int interrupt_line_quirk; -static void __init quirk_via_bridge (struct pci_dev *pdev) +static void __devinit quirk_via_bridge (struct pci_dev *pdev) {if (pdev->devfn ==0 ) interrupt_line_quirk =1 ;
Quoted 8 lines · Michael Clark
Quoted 4 lines · Russell King
On Fri, Oct 31, 2003 at 05:58:39PM +0800, Michael Clark wrote:
Your fix looks 99% correct, except for the "
__devinitdata" part - if you drop this and resubmit the patch, I'm sure gregkh will take it.Cool. dropped
__devinitdata, tested and works. Now I can suspend and resume then insert my ieee1394 cardbus controller with no oops.
Thanks, I've applied this and will send it on to Linus in a bit.
greg k-h