[PATCH 2/2] Clean up DMA allocations

Eugene Krasnikov k.eugene.e at gmail.com
Fri May 24 05:40:51 EDT 2013


Finally we get rid of this legacy function wcn36xx_dma_alloc. I did
not like it from very begging:)

2013/5/24 Pontus Fuchs <pontus.fuchs at gmail.com>:
> Remove the wrapper function. It adds nothing but confusion.
> Fix bad DMA free's as reported by Kalle Valo.
>
> Signed-off-by: Pontus Fuchs <pontus.fuchs at gmail.com>
> ---
>  dxe.c | 55 +++++++++++++++++++++----------------------------------
>  dxe.h |  2 +-
>  2 files changed, 22 insertions(+), 35 deletions(-)
>
> diff --git a/dxe.c b/dxe.c
> index d841205..6d37937 100644
> --- a/dxe.c
> +++ b/dxe.c
> @@ -24,30 +24,6 @@
>  #include "txrx.h"
>  #include "wcn36xx.h"
>
> -// Every DMA memory allocation must be preceded with wcn36xx_dxe_mem_info struct
> -static void * wcn36xx_dma_alloc(size_t size, void **paddr)
> -{
> -       u32 len;
> -       void *virt_addr;
> -       dma_addr_t phy_addr;
> -       struct wcn36xx_dxe_mem_info *mem_info = NULL;
> -
> -       len = size + sizeof(struct wcn36xx_dxe_mem_info);
> -       virt_addr = dma_alloc_coherent(NULL, len, &phy_addr, GFP_KERNEL);
> -       if (NULL == virt_addr) {
> -               wcn36xx_error("can not alloc mem");
> -               return NULL;
> -       }
> -       memset(virt_addr, 0, len);
> -       mem_info = (struct wcn36xx_dxe_mem_info *)virt_addr;
> -       mem_info->len = len;
> -       mem_info->phy_addr = phy_addr;
> -       mem_info->offset = sizeof(struct wcn36xx_dxe_mem_info);
> -
> -       *paddr = (void*)phy_addr + mem_info->offset;
> -       return virt_addr+mem_info->offset;
> -}
> -
>  static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data)
>  {
>         wcn36xx_dbg(WCN36XX_DBG_DXE,
> @@ -162,14 +138,17 @@ static int wcn36xx_dxe_init_descs(struct wcn36xx_dxe_ch *wcn_ch)
>         struct wcn36xx_dxe_desc *cur_dxe_desc = NULL;
>         struct wcn36xx_dxe_desc *prev_dxe_desc = NULL;
>         struct wcn36xx_dxe_ctl *cur_dxe_ctl = NULL;
> -       size_t size = 0;
> +       size_t size;
>         int i;
>
>         size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc);
> -       wcn_ch->cpu_addr = wcn36xx_dma_alloc(size, (void **)&wcn_ch->dma_addr);
> +       wcn_ch->cpu_addr = dma_alloc_coherent(NULL, size, &wcn_ch->dma_addr,
> +                                             GFP_KERNEL);
>         if (!wcn_ch->cpu_addr)
>                 return -ENOMEM;
>
> +       memset(wcn_ch->cpu_addr, 0, size);
> +
>         cur_dxe_desc = (struct wcn36xx_dxe_desc *)wcn_ch->cpu_addr;
>         cur_dxe_ctl = wcn_ch->head_blk_ctl;
>
> @@ -384,15 +363,21 @@ void wcn36xx_rx_ready_work(struct work_struct *work)
>  }
>  int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn)
>  {
> +       size_t s;
> +       void *cpu_addr;
> +
>         /* Allocate BD headers for MGMT frames */
>
>         // Where this come from ask QC
>         wcn->mgmt_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE +
>                 16 - (WCN36XX_BD_CHUNK_SIZE % 8);
> -       wcn->mgmt_mem_pool.virt_addr = wcn36xx_dma_alloc(
> -               wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H,
> -               (void**)&wcn->mgmt_mem_pool.phy_addr);
>
> +       s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H;
> +       cpu_addr = dma_alloc_coherent(NULL, s, &wcn->mgmt_mem_pool.phy_addr,
> +                                     GFP_KERNEL);
> +
> +       wcn->mgmt_mem_pool.virt_addr = cpu_addr;
> +       memset(cpu_addr, 0, s);
>         wcn->mgmt_mem_pool.bitmap =
>                 kzalloc((WCN36XX_DXE_CH_DESC_NUMB_TX_H / 32 + 1) *
>                 sizeof(u32), GFP_KERNEL);
> @@ -402,10 +387,12 @@ int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn)
>         // Where this come from ask QC
>         wcn->data_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE +
>                 16 - (WCN36XX_BD_CHUNK_SIZE % 8);
> -       wcn->data_mem_pool.virt_addr =  wcn36xx_dma_alloc(
> -               wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L,
> -               (void**)&wcn->data_mem_pool.phy_addr);
>
> +       s = wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L;
> +       cpu_addr = dma_alloc_coherent(NULL, s, &wcn->data_mem_pool.phy_addr,
> +                                     GFP_KERNEL);
> +       wcn->data_mem_pool.virt_addr = cpu_addr;
> +       memset(cpu_addr, 0, s);
>         wcn->data_mem_pool.bitmap =
>                 kzalloc((WCN36XX_DXE_CH_DESC_NUMB_TX_L / 32 + 1) *
>                 sizeof(u32), GFP_KERNEL);
> @@ -418,12 +405,12 @@ void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn)
>                 dma_free_coherent(NULL, wcn->mgmt_mem_pool.chunk_size *
>                                   WCN36XX_DXE_CH_DESC_NUMB_TX_H,
>                                   wcn->mgmt_mem_pool.virt_addr,
> -                                 (dma_addr_t) wcn->data_mem_pool.phy_addr);
> +                                 wcn->mgmt_mem_pool.phy_addr);
>         if (wcn->data_mem_pool.virt_addr) {
>                 dma_free_coherent(NULL, wcn->data_mem_pool.chunk_size *
>                                   WCN36XX_DXE_CH_DESC_NUMB_TX_L,
>                                   wcn->data_mem_pool.virt_addr,
> -                                 (dma_addr_t) wcn->data_mem_pool.phy_addr);
> +                                 wcn->data_mem_pool.phy_addr);
>         }
>         kfree(wcn->data_mem_pool.bitmap);
>         kfree(wcn->mgmt_mem_pool.bitmap);
> diff --git a/dxe.h b/dxe.h
> index d240a60..7761d7b 100644
> --- a/dxe.h
> +++ b/dxe.h
> @@ -224,7 +224,7 @@ struct wcn36xx_dxe_ch {
>  struct wcn36xx_dxe_mem_pool {
>         int     chunk_size;             // size of every chunk
>         void    *virt_addr;             // virtual address that is visible to CPU
> -       void    *phy_addr;              // physical address that
> +       dma_addr_t      phy_addr;       // physical address that
>         void    *bitmap;                // bitmap array for all headers
>  };
>  struct wcn36xx;
> --
> 1.8.1.2
>
>
> _______________________________________________
> wcn36xx mailing list
> wcn36xx at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx



-- 
Best regards,
Eugene



More information about the wcn36xx mailing list