Re: [PATCH v2] staging: kpc2000: Add DMA driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Matt,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on staging/staging-testing]
[cannot apply to v5.1-rc6 next-20190418]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matt-Sickler/staging-kpc2000-Add-DMA-driver/20190423-120446
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@xxxxxxxxx>


All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:330:0,
                    from include/linux/kernel.h:15,
                    from include/linux/list.h:9,
                    from include/linux/module.h:9,
                    from drivers/staging//kpc2000/kpc_dma/fileops.c:2:
   drivers/staging//kpc2000/kpc_dma/fileops.c: In function 'kpc_dma_transfer':
>> drivers/staging//kpc2000/kpc_dma/fileops.c:58:35: warning: format '%ld' expects argument of type 'long int', but argument 7 has type 'size_t {aka unsigned int}' [-Wformat=]
     dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev);
                                      ^
   include/linux/dynamic_debug.h:118:15: note: in definition of macro '__dynamic_func_call'
      func(&id, ##__VA_ARGS__);  \
                  ^~~~~~~~~~~
   include/linux/dynamic_debug.h:150:2: note: in expansion of macro '_dynamic_func_call'
     _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
     ^~~~~~~~~~~~~~~~~~
   include/linux/device.h:1493:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
   include/linux/device.h:1493:23: note: in expansion of macro 'dev_fmt'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
                          ^~~~~~~
   drivers/staging//kpc2000/kpc_dma/fileops.c:58:2: note: in expansion of macro 'dev_dbg'
     dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev);
     ^~~~~~~

vim +58 drivers/staging//kpc2000/kpc_dma/fileops.c

   > 2	#include <linux/module.h>
     3	#include <linux/init.h>
     4	#include <linux/mm.h>
     5	#include <linux/kernel.h>   /* printk() */
     6	#include <linux/slab.h>     /* kmalloc() */
     7	#include <linux/fs.h>       /* everything... */
     8	#include <linux/errno.h>    /* error codes */
     9	#include <linux/types.h>    /* size_t */
    10	#include <linux/cdev.h>
    11	#include <asm/uaccess.h>    /* copy_*_user */
    12	#include <linux/aio.h>      /* aio stuff */
    13	#include <linux/highmem.h>
    14	#include <linux/pagemap.h>
    15	#include "kpc_dma_driver.h"
    16	#include "uapi.h"
    17	
    18	/**********  Helper Functions  **********/
    19	static inline
    20	unsigned int  count_pages(unsigned long iov_base, size_t iov_len)
    21	{
    22		unsigned long first = (iov_base             & PAGE_MASK) >> PAGE_SHIFT;
    23		unsigned long last  = ((iov_base+iov_len-1) & PAGE_MASK) >> PAGE_SHIFT;
    24		return last - first + 1;
    25	}
    26	
    27	static inline
    28	unsigned int  count_parts_for_sge(struct scatterlist *sg)
    29	{
    30		unsigned int sg_length = sg_dma_len(sg);
    31		sg_length += (0x80000-1);
    32		return (sg_length / 0x80000);
    33	}
    34	
    35	/**********  Transfer Helpers  **********/
    36	static
    37	int  kpc_dma_transfer(struct dev_private_data *priv, struct kiocb *kcb, unsigned long iov_base, size_t iov_len)
    38	{
    39		unsigned int i = 0;
    40		long rv = 0;
    41		struct kpc_dma_device *ldev;
    42		struct aio_cb_data *acd;
    43		DECLARE_COMPLETION_ONSTACK(done);
    44		u32 desc_needed = 0;
    45		struct scatterlist *sg;
    46		u32 num_descrs_avail;
    47		struct kpc_dma_descriptor *desc;
    48		unsigned int pcnt;
    49		unsigned int p;
    50		u64 card_addr;
    51		u64 dma_addr;
    52		u64 user_ctl;
    53		
    54		BUG_ON(priv == NULL);
    55		ldev = priv->ldev;
    56		BUG_ON(ldev == NULL);
    57		
  > 58		dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev);
    59		
    60		acd = (struct aio_cb_data *) kzalloc(sizeof(struct aio_cb_data), GFP_KERNEL);
    61		if (!acd){
    62			dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the aio data\n");
    63			return -ENOMEM;
    64		}
    65		memset(acd, 0x66, sizeof(struct aio_cb_data));
    66		
    67		acd->priv = priv;
    68		acd->ldev = priv->ldev;
    69		acd->cpl = &done;
    70		acd->flags = 0;
    71		acd->kcb = kcb;
    72		acd->len = iov_len;
    73		acd->page_count = count_pages(iov_base, iov_len);
    74		
    75		// Allocate an array of page pointers
    76		acd->user_pages = kzalloc(sizeof(struct page *) * acd->page_count, GFP_KERNEL);
    77		if (!acd->user_pages){
    78			dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the page pointers\n");
    79			rv = -ENOMEM;
    80			goto err_alloc_userpages;
    81		}
    82		
    83		// Lock the user buffer pages in memory, and hold on to the page pointers (for the sglist)
    84		down_read(&current->mm->mmap_sem);      /*  get memory map semaphore */
    85		rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL);
    86		up_read(&current->mm->mmap_sem);        /*  release the semaphore */
    87		if (rv != acd->page_count){
    88			dev_err(&priv->ldev->pldev->dev, "Couldn't get_user_pages (%ld)\n", rv);
    89			goto err_get_user_pages;
    90		}
    91		
    92		// Allocate and setup the sg_table (scatterlist entries)
    93		rv = sg_alloc_table_from_pages(&acd->sgt, acd->user_pages, acd->page_count, iov_base & (PAGE_SIZE-1), iov_len, GFP_KERNEL);
    94		if (rv){
    95			dev_err(&priv->ldev->pldev->dev, "Couldn't alloc sg_table (%ld)\n", rv);
    96			goto err_alloc_sg_table;
    97		}
    98		
    99		// Setup the DMA mapping for all the sg entries
   100		acd->mapped_entry_count = dma_map_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
   101		if (acd->mapped_entry_count <= 0){
   102			dev_err(&priv->ldev->pldev->dev, "Couldn't dma_map_sg (%d)\n", acd->mapped_entry_count);
   103			goto err_dma_map_sg;
   104		}
   105	
   106		// Calculate how many descriptors are actually needed for this transfer.
   107		for_each_sg(acd->sgt.sgl, sg, acd->mapped_entry_count, i){
   108			desc_needed += count_parts_for_sge(sg);
   109		}
   110		
   111		lock_engine(ldev);
   112		
   113		// Figoure out how many descriptors are available and return an error if there aren't enough
   114		num_descrs_avail = count_descriptors_available(ldev);
   115		dev_dbg(&priv->ldev->pldev->dev, "    mapped_entry_count = %d    num_descrs_needed = %d    num_descrs_avail = %d\n", acd->mapped_entry_count, desc_needed, num_descrs_avail);
   116		if (desc_needed >= ldev->desc_pool_cnt){
   117			dev_warn(&priv->ldev->pldev->dev, "    mapped_entry_count = %d    num_descrs_needed = %d    num_descrs_avail = %d    TOO MANY to ever complete!\n", acd->mapped_entry_count, desc_needed, num_descrs_avail);
   118			rv = -EAGAIN;
   119			unlock_engine(ldev);
   120			goto err_descr_too_many;
   121		}
   122		if (desc_needed > num_descrs_avail){
   123			dev_warn(&priv->ldev->pldev->dev, "    mapped_entry_count = %d    num_descrs_needed = %d    num_descrs_avail = %d    Too many to complete right now.\n", acd->mapped_entry_count, desc_needed, num_descrs_avail);
   124			rv = -EMSGSIZE;
   125			unlock_engine(ldev);
   126			goto err_descr_too_many;
   127		}
   128	
   129		// Loop through all the sg table entries and fill out a descriptor for each one.
   130		desc = ldev->desc_next;
   131		card_addr = acd->priv->card_addr;
   132		for_each_sg(acd->sgt.sgl, sg, acd->mapped_entry_count, i){
   133			pcnt = count_parts_for_sge(sg);
   134			for (p = 0 ; p < pcnt ; p++){
   135				// Fill out the descriptor
   136				BUG_ON(desc == NULL);
   137				clear_desc(desc);
   138				if (p != pcnt-1){
   139					desc->DescByteCount = 0x80000;
   140				} else {
   141					desc->DescByteCount = sg_dma_len(sg) - (p * 0x80000);
   142				}
   143				desc->DescBufferByteCount = desc->DescByteCount;
   144				
   145				desc->DescControlFlags |= DMA_DESC_CTL_IRQONERR;
   146				if (i == 0 && p == 0)
   147					desc->DescControlFlags |= DMA_DESC_CTL_SOP;
   148				if (i == acd->mapped_entry_count-1 && p == pcnt-1)
   149					desc->DescControlFlags |= DMA_DESC_CTL_EOP | DMA_DESC_CTL_IRQONDONE;
   150				
   151				desc->DescCardAddrLS = (card_addr & 0xFFFFFFFF);
   152				desc->DescCardAddrMS = (card_addr >> 32) & 0xF;
   153				card_addr += desc->DescByteCount;
   154				
   155				dma_addr  = sg_dma_address(sg) + (p * 0x80000);
   156				desc->DescSystemAddrLS = (dma_addr & 0x00000000FFFFFFFF) >>  0;
   157				desc->DescSystemAddrMS = (dma_addr & 0xFFFFFFFF00000000) >> 32;
   158				
   159				user_ctl = acd->priv->user_ctl;
   160				if (i == acd->mapped_entry_count-1 && p == pcnt-1){
   161					user_ctl = acd->priv->user_ctl_last;
   162				}
   163				desc->DescUserControlLS = (user_ctl & 0x00000000FFFFFFFF) >>  0;
   164				desc->DescUserControlMS = (user_ctl & 0xFFFFFFFF00000000) >> 32;
   165				
   166				if (i == acd->mapped_entry_count-1 && p == pcnt-1)
   167					desc->acd = acd;
   168				
   169				dev_dbg(&priv->ldev->pldev->dev, "  Filled descriptor %p (acd = %p)\n", desc, desc->acd);
   170				
   171				ldev->desc_next = desc->Next;
   172				desc = desc->Next;
   173			}
   174		}
   175		
   176		// Send the filled descriptors off to the hardware to process!
   177		SetEngineSWPtr(ldev, ldev->desc_next);
   178		
   179		unlock_engine(ldev);
   180		
   181		// If this is a synchronous kiocb, we need to put the calling process to sleep until the transfer is complete
   182		if (kcb == NULL || is_sync_kiocb(kcb)){
   183			rv = wait_for_completion_interruptible(&done);
   184			// If the user aborted (rv == -ERESTARTSYS), we're no longer responsible for cleaning up the acd
   185			if (rv == -ERESTARTSYS){
   186				acd->cpl = NULL;
   187			}
   188			if (rv == 0){
   189				rv = acd->len;
   190				kfree(acd);
   191			}
   192			return rv;
   193		}
   194		
   195		return -EIOCBQUEUED;
   196	
   197	 err_descr_too_many:
   198		unlock_engine(ldev);
   199		dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
   200		sg_free_table(&acd->sgt);
   201	 err_dma_map_sg:
   202	 err_alloc_sg_table:
   203		for (i = 0 ; i < acd->page_count ; i++){
   204			put_page(acd->user_pages[i]);
   205		}
   206	 err_get_user_pages:
   207		kfree(acd->user_pages);
   208	 err_alloc_userpages:
   209		kfree(acd);
   210		dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer returning with error %ld\n", rv);
   211		return rv;
   212	}
   213	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Attachment: .config.gz
Description: application/gzip

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux