diff options
author | Mike McCormack <mikem@ring3k.org> | 2009-08-31 23:21:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-01 20:40:42 -0400 |
commit | 90bbebb4a8258a398705ecaa2e6b9e177928ee7a (patch) | |
tree | b42a5319440725da3b296bcc727672ba7107452c /drivers/net/sky2.c | |
parent | 10547ae2c01acdace636e23c991b21fef05428b4 (diff) |
sky2: Create buffer alloc and free helpers
Refactor similar two sections of code that free buffers into one.
Only call tx_init if all buffer allocations succeed.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 113 |
1 files changed, 60 insertions, 53 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ba5180a23264..7108b1292b92 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1405,6 +1405,61 @@ nomem: | |||
1405 | return -ENOMEM; | 1405 | return -ENOMEM; |
1406 | } | 1406 | } |
1407 | 1407 | ||
1408 | static int sky2_alloc_buffers(struct sky2_port *sky2) | ||
1409 | { | ||
1410 | struct sky2_hw *hw = sky2->hw; | ||
1411 | |||
1412 | /* must be power of 2 */ | ||
1413 | sky2->tx_le = pci_alloc_consistent(hw->pdev, | ||
1414 | sky2->tx_ring_size * | ||
1415 | sizeof(struct sky2_tx_le), | ||
1416 | &sky2->tx_le_map); | ||
1417 | if (!sky2->tx_le) | ||
1418 | goto nomem; | ||
1419 | |||
1420 | sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info), | ||
1421 | GFP_KERNEL); | ||
1422 | if (!sky2->tx_ring) | ||
1423 | goto nomem; | ||
1424 | |||
1425 | sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES, | ||
1426 | &sky2->rx_le_map); | ||
1427 | if (!sky2->rx_le) | ||
1428 | goto nomem; | ||
1429 | memset(sky2->rx_le, 0, RX_LE_BYTES); | ||
1430 | |||
1431 | sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info), | ||
1432 | GFP_KERNEL); | ||
1433 | if (!sky2->rx_ring) | ||
1434 | goto nomem; | ||
1435 | |||
1436 | return 0; | ||
1437 | nomem: | ||
1438 | return -ENOMEM; | ||
1439 | } | ||
1440 | |||
1441 | static void sky2_free_buffers(struct sky2_port *sky2) | ||
1442 | { | ||
1443 | struct sky2_hw *hw = sky2->hw; | ||
1444 | |||
1445 | if (sky2->rx_le) { | ||
1446 | pci_free_consistent(hw->pdev, RX_LE_BYTES, | ||
1447 | sky2->rx_le, sky2->rx_le_map); | ||
1448 | sky2->rx_le = NULL; | ||
1449 | } | ||
1450 | if (sky2->tx_le) { | ||
1451 | pci_free_consistent(hw->pdev, | ||
1452 | sky2->tx_ring_size * sizeof(struct sky2_tx_le), | ||
1453 | sky2->tx_le, sky2->tx_le_map); | ||
1454 | sky2->tx_le = NULL; | ||
1455 | } | ||
1456 | kfree(sky2->tx_ring); | ||
1457 | kfree(sky2->rx_ring); | ||
1458 | |||
1459 | sky2->tx_ring = NULL; | ||
1460 | sky2->rx_ring = NULL; | ||
1461 | } | ||
1462 | |||
1408 | /* Bring up network interface. */ | 1463 | /* Bring up network interface. */ |
1409 | static int sky2_up(struct net_device *dev) | 1464 | static int sky2_up(struct net_device *dev) |
1410 | { | 1465 | { |
@@ -1412,7 +1467,7 @@ static int sky2_up(struct net_device *dev) | |||
1412 | struct sky2_hw *hw = sky2->hw; | 1467 | struct sky2_hw *hw = sky2->hw; |
1413 | unsigned port = sky2->port; | 1468 | unsigned port = sky2->port; |
1414 | u32 imask, ramsize; | 1469 | u32 imask, ramsize; |
1415 | int cap, err = -ENOMEM; | 1470 | int cap, err; |
1416 | struct net_device *otherdev = hw->dev[sky2->port^1]; | 1471 | struct net_device *otherdev = hw->dev[sky2->port^1]; |
1417 | 1472 | ||
1418 | /* | 1473 | /* |
@@ -1431,32 +1486,12 @@ static int sky2_up(struct net_device *dev) | |||
1431 | 1486 | ||
1432 | netif_carrier_off(dev); | 1487 | netif_carrier_off(dev); |
1433 | 1488 | ||
1434 | /* must be power of 2 */ | 1489 | err = sky2_alloc_buffers(sky2); |
1435 | sky2->tx_le = pci_alloc_consistent(hw->pdev, | 1490 | if (err) |
1436 | sky2->tx_ring_size * | ||
1437 | sizeof(struct sky2_tx_le), | ||
1438 | &sky2->tx_le_map); | ||
1439 | if (!sky2->tx_le) | ||
1440 | goto err_out; | ||
1441 | |||
1442 | sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info), | ||
1443 | GFP_KERNEL); | ||
1444 | if (!sky2->tx_ring) | ||
1445 | goto err_out; | 1491 | goto err_out; |
1446 | 1492 | ||
1447 | tx_init(sky2); | 1493 | tx_init(sky2); |
1448 | 1494 | ||
1449 | sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES, | ||
1450 | &sky2->rx_le_map); | ||
1451 | if (!sky2->rx_le) | ||
1452 | goto err_out; | ||
1453 | memset(sky2->rx_le, 0, RX_LE_BYTES); | ||
1454 | |||
1455 | sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info), | ||
1456 | GFP_KERNEL); | ||
1457 | if (!sky2->rx_ring) | ||
1458 | goto err_out; | ||
1459 | |||
1460 | sky2_mac_init(hw, port); | 1495 | sky2_mac_init(hw, port); |
1461 | 1496 | ||
1462 | /* Register is number of 4K blocks on internal RAM buffer. */ | 1497 | /* Register is number of 4K blocks on internal RAM buffer. */ |
@@ -1513,22 +1548,7 @@ static int sky2_up(struct net_device *dev) | |||
1513 | return 0; | 1548 | return 0; |
1514 | 1549 | ||
1515 | err_out: | 1550 | err_out: |
1516 | if (sky2->rx_le) { | 1551 | sky2_free_buffers(sky2); |
1517 | pci_free_consistent(hw->pdev, RX_LE_BYTES, | ||
1518 | sky2->rx_le, sky2->rx_le_map); | ||
1519 | sky2->rx_le = NULL; | ||
1520 | } | ||
1521 | if (sky2->tx_le) { | ||
1522 | pci_free_consistent(hw->pdev, | ||
1523 | sky2->tx_ring_size * sizeof(struct sky2_tx_le), | ||
1524 | sky2->tx_le, sky2->tx_le_map); | ||
1525 | sky2->tx_le = NULL; | ||
1526 | } | ||
1527 | kfree(sky2->tx_ring); | ||
1528 | kfree(sky2->rx_ring); | ||
1529 | |||
1530 | sky2->tx_ring = NULL; | ||
1531 | sky2->rx_ring = NULL; | ||
1532 | return err; | 1552 | return err; |
1533 | } | 1553 | } |
1534 | 1554 | ||
@@ -1880,20 +1900,7 @@ static int sky2_down(struct net_device *dev) | |||
1880 | 1900 | ||
1881 | sky2_rx_clean(sky2); | 1901 | sky2_rx_clean(sky2); |
1882 | 1902 | ||
1883 | pci_free_consistent(hw->pdev, RX_LE_BYTES, | 1903 | sky2_free_buffers(sky2); |
1884 | sky2->rx_le, sky2->rx_le_map); | ||
1885 | kfree(sky2->rx_ring); | ||
1886 | |||
1887 | pci_free_consistent(hw->pdev, | ||
1888 | sky2->tx_ring_size * sizeof(struct sky2_tx_le), | ||
1889 | sky2->tx_le, sky2->tx_le_map); | ||
1890 | kfree(sky2->tx_ring); | ||
1891 | |||
1892 | sky2->tx_le = NULL; | ||
1893 | sky2->rx_le = NULL; | ||
1894 | |||
1895 | sky2->rx_ring = NULL; | ||
1896 | sky2->tx_ring = NULL; | ||
1897 | 1904 | ||
1898 | return 0; | 1905 | return 0; |
1899 | } | 1906 | } |