• Anton Vorontsov's avatar
    3c59x: Get rid of "Trying to free already-free IRQ" · 704cc92e
    Anton Vorontsov authored
    Following trace pops up if we try to suspend with 3c59x ethernet NIC
    brought down:
    
      root@b1:~# ifconfig eth16 down
      root@b1:~# echo mem > /sys/power/state
      ...
      3c59x 0000:00:10.0: suspend
      3c59x 0000:00:10.0: PME# disabled
      Trying to free already-free IRQ 48
      ------------[ cut here ]------------
      Badness at c00554e4 [verbose debug info unavailable]
      NIP: c00554e4 LR: c00554e4 CTR: c019a098
      REGS: c7975c60 TRAP: 0700   Not tainted  (2.6.31-rc4)
      MSR: 00021032 <ME,CE,IR,DR>  CR: 28242422  XER: 20000000
      TASK = c79cb0c0[1746] 'bash' THREAD: c7974000
      ...
      NIP [c00554e4] __free_irq+0x108/0x1b0
      LR [c00554e4] __free_irq+0x108/0x1b0
      Call Trace:
      [c7975d10] [c00554e4] __free_irq+0x108/0x1b0 (unreliable)
      [c7975d30] [c005559c] free_irq+0x10/0x24
      [c7975d40] [c01e21ec] vortex_suspend+0x70/0xc4
      [c7975d60] [c017e584] pci_legacy_suspend+0x58/0x100
    
    This is because the driver manages interrupts without checking for
    netif_running().
    
    Though, there are few other issues with suspend/resume in this driver.
    The intention of calling free_irq() in suspend() was to avoid any
    possible spurious interrupts (see commit 5b039e68
    "3c59x PM fixes"). But,
    
    - On resume, the driver was requesting IRQ just after pci_set_master(),
      but before vortex_up() (which actually resets 3c59x chips).
    
    - Issuing free_irq() on a shared IRQ doesn't guarantee that a buggy
      HW won't trigger spurious interrupts in another driver that
      requested the same interrupt. So, if we want to protect from
      unexpected interrupts, then on suspend we should issue disable_irq(),
      not free_irq().
    Signed-off-by: default avatarAnton Vorontsov <avorontsov@ru.mvista.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    704cc92e
3c59x.c 101 KB