Commit 139292f2 authored by Andrew Morton's avatar Andrew Morton Committed by Jeff Garzik

[PATCH] e100: early reset fix

Gents, what do we think of the below fix?

Thanks.

My IBM A21P laptop is getting an IRQ storm at boot.

IRQ #11 is shared between USB and e100, and USB is getting in there first.
Consequently, when e100 initialises the hardware, that interrupt line is ready
to go.  As soon as e100.c runs pci_set_master(), the interrupt hits the CPU.
But of course the e100 driver isn't ready to handle the interrupt yet, so the
system disables IRQ #11.

This only happens on warm boots (/sbin/reboot).  Things work OK from power-on.
 So I assume that the BIOS is failing to fully reset the NIC and that some
sort of interrupt is internally pending.

The patch rearranges e100_probe() so that we issue e100_hw_reset() prior to
running pci_set_master(), and fixes the problem.

Note that e100_probe() is now running e100_hw_reset() twice - I didn't remove
the later call for general paranoia reasons.

eepro100.c has the same lockup, and needs a similar fix.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 0a57a616
...@@ -2204,23 +2204,25 @@ static int __devinit e100_probe(struct pci_dev *pdev, ...@@ -2204,23 +2204,25 @@ static int __devinit e100_probe(struct pci_dev *pdev,
goto err_out_disable_pdev; goto err_out_disable_pdev;
} }
nic->csr = ioremap(pci_resource_start(pdev, 0), sizeof(struct csr));
if(!nic->csr) {
DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n");
err = -ENOMEM;
goto err_out_free_res;
}
e100_hw_reset(nic);
pci_set_master(pdev); pci_set_master(pdev);
if((err = pci_set_dma_mask(pdev, 0xFFFFFFFFULL))) { if((err = pci_set_dma_mask(pdev, 0xFFFFFFFFULL))) {
DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n"); DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
goto err_out_free_res; goto err_out_iounmap;
} }
SET_MODULE_OWNER(netdev); SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &pdev->dev); SET_NETDEV_DEV(netdev, &pdev->dev);
nic->csr = ioremap(pci_resource_start(pdev, 0), sizeof(struct csr));
if(!nic->csr) {
DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n");
err = -ENOMEM;
goto err_out_free_res;
}
if(ent->driver_data) if(ent->driver_data)
nic->flags |= ich; nic->flags |= ich;
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment