diff options
| author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2013-05-09 07:14:07 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-05-11 20:40:14 -0400 |
| commit | 4b264a1676e70dc656ba53a8cac690f2d4b65f4e (patch) | |
| tree | cab97086e17afe834d12555c7fbee6821d0837d9 /drivers/net/ethernet/3com | |
| parent | 79e0c19e85cd1617efcf441988a206ffc96b56a1 (diff) | |
3c59x: fix PCI resource management
The driver wrongly claimed I/O ports at an address returned by pci_iomap() --
even if it was passed an MMIO address. Fix this by claiming/releasing all PCI
resources in the PCI driver's probe()/remove() methods instead and get rid of
'must_free_region' flag weirdness (why would Cardbus claim anything for us?).
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/3com')
| -rw-r--r-- | drivers/net/ethernet/3com/3c59x.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index de570a8f8967..072c6f14e8fc 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
| @@ -632,7 +632,6 @@ struct vortex_private { | |||
| 632 | pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ | 632 | pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ |
| 633 | open:1, | 633 | open:1, |
| 634 | medialock:1, | 634 | medialock:1, |
| 635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ | ||
| 636 | large_frames:1, /* accept large frames */ | 635 | large_frames:1, /* accept large frames */ |
| 637 | handling_irq:1; /* private in_irq indicator */ | 636 | handling_irq:1; /* private in_irq indicator */ |
| 638 | /* {get|set}_wol operations are already serialized by rtnl. | 637 | /* {get|set}_wol operations are already serialized by rtnl. |
| @@ -1012,6 +1011,12 @@ static int vortex_init_one(struct pci_dev *pdev, | |||
| 1012 | if (rc < 0) | 1011 | if (rc < 0) |
| 1013 | goto out; | 1012 | goto out; |
| 1014 | 1013 | ||
| 1014 | rc = pci_request_regions(pdev, DRV_NAME); | ||
| 1015 | if (rc < 0) { | ||
| 1016 | pci_disable_device(pdev); | ||
| 1017 | goto out; | ||
| 1018 | } | ||
| 1019 | |||
| 1015 | unit = vortex_cards_found; | 1020 | unit = vortex_cards_found; |
| 1016 | 1021 | ||
| 1017 | if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) { | 1022 | if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) { |
| @@ -1027,6 +1032,7 @@ static int vortex_init_one(struct pci_dev *pdev, | |||
| 1027 | if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */ | 1032 | if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */ |
| 1028 | ioaddr = pci_iomap(pdev, 0, 0); | 1033 | ioaddr = pci_iomap(pdev, 0, 0); |
| 1029 | if (!ioaddr) { | 1034 | if (!ioaddr) { |
| 1035 | pci_release_regions(pdev); | ||
| 1030 | pci_disable_device(pdev); | 1036 | pci_disable_device(pdev); |
| 1031 | rc = -ENOMEM; | 1037 | rc = -ENOMEM; |
| 1032 | goto out; | 1038 | goto out; |
| @@ -1036,6 +1042,7 @@ static int vortex_init_one(struct pci_dev *pdev, | |||
| 1036 | ent->driver_data, unit); | 1042 | ent->driver_data, unit); |
| 1037 | if (rc < 0) { | 1043 | if (rc < 0) { |
| 1038 | pci_iounmap(pdev, ioaddr); | 1044 | pci_iounmap(pdev, ioaddr); |
| 1045 | pci_release_regions(pdev); | ||
| 1039 | pci_disable_device(pdev); | 1046 | pci_disable_device(pdev); |
| 1040 | goto out; | 1047 | goto out; |
| 1041 | } | 1048 | } |
| @@ -1178,11 +1185,6 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, | |||
| 1178 | 1185 | ||
| 1179 | /* PCI-only startup logic */ | 1186 | /* PCI-only startup logic */ |
| 1180 | if (pdev) { | 1187 | if (pdev) { |
| 1181 | /* EISA resources already marked, so only PCI needs to do this here */ | ||
| 1182 | /* Ignore return value, because Cardbus drivers already allocate for us */ | ||
| 1183 | if (request_region(dev->base_addr, vci->io_size, print_name) != NULL) | ||
| 1184 | vp->must_free_region = 1; | ||
| 1185 | |||
| 1186 | /* enable bus-mastering if necessary */ | 1188 | /* enable bus-mastering if necessary */ |
| 1187 | if (vci->flags & PCI_USES_MASTER) | 1189 | if (vci->flags & PCI_USES_MASTER) |
| 1188 | pci_set_master(pdev); | 1190 | pci_set_master(pdev); |
| @@ -1220,7 +1222,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, | |||
| 1220 | &vp->rx_ring_dma); | 1222 | &vp->rx_ring_dma); |
| 1221 | retval = -ENOMEM; | 1223 | retval = -ENOMEM; |
| 1222 | if (!vp->rx_ring) | 1224 | if (!vp->rx_ring) |
| 1223 | goto free_region; | 1225 | goto free_device; |
| 1224 | 1226 | ||
| 1225 | vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE); | 1227 | vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE); |
| 1226 | vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE; | 1228 | vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE; |
| @@ -1484,9 +1486,7 @@ free_ring: | |||
| 1484 | + sizeof(struct boom_tx_desc) * TX_RING_SIZE, | 1486 | + sizeof(struct boom_tx_desc) * TX_RING_SIZE, |
| 1485 | vp->rx_ring, | 1487 | vp->rx_ring, |
| 1486 | vp->rx_ring_dma); | 1488 | vp->rx_ring_dma); |
| 1487 | free_region: | 1489 | free_device: |
| 1488 | if (vp->must_free_region) | ||
| 1489 | release_region(dev->base_addr, vci->io_size); | ||
| 1490 | free_netdev(dev); | 1490 | free_netdev(dev); |
| 1491 | pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval); | 1491 | pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval); |
| 1492 | out: | 1492 | out: |
| @@ -3254,8 +3254,9 @@ static void vortex_remove_one(struct pci_dev *pdev) | |||
| 3254 | + sizeof(struct boom_tx_desc) * TX_RING_SIZE, | 3254 | + sizeof(struct boom_tx_desc) * TX_RING_SIZE, |
| 3255 | vp->rx_ring, | 3255 | vp->rx_ring, |
| 3256 | vp->rx_ring_dma); | 3256 | vp->rx_ring_dma); |
| 3257 | if (vp->must_free_region) | 3257 | |
| 3258 | release_region(dev->base_addr, vp->io_size); | 3258 | pci_release_regions(pdev); |
| 3259 | |||
| 3259 | free_netdev(dev); | 3260 | free_netdev(dev); |
| 3260 | } | 3261 | } |
| 3261 | 3262 | ||
