diff options
author | Marcelo Tosatti <marcelo.tosatti@cyclades.com> | 2005-04-26 16:09:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-26 16:09:35 -0400 |
commit | e8108c98dd6d65613fa0ec9d2300f89c48d554bf (patch) | |
tree | 3608de2fc88b062070a9d197eda9cac1fb9635d3 /drivers | |
parent | efa545791ff439d778f79d02255d59ff1f7ea0fc (diff) |
[PATCH] PC300 pci_enable_device fix
Call pci_enable_device() before looking at IRQ and resources,
and pci_disable_device() when shutting the interface down.
The driver requires this fix or the "pci=routeirq" workaround
on 2.6.10 and later kernels.
Reported and tested by Artur Lipowski.
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Marcelo Tosatti <marcelo.tosatti@cyclades.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wan/pc300_drv.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index d67be2587d4d..3e7753b10717 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
@@ -3427,7 +3427,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3427 | { | 3427 | { |
3428 | static int first_time = 1; | 3428 | static int first_time = 1; |
3429 | ucchar cpc_rev_id; | 3429 | ucchar cpc_rev_id; |
3430 | int err = 0, eeprom_outdated = 0; | 3430 | int err, eeprom_outdated = 0; |
3431 | ucshort device_id; | 3431 | ucshort device_id; |
3432 | pc300_t *card; | 3432 | pc300_t *card; |
3433 | 3433 | ||
@@ -3439,15 +3439,21 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3439 | #endif | 3439 | #endif |
3440 | } | 3440 | } |
3441 | 3441 | ||
3442 | if ((err = pci_enable_device(pdev)) < 0) | ||
3443 | return err; | ||
3444 | |||
3442 | card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); | 3445 | card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); |
3443 | if (card == NULL) { | 3446 | if (card == NULL) { |
3444 | printk("PC300 found at RAM 0x%08lx, " | 3447 | printk("PC300 found at RAM 0x%08lx, " |
3445 | "but could not allocate card structure.\n", | 3448 | "but could not allocate card structure.\n", |
3446 | pci_resource_start(pdev, 3)); | 3449 | pci_resource_start(pdev, 3)); |
3447 | return -ENOMEM; | 3450 | err = -ENOMEM; |
3451 | goto err_disable_dev; | ||
3448 | } | 3452 | } |
3449 | memset(card, 0, sizeof(pc300_t)); | 3453 | memset(card, 0, sizeof(pc300_t)); |
3450 | 3454 | ||
3455 | err = -ENODEV; | ||
3456 | |||
3451 | /* read PCI configuration area */ | 3457 | /* read PCI configuration area */ |
3452 | device_id = ent->device; | 3458 | device_id = ent->device; |
3453 | card->hw.irq = pdev->irq; | 3459 | card->hw.irq = pdev->irq; |
@@ -3507,7 +3513,6 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3507 | printk("PC300 found at RAM 0x%08x, " | 3513 | printk("PC300 found at RAM 0x%08x, " |
3508 | "but could not allocate PLX mem region.\n", | 3514 | "but could not allocate PLX mem region.\n", |
3509 | card->hw.ramphys); | 3515 | card->hw.ramphys); |
3510 | err = -ENODEV; | ||
3511 | goto err_release_io; | 3516 | goto err_release_io; |
3512 | } | 3517 | } |
3513 | if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize, | 3518 | if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize, |
@@ -3515,7 +3520,6 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3515 | printk("PC300 found at RAM 0x%08x, " | 3520 | printk("PC300 found at RAM 0x%08x, " |
3516 | "but could not allocate RAM mem region.\n", | 3521 | "but could not allocate RAM mem region.\n", |
3517 | card->hw.ramphys); | 3522 | card->hw.ramphys); |
3518 | err = -ENODEV; | ||
3519 | goto err_release_plx; | 3523 | goto err_release_plx; |
3520 | } | 3524 | } |
3521 | if (!request_mem_region(card->hw.scaphys, card->hw.scasize, | 3525 | if (!request_mem_region(card->hw.scaphys, card->hw.scasize, |
@@ -3523,13 +3527,9 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3523 | printk("PC300 found at RAM 0x%08x, " | 3527 | printk("PC300 found at RAM 0x%08x, " |
3524 | "but could not allocate SCA mem region.\n", | 3528 | "but could not allocate SCA mem region.\n", |
3525 | card->hw.ramphys); | 3529 | card->hw.ramphys); |
3526 | err = -ENODEV; | ||
3527 | goto err_release_ram; | 3530 | goto err_release_ram; |
3528 | } | 3531 | } |
3529 | 3532 | ||
3530 | if ((err = pci_enable_device(pdev)) != 0) | ||
3531 | goto err_release_sca; | ||
3532 | |||
3533 | card->hw.plxbase = ioremap(card->hw.plxphys, card->hw.plxsize); | 3533 | card->hw.plxbase = ioremap(card->hw.plxphys, card->hw.plxsize); |
3534 | card->hw.rambase = ioremap(card->hw.ramphys, card->hw.alloc_ramsize); | 3534 | card->hw.rambase = ioremap(card->hw.ramphys, card->hw.alloc_ramsize); |
3535 | card->hw.scabase = ioremap(card->hw.scaphys, card->hw.scasize); | 3535 | card->hw.scabase = ioremap(card->hw.scaphys, card->hw.scasize); |
@@ -3619,7 +3619,6 @@ err_io_unmap: | |||
3619 | iounmap(card->hw.falcbase); | 3619 | iounmap(card->hw.falcbase); |
3620 | release_mem_region(card->hw.falcphys, card->hw.falcsize); | 3620 | release_mem_region(card->hw.falcphys, card->hw.falcsize); |
3621 | } | 3621 | } |
3622 | err_release_sca: | ||
3623 | release_mem_region(card->hw.scaphys, card->hw.scasize); | 3622 | release_mem_region(card->hw.scaphys, card->hw.scasize); |
3624 | err_release_ram: | 3623 | err_release_ram: |
3625 | release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); | 3624 | release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); |
@@ -3628,7 +3627,9 @@ err_release_plx: | |||
3628 | err_release_io: | 3627 | err_release_io: |
3629 | release_region(card->hw.iophys, card->hw.iosize); | 3628 | release_region(card->hw.iophys, card->hw.iosize); |
3630 | kfree(card); | 3629 | kfree(card); |
3631 | return -ENODEV; | 3630 | err_disable_dev: |
3631 | pci_disable_device(pdev); | ||
3632 | return err; | ||
3632 | } | 3633 | } |
3633 | 3634 | ||
3634 | static void __devexit cpc_remove_one(struct pci_dev *pdev) | 3635 | static void __devexit cpc_remove_one(struct pci_dev *pdev) |
@@ -3662,6 +3663,7 @@ static void __devexit cpc_remove_one(struct pci_dev *pdev) | |||
3662 | if (card->hw.irq) | 3663 | if (card->hw.irq) |
3663 | free_irq(card->hw.irq, card); | 3664 | free_irq(card->hw.irq, card); |
3664 | kfree(card); | 3665 | kfree(card); |
3666 | pci_disable_device(pdev); | ||
3665 | } | 3667 | } |
3666 | } | 3668 | } |
3667 | 3669 | ||