Hi Marcelo,
I found this message from you in the archives... I have a patch for this problem now:
Marcelo Tosatti wrote:
Hi,
Had an issue today with 2.6.4-rc2 and a pcmcia 3c59x card on my laptop.
Suddenly it stopped working, I tried rmmoding and reloading the driver, but no success.
Rebooting the kernel made it work again.
If you need more information, just ask.
[snip]
Looks like your problem is caused by suspend. I see the exact same problem after S3 resume on my ACPI desktop system with a PCI 3c59x. I am attaching a patch which works on my PCI desktop, could you also test it on your cardbus/laptop setup?hda: start_power_step(step: 0) hda: start_power_step(step: 1) hda: complete_power_step(step: 1, stat: 50, err: 0) hda: completing PM request, suspend PCI: Guessed IRQ 10 for device 0000:00:0b.0 PCI: Sharing IRQ 10 with 0000:00:0a.0 hda: Wakeup request inited, waiting for !BSY... hda: start_power_step(step: 1000) blk: queue cb596e00, I/O limit 4095Mb (mask 0xffffffff) hda: completing PM request, resume spurious 8259A interrupt: IRQ7. eth0: command 0x5800 did not complete! Status=0xffff
The problem is that under the new PCI driver model, cards are required to always restore state and call pci_enable_device() on resume. So the patch changes the driver to do its restore state calls unconditionally (it used to only do them when it was configured for wake-on-lan) and adds a call to pci_enable_device().
Maybe we should also be disabling bus-master on suspend, but I didn't want to change any more than I had to.
(By CC to Jeff - is this ok for the netdev tree?)
Nathan
===== drivers/net/3c59x.c 1.57 vs edited ===== --- 1.57/drivers/net/3c59x.c 2004-07-14 04:13:48 -04:00 +++ edited/drivers/net/3c59x.c 2004-08-11 22:32:58 -04:00 @@ -1476,7 +1476,7 @@ #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = poll_vortex; #endif - if (pdev && vp->enable_wol) { + if (pdev) { vp->pm_state_valid = 1; pci_save_state(VORTEX_PCI(vp), vp->power_state); acpi_set_WOL(dev); @@ -1533,9 +1533,10 @@ unsigned int config; int i; - if (VORTEX_PCI(vp) && vp->enable_wol) { + if (VORTEX_PCI(vp)) { pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ pci_restore_state(VORTEX_PCI(vp), vp->power_state); + pci_enable_device(VORTEX_PCI(vp)); } /* Before initializing select the active media port. */ @@ -2684,7 +2685,7 @@ if (vp->full_bus_master_tx) outl(0, ioaddr + DownListPtr); - if (final_down && VORTEX_PCI(vp) && vp->enable_wol) { + if (final_down && VORTEX_PCI(vp)) { pci_save_state(VORTEX_PCI(vp), vp->power_state); acpi_set_WOL(dev); } @@ -3052,15 +3053,17 @@ struct vortex_private *vp = netdev_priv(dev); long ioaddr = dev->base_addr; - /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ - EL3WINDOW(7); - outw(2, ioaddr + 0x0c); - /* The RxFilter must accept the WOL frames. */ - outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); - outw(RxEnable, ioaddr + EL3_CMD); + if (vp->enable_wol) { + /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ + EL3WINDOW(7); + outw(2, ioaddr + 0x0c); + /* The RxFilter must accept the WOL frames. */ + outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); + outw(RxEnable, ioaddr + EL3_CMD); + pci_enable_wake(VORTEX_PCI(vp), 0, 1); + } /* Change the power state to D3; RxEnable doesn't take effect. */ - pci_enable_wake(VORTEX_PCI(vp), 0, 1); pci_set_power_state(VORTEX_PCI(vp), 3); } @@ -3083,7 +3086,7 @@ */ unregister_netdev(dev); - if (VORTEX_PCI(vp) && vp->enable_wol) { + if (VORTEX_PCI(vp)) { pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */ if (vp->pm_state_valid) pci_restore_state(VORTEX_PCI(vp), vp->power_state);