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 | |
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>
-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 | ||