Skip to contentSkip to conversation

2.6.0-test9 Fix oops in quirk_via_bridge

PATCH In review Michael Clark 3 participants 6 messages Oct 31, 2003 – Nov 7, 2003 PCI

lore
Share & tools
lore
#0 lore raw

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;
#1 lore raw
Quoted 5 lines · Michael Clark

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.

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 core
#2 lore raw
Quoted 9 lines · Russell King
Quoted 5 lines · Michael Clark

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.

Quoted 3 lines

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.

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;
#3 lore raw
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 core
#4 lore raw
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.

~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;
#5 lore raw
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