diff options
author | Michael Chan <mchan@broadcom.com> | 2012-09-08 02:01:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-09-10 15:48:20 -0400 |
commit | 74dd0c42093e0fd70ca7d901d18c2c01a6fd0fd3 (patch) | |
tree | 2c31343a45040002484627065622d375b6fa2cac /drivers/net/ethernet/broadcom/cnic.c | |
parent | b6069a95706ca5738be3f5d90fd286cbd13ac695 (diff) |
cnic: Add functions to allocate and free UIO rings
These functions are needed to free up memory when the rings are no longer
needed.
Reviewed-by: Eddie Wai <eddie.wai@broadcom.com>
Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/cnic.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/cnic.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 3b4fc61f24cf..ff3589405dce 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -823,10 +823,8 @@ static void cnic_free_context(struct cnic_dev *dev) | |||
823 | } | 823 | } |
824 | } | 824 | } |
825 | 825 | ||
826 | static void __cnic_free_uio(struct cnic_uio_dev *udev) | 826 | static void __cnic_free_uio_rings(struct cnic_uio_dev *udev) |
827 | { | 827 | { |
828 | uio_unregister_device(&udev->cnic_uinfo); | ||
829 | |||
830 | if (udev->l2_buf) { | 828 | if (udev->l2_buf) { |
831 | dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size, | 829 | dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size, |
832 | udev->l2_buf, udev->l2_buf_map); | 830 | udev->l2_buf, udev->l2_buf_map); |
@@ -839,6 +837,14 @@ static void __cnic_free_uio(struct cnic_uio_dev *udev) | |||
839 | udev->l2_ring = NULL; | 837 | udev->l2_ring = NULL; |
840 | } | 838 | } |
841 | 839 | ||
840 | } | ||
841 | |||
842 | static void __cnic_free_uio(struct cnic_uio_dev *udev) | ||
843 | { | ||
844 | uio_unregister_device(&udev->cnic_uinfo); | ||
845 | |||
846 | __cnic_free_uio_rings(udev); | ||
847 | |||
842 | pci_dev_put(udev->pdev); | 848 | pci_dev_put(udev->pdev); |
843 | kfree(udev); | 849 | kfree(udev); |
844 | } | 850 | } |
@@ -996,6 +1002,34 @@ static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info, | |||
996 | return 0; | 1002 | return 0; |
997 | } | 1003 | } |
998 | 1004 | ||
1005 | static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages) | ||
1006 | { | ||
1007 | struct cnic_local *cp = udev->dev->cnic_priv; | ||
1008 | |||
1009 | if (udev->l2_ring) | ||
1010 | return 0; | ||
1011 | |||
1012 | udev->l2_ring_size = pages * BCM_PAGE_SIZE; | ||
1013 | udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, | ||
1014 | &udev->l2_ring_map, | ||
1015 | GFP_KERNEL | __GFP_COMP); | ||
1016 | if (!udev->l2_ring) | ||
1017 | return -ENOMEM; | ||
1018 | |||
1019 | udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; | ||
1020 | udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); | ||
1021 | udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, | ||
1022 | &udev->l2_buf_map, | ||
1023 | GFP_KERNEL | __GFP_COMP); | ||
1024 | if (!udev->l2_buf) { | ||
1025 | __cnic_free_uio_rings(udev); | ||
1026 | return -ENOMEM; | ||
1027 | } | ||
1028 | |||
1029 | return 0; | ||
1030 | |||
1031 | } | ||
1032 | |||
999 | static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) | 1033 | static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) |
1000 | { | 1034 | { |
1001 | struct cnic_local *cp = dev->cnic_priv; | 1035 | struct cnic_local *cp = dev->cnic_priv; |
@@ -1020,20 +1054,9 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) | |||
1020 | 1054 | ||
1021 | udev->dev = dev; | 1055 | udev->dev = dev; |
1022 | udev->pdev = dev->pcidev; | 1056 | udev->pdev = dev->pcidev; |
1023 | udev->l2_ring_size = pages * BCM_PAGE_SIZE; | ||
1024 | udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, | ||
1025 | &udev->l2_ring_map, | ||
1026 | GFP_KERNEL | __GFP_COMP); | ||
1027 | if (!udev->l2_ring) | ||
1028 | goto err_udev; | ||
1029 | 1057 | ||
1030 | udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; | 1058 | if (__cnic_alloc_uio_rings(udev, pages)) |
1031 | udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); | 1059 | goto err_udev; |
1032 | udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, | ||
1033 | &udev->l2_buf_map, | ||
1034 | GFP_KERNEL | __GFP_COMP); | ||
1035 | if (!udev->l2_buf) | ||
1036 | goto err_dma; | ||
1037 | 1060 | ||
1038 | write_lock(&cnic_dev_lock); | 1061 | write_lock(&cnic_dev_lock); |
1039 | list_add(&udev->list, &cnic_udev_list); | 1062 | list_add(&udev->list, &cnic_udev_list); |
@@ -1044,9 +1067,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) | |||
1044 | cp->udev = udev; | 1067 | cp->udev = udev; |
1045 | 1068 | ||
1046 | return 0; | 1069 | return 0; |
1047 | err_dma: | 1070 | |
1048 | dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size, | ||
1049 | udev->l2_ring, udev->l2_ring_map); | ||
1050 | err_udev: | 1071 | err_udev: |
1051 | kfree(udev); | 1072 | kfree(udev); |
1052 | return -ENOMEM; | 1073 | return -ENOMEM; |