From 7ec4581ad37b88bbb300ac00850603433a8cdfe9 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Thu, 20 Jun 2013 19:15:55 +0200 Subject: Multipage DMA tests for Xilinx --- driver/kmem.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'driver/kmem.c') diff --git a/driver/kmem.c b/driver/kmem.c index 37a7368..ee64a78 100644 --- a/driver/kmem.c +++ b/driver/kmem.c @@ -130,23 +130,28 @@ int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_han retptr = pci_alloc_consistent( privdata->pdev, kmem_handle->size, &(kmem_entry->dma_handle) ); break; case PCILIB_KMEM_TYPE_PAGE: - retptr = (void*)__get_free_pages(GFP_KERNEL, get_order(PAGE_SIZE)); + if (kmem_handle->size == 0) + kmem_handle->size = PAGE_SIZE; + else if (kmem_handle->size%PAGE_SIZE) + goto kmem_alloc_mem_fail; + + retptr = (void*)__get_free_pages(GFP_KERNEL|__GFP_DMA, get_order(kmem_handle->size)); kmem_entry->dma_handle = 0; - kmem_handle->size = PAGE_SIZE; + kmem_handle->size = kmem_handle->size; if (retptr) { if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_S2C_PAGE) { kmem_entry->direction = PCI_DMA_TODEVICE; - kmem_entry->dma_handle = pci_map_single(privdata->pdev, retptr, PAGE_SIZE, PCI_DMA_TODEVICE); + kmem_entry->dma_handle = pci_map_single(privdata->pdev, retptr, kmem_handle->size, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(privdata->pdev, kmem_entry->dma_handle)) { - free_page((unsigned long)retptr); + free_pages((unsigned long)retptr, get_order(kmem_handle->size)); goto kmem_alloc_mem_fail; } } else if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_C2S_PAGE) { kmem_entry->direction = PCI_DMA_FROMDEVICE; - kmem_entry->dma_handle = pci_map_single(privdata->pdev, retptr, PAGE_SIZE, PCI_DMA_FROMDEVICE); + kmem_entry->dma_handle = pci_map_single(privdata->pdev, retptr, kmem_handle->size, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(privdata->pdev, kmem_entry->dma_handle)) { - free_page((unsigned long)retptr); + free_pages((unsigned long)retptr, get_order(kmem_handle->size)); goto kmem_alloc_mem_fail; } @@ -435,7 +440,7 @@ int pcidriver_kmem_free_entry(pcidriver_privdata_t *privdata, pcidriver_kmem_ent pci_unmap_single(privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, PCI_DMA_FROMDEVICE); } } - free_page((unsigned long)kmem_entry->cpua); + free_pages((unsigned long)kmem_entry->cpua, get_order(kmem_entry->size)); break; } -- cgit v1.2.3 From f000eb0d43193ef8225f947226d9cd3deb00115b Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sun, 14 Jul 2013 05:49:19 +0200 Subject: Support pre-allocated memory with memmap in KMem --- driver/kmem.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'driver/kmem.c') diff --git a/driver/kmem.c b/driver/kmem.c index ee64a78..f36ff8c 100644 --- a/driver/kmem.c +++ b/driver/kmem.c @@ -129,15 +129,23 @@ int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_han case PCILIB_KMEM_TYPE_CONSISTENT: retptr = pci_alloc_consistent( privdata->pdev, kmem_handle->size, &(kmem_entry->dma_handle) ); break; + case PCILIB_KMEM_TYPE_REGION: + retptr = ioremap(kmem_handle->pa, kmem_handle->size); + kmem_entry->dma_handle = kmem_handle->pa; + if (kmem_entry->type == PCILIB_KMEM_TYPE_REGION_S2C) { + kmem_entry->direction = PCI_DMA_TODEVICE; + } else if (kmem_entry->type == PCILIB_KMEM_TYPE_REGION_C2S) { + kmem_entry->direction = PCI_DMA_FROMDEVICE; + } + break; case PCILIB_KMEM_TYPE_PAGE: if (kmem_handle->size == 0) kmem_handle->size = PAGE_SIZE; else if (kmem_handle->size%PAGE_SIZE) goto kmem_alloc_mem_fail; - + retptr = (void*)__get_free_pages(GFP_KERNEL|__GFP_DMA, get_order(kmem_handle->size)); kmem_entry->dma_handle = 0; - kmem_handle->size = kmem_handle->size; if (retptr) { if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_S2C_PAGE) { @@ -432,6 +440,9 @@ int pcidriver_kmem_free_entry(pcidriver_privdata_t *privdata, pcidriver_kmem_ent case PCILIB_KMEM_TYPE_CONSISTENT: pci_free_consistent( privdata->pdev, kmem_entry->size, (void *)(kmem_entry->cpua), kmem_entry->dma_handle ); break; + case PCILIB_KMEM_TYPE_REGION: + iounmap((void *)(kmem_entry->cpua)); + break; case PCILIB_KMEM_TYPE_PAGE: if (kmem_entry->dma_handle) { if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_S2C_PAGE) { @@ -609,12 +620,25 @@ int pcidriver_mmap_kmem(pcidriver_privdata_t *privdata, struct vm_area_struct *v virt_to_phys((void*)kmem_entry->cpua), page_to_pfn(virt_to_page((void*)kmem_entry->cpua))); - ret = remap_pfn_range_cpua_compat( + if ((kmem_entry->type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) { + mod_info("Mapping address %08lx / Size %08lx\n", + kmem_entry->dma_handle, + (vma_size < kmem_entry->size)?vma_size:kmem_entry->size) + + ret = remap_pfn_range_compat( + vma, + vma->vm_start, + kmem_entry->dma_handle, + (vma_size < kmem_entry->size)?vma_size:kmem_entry->size, + vma->vm_page_prot); + } else { + ret = remap_pfn_range_cpua_compat( vma, vma->vm_start, kmem_entry->cpua, (vma_size < kmem_entry->size)?vma_size:kmem_entry->size, vma->vm_page_prot ); + } if (ret) { mod_info("kmem remap failed: %d (%lx)\n", ret,kmem_entry->cpua); -- cgit v1.2.3 From f5b4c23cc79affe851016c7ef7970b3e3489fad3 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Fri, 26 Jul 2013 18:30:01 +0200 Subject: Add missing semicolon in the driver --- driver/kmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'driver/kmem.c') diff --git a/driver/kmem.c b/driver/kmem.c index f36ff8c..b8ce0d0 100644 --- a/driver/kmem.c +++ b/driver/kmem.c @@ -621,9 +621,9 @@ int pcidriver_mmap_kmem(pcidriver_privdata_t *privdata, struct vm_area_struct *v page_to_pfn(virt_to_page((void*)kmem_entry->cpua))); if ((kmem_entry->type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) { - mod_info("Mapping address %08lx / Size %08lx\n", - kmem_entry->dma_handle, - (vma_size < kmem_entry->size)?vma_size:kmem_entry->size) + mod_info("Mapping address %08lx / Size %08lx\n", + (unsigned long)kmem_entry->dma_handle, + (vma_size < kmem_entry->size)?vma_size:kmem_entry->size); ret = remap_pfn_range_compat( vma, -- cgit v1.2.3