Suren A. Chilingaryan 8 gadi atpakaļ
vecāks
revīzija
4c17aa5a10
16 mainītis faili ar 335 papildinājumiem un 54 dzēšanām
  1. 5 0
      .bzrignore
  2. 64 14
      CMakeLists.txt
  3. 1 1
      dma/ipe.c
  4. 2 2
      dma/nwl_engine.c
  5. 4 4
      dma/nwl_engine_buffers.h
  6. 0 5
      docs/BUGS
  7. 13 4
      driver/makefile
  8. 9 0
      misc/dkms.conf.in
  9. 8 0
      misc/rpmlintrc
  10. 3 3
      pcilib/kmem.c
  11. 3 3
      pcilib/kmem.h
  12. 3 3
      pcilib/locking.c
  13. 204 0
      pcitool.spec.in
  14. 2 2
      pcitool/cli.c
  15. 3 3
      protocols/software.c
  16. 11 10
      tests/reload.sh

+ 5 - 0
.bzrignore

@@ -37,3 +37,8 @@ build
 pcipywrap.py
 pcipywrapPYTHON_wrap.c
 apps/test_multithread
+pcitool.spec
+misc/dkms.conf
+CPackConfig.cmake
+CPackSourceConfig.cmake
+_CPack_Packages

+ 64 - 14
CMakeLists.txt

@@ -1,5 +1,6 @@
-project(pcitool)
+project(pcitool C)
 
+set(RELEASE "0")
 set(PCILIB_VERSION "0.2.7")
 set(PCILIB_ABI_VERSION "2")
 
@@ -12,12 +13,20 @@ set(DISABLE_PYTHON FALSE CACHE BOOL "Disable python scripting support")
 
 #list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
+if(NOT DEFINED LIB_SUFFIX)
+ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(LIB_SUFFIX "64")
+ else (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(LIB_SUFFIX "")
+ endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
+endif(NOT DEFINED LIB_SUFFIX)
+
 if(NOT DEFINED BIN_INSTALL_DIR)
     set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
 endif(NOT DEFINED BIN_INSTALL_DIR)
 
 if(NOT DEFINED LIB_INSTALL_DIR)
-    set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+    set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
 endif(NOT DEFINED LIB_INSTALL_DIR)
 
 if(NOT DEFINED INCLUDE_INSTALL_DIR)
@@ -32,10 +41,31 @@ if(NOT DEFINED LOCALE_INSTALL_DIR)
     set(LOCALE_INSTALL_DIR "${DATA_INSTALL_DIR}/locale")
 endif(NOT DEFINED LOCALE_INSTALL_DIR)
 
+if (NOT DEFINED PCILIB_PLUGIN_DIR)
+    set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install plugins")
+endif (NOT DEFINED PCILIB_PLUGIN_DIR)
+
+if (NOT DEFINED PCILIB_DATA_DIR)
+    set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install data files")
+endif (NOT DEFINED PCILIB_DATA_DIR)
+
+if (NOT DEFINED PCILIB_MODEL_DIR)
+    set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models" CACHE PATH "Directory to install XML models")
+endif (NOT DEFINED PCILIB_MODEL_DIR)
+
+if (NOT DEFINED PCILIB_DOC_DIR)
+    set(PCILIB_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/docs/" CACHE PATH "Directory to install documentation")
+endif (NOT DEFINED PCILIB_DOC_DIR)
+    
+if (NOT DEFINED PCILIB_DEBUG_DIR)
+    set(PCILIB_DEBUG_DIR "." CACHE PATH "Directory to write debug information")
+endif (NOT DEFINED PCILIB_DEBUG_DIR)
+
 SET(ENV{PKG_CONFIG_PATH} "${LIB_INSTALL_DIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}")
 
 find_package(PkgConfig REQUIRED)
 find_package(Threads REQUIRED)
+find_package(Doxygen)
 
 if (NOT DISABLE_PYTHON)
     set(PYTHON_VERSION 2.7 CACHE STRING "python version")
@@ -50,13 +80,15 @@ if (NOT DISABLE_PYTHON)
 
 #    execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "from sysconfig import get_path; print get_path('platlib')" OUTPUT_VARIABLE PYTHON_INSTALL_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
     
-    execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.PREFIXES[-1])" OUTPUT_VARIABLE PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
-    file (TO_CMAKE_PATH "${PYTHON_PREFIX}" PYTHON_PREFIX)
-    execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.getsitepackages()[0])" OUTPUT_VARIABLE PYTHON_SITE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
-    file (TO_CMAKE_PATH "${PYTHON_SITE_DIR}" PYTHON_SITE_DIR)
+    if (NOT DEFINED PYTHON_INSTALL_DIR)
+	execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.PREFIXES[-1])" OUTPUT_VARIABLE PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
+	file (TO_CMAKE_PATH "${PYTHON_PREFIX}" PYTHON_PREFIX)
+	execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.getsitepackages()[0])" OUTPUT_VARIABLE PYTHON_SITE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
+	file (TO_CMAKE_PATH "${PYTHON_SITE_DIR}" PYTHON_SITE_DIR)
 
-    string (REGEX REPLACE "^${PYTHON_PREFIX}/" "${CMAKE_INSTALL_PREFIX}/" PYTHON_SITE_DIR "${PYTHON_SITE_DIR}")
-    set(PYTHON_INSTALL_DIR ${PYTHON_SITE_DIR} CACHE PATH "path to install python module")
+	string (REGEX REPLACE "^${PYTHON_PREFIX}/" "${CMAKE_INSTALL_PREFIX}/" PYTHON_SITE_DIR "${PYTHON_SITE_DIR}")
+	set(PYTHON_INSTALL_DIR ${PYTHON_SITE_DIR} CACHE PATH "path to install python module")
+    endif (NOT DEFINED PYTHON_INSTALL_DIR)
 
     set(HAVE_PYTHON TRUE)
 endif (NOT DISABLE_PYTHON)
@@ -93,7 +125,6 @@ add_custom_command(TARGET build
 )
 set_source_files_properties(${CMAKE_BINARY_DIR}/pcilib/build.h PROPERTIES GENERATED TRUE)
 
-
 set(TARNAME "pcitool")
 set(PACKAGE_VERSION ${PCILIB_VERSION})
 set(PACKAGE_NAME "${TARNAME}")
@@ -101,11 +132,20 @@ set(PACKAGE_TARNAME "${TARNAME}")
 set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_BUGREPORT "http://ufo.kit.edu/ufo/newticket")
 
-set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install plugins")
-set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install data files")
-set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models" CACHE PATH "Directory to install XML models")
-set(PCILIB_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/docs/" CACHE PATH "Directory to install documentation")
-set(PCILIB_DEBUG_DIR "." CACHE PATH "Directory to write debug information")
+set(CPACK_SOURCE_GENERATOR "TBZ2")
+set(CPACK_PACKAGE_CONTACT "Suren A. Chilingaryan <csa@suren.me>")
+if (${RELEASE} GREATER 0)
+    set(CPACK_PACKAGE_VERSION "${PACKAGE_VERSION}.${RELEASE}")
+else (${RELEASE} GREATER 0)
+    set(CPACK_PACKAGE_VERSION "${PACKAGE_VERSION}")
+endif (${RELEASE} GREATER 0)
+set(CPACK_SOURCE_IGNORE_FILES "/.bzr/;CMakeFiles;_CPack_Packages;cmake_install.cmake;CPack.*.cmake;CMakeCache.txt;install_manifest.txt;config.h$;.pc$;Makefile;.tar.bz2$;~$;${CPACK_SOURCE_IGNORE_FILES}")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}")
+include(CPack)
+
+add_custom_target(dist_clean COMMAND ${CMAKE_MAKE_PROGRAM} clean WORKING_DIRECTORY ${CMAKE_CURRENT_DIR})
+add_custom_target(dist DEPENDS dist_clean COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
+
 
 add_subdirectory(dma)
 add_subdirectory(protocols)
@@ -124,6 +164,16 @@ set_target_properties(pcilib PROPERTIES
     SOVERSION ${PCILIB_ABI_VERSION}
 )
 
+add_custom_target(docs
+    COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile 
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs
+    COMMENT "Generating API documentation with Doxygen" VERBATIM
+)
+set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "docs/html")
+
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcitool.spec.in ${CMAKE_CURRENT_BINARY_DIR}/pcitool.spec)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/dkms.conf.in ${CMAKE_CURRENT_BINARY_DIR}/misc/dkms.conf)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/config.h)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/version.h)

+ 1 - 1
dma/ipe.c

@@ -651,7 +651,7 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
 	
 	if ((ctx->dma_flags&IPEDMA_FLAG_NOSYNC) == 0)
 	    pcilib_kmem_sync_block(ctx->dmactx.pcilib, ctx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, cur_read);
-        void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ctx->pages, cur_read);
+        void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ctx->pages, cur_read);
 	ret = cb(cbattr, packet_flags, ctx->page_size, buf);
 	if (ret < 0) return -ret;
 	

+ 2 - 2
dma/nwl_engine.c

@@ -237,7 +237,7 @@ int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma,
 		return PCILIB_ERROR_TIMEOUT;
 	    }
 	
-    	    void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum);
+    	    void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum);
 
 	    pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum);
 	    memcpy(buf, data, block_size);
@@ -293,7 +293,7 @@ int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
 	if (ctx->ignore_eop) eop = 1;
 	
 	pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum);
-        void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum);
+        void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum);
 	ret = cb(cbattr, (eop?PCILIB_DMA_FLAG_EOP:0), bufsize, buf);
 	if (ret < 0) return -ret;
 //	DS: Fixme, it looks like we can avoid calling this for the sake of performance

+ 4 - 4
dma/nwl_engine_buffers.h

@@ -173,7 +173,7 @@ static size_t dma_nwl_clean_buffers(nwl_dma_t * ctx, pcilib_nwl_engine_context_t
     size_t res = 0;
     uint32_t status;
 
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
+    volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
     ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
 
 next_buffer:
@@ -250,7 +250,7 @@ static int dma_nwl_push_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx
     int flags = 0;
     
     uint32_t val;
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
+    volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
     uint32_t ring_pa = pcilib_kmem_get_ba(ctx->dmactx.pcilib, ectx->ring);
 
     ring += ectx->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
@@ -282,7 +282,7 @@ static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *e
     struct timeval start, cur;
     uint32_t status_size, status;
 
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
+    volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
     
     ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
 
@@ -337,7 +337,7 @@ static int dma_nwl_is_overflown(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ect
 static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx) {
     uint32_t val;
 
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
+    volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring);
     uint32_t ring_pa = pcilib_kmem_get_ba(ctx->dmactx.pcilib, ectx->ring);
     size_t bufsz = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, ectx->pages, ectx->tail);
 

+ 0 - 5
docs/BUGS

@@ -1,5 +0,0 @@
-IPECamera Hardware Bugs
-=======================
- 1. Strange sequence writting CMOSIS registers
- 2. Sometimes during DMA streaming register accesses fail
- 3. The lower 12-bit of bus address are ignored by all hardware

+ 13 - 4
driver/Makefile → driver/makefile

@@ -3,10 +3,11 @@ CONFIG_MODULE_SIG=n
 obj-m := pciDriver.o
 pciDriver-objs := base.o dev.o int.o umem.o kmem.o sysfs.o ioctl.o pcibus.o rdma.o
 
-KERNELDIR ?= /lib/modules/$(shell uname -r)/build
-INSTALLDIR ?= /lib/modules/$(shell uname -r)/extra
-MAININSTALLDIR ?= /lib/modules/$(shell uname -r)/kernel/extra
-HEADERDIR ?= /lib/modules/$(shell uname -r)/source/include
+KERNELVER ?= $(shell uname -r)
+KERNELDIR ?= /lib/modules/$(KERNELVER)/build
+INSTALLDIR ?= /lib/modules/$(KERNELVER)/extra
+MAININSTALLDIR ?= /lib/modules/$(KERNELVER)/kernel/extra
+HEADERDIR ?= /lib/modules/$(KERNELVER)/source/include
 PWD := $(shell pwd)
 
 EXTRA_CFLAGS += -I$(M)/..
@@ -63,6 +64,14 @@ install:
 	@mkdir -p /usr/include/linux
 	@install -m 644 ioctl.h /usr/include/linux/pcidriver.h
 
+install_symvers:
+	@mkdir -p $(INSTALLDIR)
+	@echo "INSTALL $(INSTALLDIR)/pciDriver.symvers"
+	@install -m 644 Module.symvers $(INSTALLDIR)/pciDriver.symvers
+	@echo "INSTALL $(HEADERDIR)/linux/pcidriver.h"
+	@install -m 644 pcidriver.h $(HEADERDIR)/linux/
+
+
 uninstall:
 	@echo "UNINSTALL $(INSTALLDIR)/pciDriver.ko"
 	@rm -f $(INSTALLDIR)/pciDriver.ko

+ 9 - 0
misc/dkms.conf.in

@@ -0,0 +1,9 @@
+POST_INSTALL="make -C driver/ install_symvers KERNELVER=$kernelver KERNELDIR=$kernel_source_dir"
+MAKE="make -C driver/ KERNELDIR=/lib/modules/${kernelver}/build"
+CLEAN="make -C driver/ clean"
+BUILT_MODULE_NAME=pciDriver
+BUILT_MODULE_LOCATION=driver/
+PACKAGE_NAME=${PACKAGE_NAME}
+PACKAGE_VERSION=${CPACK_PACKAGE_VERSION}
+REMAKE_INITRD=no
+AUTOINSTALL=yes

+ 8 - 0
misc/rpmlintrc

@@ -0,0 +1,8 @@
+addFilter("devel-file-in-non-devel-package.*/usr/src/pciDriver")
+addFilter("no-manual-page-for-binary")
+addFilter("files-duplicate /usr/share/doc/packages/libpcilib-devel/html/")
+addFilter("files-duplicate /usr/share/pcilib.*/pyserver/static/codebase/imgs/dhxtree_skyblue/")
+addFilter("suse-filelist-forbidden-fhs23 /usr/src/pciDriver")
+
+# uthash
+addFilter("libpcilib.* shared-lib-calls-exit /usr/lib.*/libpcilib")

+ 3 - 3
pcilib/kmem.c

@@ -29,7 +29,7 @@ int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem
 static int pcilib_free_kernel_buffer(pcilib_t *ctx, pcilib_kmem_list_t *kbuf, size_t i, pcilib_kmem_flags_t flags) {
     kmem_handle_t kh = {0};
 
-    if (kbuf->buf.blocks[i].ua) munmap(kbuf->buf.blocks[i].ua, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset);
+    if (kbuf->buf.blocks[i].ua) munmap((void*)kbuf->buf.blocks[i].ua, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset);
     kh.handle_id = kbuf->buf.blocks[i].handle_id;
     kh.pa = kbuf->buf.blocks[i].pa;
     kh.flags = flags;
@@ -361,7 +361,7 @@ int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_s
     return 0;
 }
 
-void* volatile pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k) {
+volatile void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k) {
     pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
     return kbuf->buf.addr.ua + kbuf->buf.addr.alignment_offset + kbuf->buf.addr.mmap_offset;
 }
@@ -380,7 +380,7 @@ uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k) {
     return 0;
 }
 
-void* volatile pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) {
+volatile void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) {
     pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
     return kbuf->buf.blocks[block].ua + kbuf->buf.blocks[block].alignment_offset + kbuf->buf.blocks[block].mmap_offset;
 }

+ 3 - 3
pcilib/kmem.h

@@ -68,7 +68,7 @@ typedef struct {
 
     uintptr_t pa;					/**< physical address of buffer */
     uintptr_t ba;					/**< bus address of buffer (if it is mapped for DMA operations) */
-    void* volatile ua;					/**< pointer to buffer in the process address space */
+    volatile void *ua;					/**< pointer to buffer in the process address space */
     size_t size;					/**< size of the buffer in bytes */
 
     size_t alignment_offset;				/**< we may request alignment of allocated buffers. To enusre proper alignment the larger buffer will be allocated and the offset will specify the first position in the buffer fullfilling alignment request */
@@ -205,7 +205,7 @@ int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_s
  * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
  * @return 			- user-space pointer
  */
-void* volatile pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k);
+volatile void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k);
 
 /**
  * Get a physical address of a single-buffer kernel memory
@@ -233,7 +233,7 @@ uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k);
  * @param[in] block		- specifies the buffer within the kernel memory (buffers are numbered from 0)
  * @return 			- user-space pointer
  */
-void* volatile pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
+volatile void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
 
 /**
  * Get a physical address of the specified kernel memory buffer

+ 3 - 3
pcilib/locking.c

@@ -43,7 +43,7 @@ int pcilib_init_locking(pcilib_t* ctx) {
 
     if ((reused & PCILIB_KMEM_REUSE_REUSED) == 0) {
         for (i = 0; i < PCILIB_LOCK_PAGES; i++) {
-	    void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i);
+	    void *addr = (void*)pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i);
 	    memset(addr, 0, PCILIB_KMEM_PAGE_SIZE);
         }
     }
@@ -95,7 +95,7 @@ void pcilib_unlock_global(pcilib_t *ctx) {
 pcilib_lock_t *pcilib_get_lock_by_id(pcilib_t *ctx, pcilib_lock_id_t id) {
     int page = id / PCILIB_LOCKS_PER_PAGE;
     int offset = id - page * PCILIB_LOCKS_PER_PAGE;
-    void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, page);
+    volatile void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, page);
     pcilib_lock_t *lock = (pcilib_lock_t*)(addr + offset * PCILIB_LOCK_SIZE);
 
     return lock;
@@ -308,7 +308,7 @@ int pcilib_destroy_all_locks(pcilib_t *ctx, int force) {
     }
 
     for (i = 0; i < PCILIB_LOCK_PAGES; i++) {
-	void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i);
+	void *addr = (void*)pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i);
 	memset(addr, 0, PCILIB_KMEM_PAGE_SIZE);
     }
 

+ 204 - 0
pcitool.spec.in

@@ -0,0 +1,204 @@
+%define	modname pciDriver
+
+%{!?__python2: %global __python2 /usr/bin/python2}
+%{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
+%{!?python2_sitearch: %global python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
+
+Summary: Universal PCI driver
+Name: pcitool
+Version: ${CPACK_PACKAGE_VERSION}
+Release: csa
+License: GPL-3.0
+Group: Development/Libraries
+Source: ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.bz2
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+URL: http://darksoft.org
+Prefix: %{_prefix}
+Docdir: %{_docdir}
+BuildRequires: libfastwriter-devel libxml2-devel uthash
+BuildRequires: python python-devel swig 
+BuildRequires: kernel-devel dkms
+BuildRequires: doxygen
+BuildRequires: pkg-config libtool cmake
+Vendor: Institute for Data Processing and Electronics, KIT
+Packager: Suren A. Chilingaryan <csa@suren.me>
+
+%description 
+pcitool is a command line tool to manipulate PCI hardware. It provides ability
+to get/set registers, read/write data using DMA engine, and debug hardware 
+operation. 
+
+%package -n libpcilib${PCILIB_ABI_VERSION}
+Summary: User-space PCI library
+Group: Development/Libraries
+Requires: pcilib-python >= %{version}
+Requires: pcilib-dkms >= %{version}
+
+%description -n libpcilib${PCILIB_ABI_VERSION}
+pcilib is a user-space library providing structured access to the PCI hardware.
+API exposes 4 API layers.
+ - PCI memory access - allows to map PCI bar memory into the address space of 
+ user application and manipulate it directly.
+ - Register access - allows to read and write device registers. The register
+ model is defined using XML. Besides the direct hardware access, the register
+ values can be filtered using Python scripts. This allows to convert hardware
+ reading to standard units, make consistency checking, and create meta registers
+ setting multiple registers from a single parameter.
+ - DMA engine - allows high-speed reading and writting using DMA. The DMA 
+ engines are implemented in user-space as plugins.
+ - Event engine - allows polling for hardware events and grabbing the data
+ associated with the event in multiple supported formats. The event engines
+ are implemented as plugins and are not part of this package.
+ 
+%package -n libpcilib-devel
+Summary: Development files for pcilib
+Group: Development/Libraries 
+Requires: libpcilib${PCILIB_ABI_VERSION} = %{version}
+
+%description -n libpcilib-devel
+Development files for user-space PCI library
+
+%package -n pcilib-test
+Summary: Testing files for pcilib
+Group: Development/Libraries 
+Requires: libpcilib${PCILIB_ABI_VERSION} = %{version}
+
+%description -n pcilib-test
+Sample XML register model and a few applications for testing pcilib
+
+%package -n pcilib-python
+Summary: Python wrapper for pcilib
+Group: Development/Libraries 
+Requires: libpcilib${PCILIB_ABI_VERSION} = %{version}
+
+%description -n pcilib-python
+Python wrapper for pcilib. The python wrapper is used 
+ - By register scripts which are used to convert hardware reading to standard
+ units, make consistency checking, and create meta registers setting multiple 
+ registers from a single parameter.
+ - pcilib web api which used to provide register and dma access from remote
+ applications.
+
+%package -n pcilib-dkms
+Summary: Kernel module providing low-level PCI access
+Group: Development/Libraries 
+Requires: dkms bash gcc make
+
+%description -n pcilib-dkms
+Minimalistic driver used by pcilib to 
+ - Handle interrupts
+ - Map PCI regions into the user space
+ - Allocate persistent page-locked memory for DMA operations
+ and map it into the user-space
+ - Ensure access syncrhonization between multiple applications
+ 
+%package -n pcilib-server
+Summary: Pcilib Web API
+Group: Development/Libraries 
+Requires: pcilib-python = %{version}
+Requires: python
+
+%description -n pcilib-server
+Pcilib Web API and small demo web server.
+
+%prep
+%setup -q -n pcitool-%{version}
+
+%build
+cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \
+	-DPCILIB_PLUGIN_DIR=%{_libdir}/pcilib${PCILIB_ABI_VERSION}/ -DPCILIB_DATA_DIR=%{_datadir}/pcilib${PCILIB_ABI_VERSION}/ \
+	-DLIB_INSTALL_DIR=%{_libdir} -DBIN_INSTALL_DIR=%{_bindir} -DDATA_INSTALL_DIR=%{_datadir} -DINCLUDE_INSTALL_DIR=%{_includedir} -DPYTHON_INSTALL_DIR=%{python2_sitearch} .
+make
+make docs
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/%{_libdir}/pcilib${PCILIB_ABI_VERSION}/
+
+# scripts
+install -m 755 tests/reload.sh $RPM_BUILD_ROOT/%{_bindir}/pci-reload
+
+# udev
+mkdir -p $RPM_BUILD_ROOT/usr/lib/udev/rules.d
+install -m 644 misc/50-pcidriver.rules $RPM_BUILD_ROOT/%{_udevrulesdir}
+
+# DKMS
+mkdir -p $RPM_BUILD_ROOT/%{_includedir}/linux/
+install -m 644 driver/ioctl.h $RPM_BUILD_ROOT/%{_includedir}/linux/pcidriver.h
+mkdir -p $RPM_BUILD_ROOT/usr/src/%{modname}-%{version}/pcilib/
+install -m 644 misc/dkms.conf $RPM_BUILD_ROOT/%{_prefix}/src/%{modname}-%{version}/
+install -m 644 pcilib/*.h $RPM_BUILD_ROOT/%{_prefix}/src/%{modname}-%{version}/pcilib/
+cp -r driver $RPM_BUILD_ROOT/usr/src/%{modname}-%{version}/
+
+# Sample model
+cp -r xml/test $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/
+
+# Servers
+cp -r pyserver $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -n libpcilib${PCILIB_ABI_VERSION} -p /sbin/ldconfig
+
+%postun -n libpcilib${PCILIB_ABI_VERSION} -p /sbin/ldconfig
+
+%post -n pcilib-dkms
+if [ -z "`dkms status -m %{modname} -v %{version}`" ]; then
+	echo "Add module source to dkms"
+	dkms add -m %{modname} -v %{version} --rpm_safe_upgrade
+
+	echo "Build module with dkms"
+	dkms build -m %{modname} -v %{version}
+	dkms install -m %{modname} -v %{version}
+fi
+exit 0
+
+%preun -n pcilib-dkms
+/usr/sbin/dkms remove -m %{modname} -v %{version} --all --rpm_safe_upgrade
+exit 0
+
+%files
+%defattr(-, root, root)
+%{_bindir}/pci
+%{_bindir}/pci-reload
+
+%files -n libpcilib${PCILIB_ABI_VERSION}
+%defattr(-, root, root)
+%doc docs/README 
+%doc docs/HARDWARE
+%dir %{_libdir}/pcilib${PCILIB_ABI_VERSION}/
+%dir %{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/
+%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/*.xsd
+%{_libdir}/libpcilib.so.*
+
+%files -n libpcilib-devel
+%defattr(-, root, root)  
+%doc docs/html
+%{_includedir}/linux/pcidriver.h
+%{_includedir}/pcilib.h
+%{_includedir}/pcilib/
+%{_libdir}/lib*.so
+%{_libdir}/pkgconfig/*.pc
+
+%files -n pcilib-test
+%defattr(-, root, root)  
+%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/test
+
+%files -n pcilib-dkms
+%defattr(-, root, root)  
+%{_udevrulesdir}
+%{_prefix}/src/%{modname}-%{version}/
+
+%files -n pcilib-python
+%defattr(-, root, root)
+%{python2_sitearch}/*
+
+%files -n pcilib-server
+%defattr(-, root, root)  
+%{_datadir}/pcilib${PCILIB_ABI_VERSION}/pyserver
+
+%changelog
+* Fri Mar  4 2016 Suren A. Chilingaryan <csa@suren.me> - ${CPACK_PACKAGE_VERSION}
+- Added spec file to the sources

+ 2 - 2
pcitool/cli.c

@@ -2614,7 +2614,7 @@ int DetailKMEM(pcilib_t *handle, const char *device, const char *use, size_t blo
     printf("Buffer         Address          Hardware Address          Bus Address\n");
     printf("--------------------------------------------------------------------------------\n");
     for (; i < n; i++) {
-	void *data = pcilib_kmem_get_block_ua(handle, kbuf, i);
+	volatile void *data = pcilib_kmem_get_block_ua(handle, kbuf, i);
 	uintptr_t pa = pcilib_kmem_get_block_pa(handle, kbuf, i);
 	uintptr_t ba = pcilib_kmem_get_block_ba(handle, kbuf, i);
 	printf("%6lu     %16p     %16lx       %16lx\n", i, data, pa, ba);
@@ -2648,7 +2648,7 @@ int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size
 	return 0;
     }
 
-    data = pcilib_kmem_get_block_ua(handle, kbuf, block);
+    data = (void*)pcilib_kmem_get_block_ua(handle, kbuf, block);
     if (data) {
 	size = pcilib_kmem_get_block_size(handle, kbuf, block);
 	if ((max_size)&&(size > max_size)) size = max_size;

+ 3 - 3
protocols/software.c

@@ -21,7 +21,7 @@ typedef struct pcilib_software_register_bank_context_s pcilib_software_register_
 struct pcilib_software_register_bank_context_s {
     pcilib_register_bank_context_t bank_ctx;	/**< the bank context associated with the software registers */
     pcilib_kmem_handle_t *kmem;			/**< the kernel memory for software registers */
-    void *addr;					/**< the virtual adress of the allocated kernel memory*/
+    volatile void *addr;			/**< the virtual adress of the allocated kernel memory*/
 };
 
 void pcilib_software_registers_close(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx) {
@@ -131,7 +131,7 @@ int pcilib_software_registers_read(pcilib_t *ctx, pcilib_register_bank_context_t
 	return PCILIB_ERROR_INVALID_ADDRESS;
     }
 
-    pcilib_datacpy(&val, ((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, access, 1, b->raw_endianess);
+    pcilib_datacpy(&val, (void*)((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, access, 1, b->raw_endianess);
     *value = val;
 
     return 0;
@@ -147,7 +147,7 @@ int pcilib_software_registers_write(pcilib_t *ctx, pcilib_register_bank_context_
     }
 
     // we consider this atomic operation and, therefore, do no locking
-    pcilib_datacpy(((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, &value, access, 1, b->raw_endianess);
+    pcilib_datacpy((void*)((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, &value, access, 1, b->raw_endianess);
 
     return 0;
 }

+ 11 - 10
tests/reload.sh

@@ -1,25 +1,26 @@
 #! /bin/bash
-
-device=`lspci -n | grep -m 1 "10ee:" | awk '{print $1}'`
-if [ -z "$device" ]; then
+devdir=`ls -d /sys/bus/pci/devices/*/driver/module/drivers/pci:pciDriver`
+if [ $? -ne 0 ]; then
     echo "Xilinx device doesn't exist, rescanning..."
     echo 1 > /sys/bus/pci/rescan
     exit
 else
+    device=`echo $devdir | head -n 1 | cut -c 27-33`
     echo "Xilinx is located at: " $device
 fi
-echo "remove driver"
-rmmod pciDriver 
 echo "remove devices"
 echo  1 > /sys/bus/pci/devices/0000\:${device:0:2}\:${device:3:4}/remove
 sleep 1
 echo "rescan"
 echo 1 > /sys/bus/pci/rescan
 sleep 1
+echo "remove driver"
+rmmod pciDriver 
+sleep 1
 echo "instantiate driver"
 modprobe pciDriver
-# for devices with different ID
-#echo "10ee 6028" > /sys/bus/pci/drivers/pciDriver/new_id
-pci -i
-#echo Enabling bus mastering on device $dev
-#setpci -s $device 4.w=0x07
+sleep 1
+echo "set bus master dma"
+dev=$device  
+echo Enabling bus mastering on device $dev
+setpci -s $dev 4.w=0x07