summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.bzrignore9
-rw-r--r--CMakeLists.txt121
-rw-r--r--dma/ipe.c2
-rw-r--r--dma/nwl_engine.c4
-rw-r--r--dma/nwl_engine_buffers.h8
-rw-r--r--docs/BUGS5
-rw-r--r--driver/makefile (renamed from driver/Makefile)17
-rw-r--r--misc/dkms.conf.in10
-rw-r--r--misc/pcilib.in9
-rw-r--r--misc/pcilib.sysconfig.in12
-rw-r--r--misc/pcilib_api.service.in2
-rw-r--r--misc/pcilib_html.service.in2
-rw-r--r--misc/rpmlintrc8
-rw-r--r--pcilib/kmem.c6
-rw-r--r--pcilib/kmem.h6
-rw-r--r--pcilib/locking.c6
-rw-r--r--pcilib/py.c211
-rw-r--r--pcitool.spec.in204
-rw-r--r--pcitool/cli.c4
-rw-r--r--protocols/software.c6
-rw-r--r--pywrap/CMakeLists.txt1
-rwxr-xr-xtests/reload.sh21
22 files changed, 490 insertions, 184 deletions
diff --git a/.bzrignore b/.bzrignore
index 453185a..1fae1db 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -37,3 +37,12 @@ build
pcipywrap.py
pcipywrapPYTHON_wrap.c
apps/test_multithread
+pcitool.spec
+misc/dkms.conf
+CPackConfig.cmake
+CPackSourceConfig.cmake
+_CPack_Packages
+pcilib_api.service
+pcilib_html.service
+pcilib.conf
+pcilib.sysconfig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b5e9ca..3db7ca9 100644
--- a/CMakeLists.txt
+++ b/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")
@@ -9,15 +10,24 @@ cmake_minimum_required(VERSION 2.8)
set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library")
set(DISABLE_PYTHON FALSE CACHE BOOL "Disable python scripting support")
+set(DISABLE_SERVERS FALSE CACHE BOOL "Disable Web API 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,11 +42,35 @@ 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_SERVER_DIR)
+ set(PCILIB_SERVER_DIR "${PCILIB_DATA_DIR}/pyserver" CACHE PATH "Directory to install python server")
+endif (NOT DEFINED PCILIB_SERVER_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")
@@ -51,19 +85,26 @@ 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)
+if (NOT HAVE_PYTHON)
+ set(DISABLE_SERVERS TRUE)
+endif (NOT HAVE_PYTHON)
+
set(EXTRA_SYSTEM_LIBS -lrt)
+include(CheckIncludeFiles)
check_include_files(stdatomic.h HAVE_STDATOMIC_H)
find_path(UTHASH_INCLUDE_DIRS uthash.h PATH_SUFFIXES uthash)
@@ -94,7 +135,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}")
@@ -102,12 +142,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_PY_SERVER_INSTALL_DIR "${PCILIB_DATA_DIR}/pyserver" CACHE PATH "Directory to install python server")
-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)
@@ -126,18 +174,25 @@ 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)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile)
-if (HAVE_PYTHON)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_api.service.in
- ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_api.service)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_html.service.in
- ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_html.service)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib.in
- ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib)
-endif (HAVE_PYTHON)
+if (NOT DISABLE_SERVERS)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_api.service.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_api.service)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_html.service.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_html.service)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib.sysconfig.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib.sysconfig)
+endif (NOT DISABLE_SERVERS)
if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
file(COPY ${CMAKE_SOURCE_DIR}/xml DESTINATION ${CMAKE_BINARY_DIR})
@@ -157,18 +212,18 @@ install(FILES
DESTINATION ${LIB_INSTALL_DIR}/pkgconfig
)
-if (HAVE_PYTHON)
+if (NOT DISABLE_SERVERS)
#install Python servers
file(GLOB DEPLOY_FILES_AND_DIRS "${CMAKE_SOURCE_DIR}/pyserver/*")
foreach(ITEM ${DEPLOY_FILES_AND_DIRS})
- IF( IS_DIRECTORY "${ITEM}" )
- LIST( APPEND DIRS_TO_DEPLOY "${ITEM}" )
- ELSE()
- LIST( APPEND FILES_TO_DEPLOY "${ITEM}" )
- ENDIF()
- endforeach()
- INSTALL( FILES ${FILES_TO_DEPLOY} DESTINATION ${PCILIB_PY_SERVER_INSTALL_DIR} )
- INSTALL( DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION ${PCILIB_PY_SERVER_INSTALL_DIR} )
-endif (HAVE_PYTHON)
+ if( IS_DIRECTORY "${ITEM}" )
+ list(APPEND DIRS_TO_DEPLOY "${ITEM}")
+ else()
+ list(APPEND FILES_TO_DEPLOY "${ITEM}")
+ endif()
+ endforeach()
+ install(FILES ${FILES_TO_DEPLOY} DESTINATION ${PCILIB_SERVER_DIR})
+ install(DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION ${PCILIB_SERVER_DIR})
+endif (NOT DISABLE_SERVERS)
message("-- Configured pcitool ${PCILIB_VERSION_MAJOR}.${PCILIB_VERSION_MINOR}.${PCILIB_VERSION_MICRO} with public ABI ${PCILIB_ABI_VERSION}")
diff --git a/dma/ipe.c b/dma/ipe.c
index e1f7835..fb35dbc 100644
--- a/dma/ipe.c
+++ b/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;
diff --git a/dma/nwl_engine.c b/dma/nwl_engine.c
index b098943..f8ae6ac 100644
--- a/dma/nwl_engine.c
+++ b/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
diff --git a/dma/nwl_engine_buffers.h b/dma/nwl_engine_buffers.h
index 0cc5343..8d1185f 100644
--- a/dma/nwl_engine_buffers.h
+++ b/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);
diff --git a/docs/BUGS b/docs/BUGS
deleted file mode 100644
index 4b0c1cc..0000000
--- a/docs/BUGS
+++ /dev/null
@@ -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
diff --git a/driver/Makefile b/driver/makefile
index a55e7c7..ca44b94 100644
--- a/driver/Makefile
+++ b/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
diff --git a/misc/dkms.conf.in b/misc/dkms.conf.in
new file mode 100644
index 0000000..2e647a9
--- /dev/null
+++ b/misc/dkms.conf.in
@@ -0,0 +1,10 @@
+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}
+DEST_MODULE_LOCATION[0]="/extra"
+REMAKE_INITRD=no
+AUTOINSTALL=yes
diff --git a/misc/pcilib.in b/misc/pcilib.in
deleted file mode 100644
index 9b7352c..0000000
--- a/misc/pcilib.in
+++ /dev/null
@@ -1,9 +0,0 @@
-# API server parameters
-API_SERVER_DEVICE="/dev/fpga0"
-API_SERVER_MODEL="test"
-
-# HTML server parameters
-HTML_SERVER_PORT=5000
-
-#Scripts directory
-PCILIB_SCRIPTS_DIR="${PCILIB_PY_SERVER_INSTALL_DIR}/scripts"
diff --git a/misc/pcilib.sysconfig.in b/misc/pcilib.sysconfig.in
new file mode 100644
index 0000000..65edeb3
--- /dev/null
+++ b/misc/pcilib.sysconfig.in
@@ -0,0 +1,12 @@
+# Common parameters
+SERVER_DEVICE="/dev/fpga0"
+SERVER_MODEL="test"
+
+# API server parameters
+API_SERVER_PORT=9000
+
+# HTML server parameters
+HTML_SERVER_PORT=5000
+
+#Scripts directory
+PCILIB_SCRIPTS_DIR="${PCILIB_SERVER_DIR}/scripts"
diff --git a/misc/pcilib_api.service.in b/misc/pcilib_api.service.in
index 291a3e0..297772b 100644
--- a/misc/pcilib_api.service.in
+++ b/misc/pcilib_api.service.in
@@ -6,7 +6,7 @@ After=network.target nss-lookup.target
[Service]
Type=simple
EnvironmentFile=/etc/sysconfig/pcilib
-ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_PY_SERVER_INSTALL_DIR}/pcilib_api_server.py -d $API_SERVER_DEVICE -m $API_SERVER_MODEL
+ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_SERVER_DIR}/pcilib_api_server.py -d SERVER_DEVICE -m $SERVER_MODEL -p $API_SERVER_PORT
[Install]
WantedBy=multi-user.target
diff --git a/misc/pcilib_html.service.in b/misc/pcilib_html.service.in
index 634d9c7..7f03e77 100644
--- a/misc/pcilib_html.service.in
+++ b/misc/pcilib_html.service.in
@@ -8,7 +8,7 @@ After=pcilib_api.service
[Service]
Type=simple
EnvironmentFile=/etc/sysconfig/pcilib
-ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_PY_SERVER_INSTALL_DIR}/pcilib_html_server.py -p $HTML_SERVER_PORT -e
+ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_SERVER_DIR}/pcilib_html_server.py -d $SERVER_DEVICE -m $SERVER_MODEL -p $HTML_SERVER_PORT -e --api-server-port $API_SERVER_PORT
[Install]
WantedBy=multi-user.target
diff --git a/misc/rpmlintrc b/misc/rpmlintrc
new file mode 100644
index 0000000..d79a8b5
--- /dev/null
+++ b/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")
diff --git a/pcilib/kmem.c b/pcilib/kmem.c
index b103126..e1d60c5 100644
--- a/pcilib/kmem.c
+++ b/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;
}
diff --git a/pcilib/kmem.h b/pcilib/kmem.h
index 1d63e3b..e8d2827 100644
--- a/pcilib/kmem.h
+++ b/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
diff --git a/pcilib/locking.c b/pcilib/locking.c
index 71f204e..6ae4365 100644
--- a/pcilib/locking.c
+++ b/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);
}
diff --git a/pcilib/py.c b/pcilib/py.c
index 94d7ed8..03e9d8d 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -3,10 +3,9 @@
#ifdef HAVE_PYTHON
# include <Python.h>
-#if PY_MAJOR_VERSION >= 3
-#include <pthread.h>
-#endif /* PY_MAJOR_VERSION >= 3 */
-
+# if PY_MAJOR_VERSION >= 3
+# include <pthread.h>
+# endif /* PY_MAJOR_VERSION >= 3 */
#endif /* HAVE_PYTHON */
#include <stdio.h>
@@ -22,7 +21,7 @@
#include "error.h"
#ifdef HAVE_PYTHON
-#define PCILIB_PYTHON_WRAPPER "pcipywrap"
+# define PCILIB_PYTHON_WRAPPER "pcipywrap"
typedef struct pcilib_script_s pcilib_script_t;
@@ -32,14 +31,6 @@ struct pcilib_script_s {
UT_hash_handle hh; /**< hash */
};
-#if PY_MAJOR_VERSION >= 3
-typedef struct pcilib_py_s_thread_control {
- pthread_t pth;
- pthread_cond_t cond_finished;
- pthread_mutex_t cond_finished_lock;
-} pcilib_py_s_thread_control;
-#endif /* PY_MAJOR_VERSION < 3 */
-
struct pcilib_py_s {
int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */
PyObject *main_module; /**< Main interpreter */
@@ -47,9 +38,11 @@ struct pcilib_py_s {
PyObject *pcilib_pywrap; /**< pcilib wrapper module */
pcilib_script_t *script_hash; /**< Hash with loaded scripts */
-#if PY_MAJOR_VERSION >= 3
- pcilib_py_s_thread_control *thr_ctl; /**< Controller for Python main loop thread for Python 3 */
-#endif /* PY_MAJOR_VERSION < 3 */
+# if PY_MAJOR_VERSION >= 3
+ pthread_t pth;
+ pthread_cond_t cond;
+ pthread_mutex_t lock;
+# endif /* PY_MAJOR_VERSION > 3 */
};
#endif /* HAVE_PYTHON */
@@ -72,7 +65,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag
PyErr_NormalizeException(&pytype, &pyval, &pytraceback);
if (pyval) pystr = PyObject_Str(pyval);
-#if PY_MAJOR_VERSION >= 3
+# if PY_MAJOR_VERSION >= 3
if (pytype) {
if (PyUnicode_Check(pytype))
type = PyUnicode_AsUTF8(pytype);
@@ -82,7 +75,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag
if (pystr) {
val = PyUnicode_AsUTF8(pystr);
}
-#else /* PY_MAJOR_VERSION >= 3 */
+# else /* PY_MAJOR_VERSION >= 3 */
if (pytype) {
if (PyString_Check(pytype))
type = PyString_AsString(pytype);
@@ -92,7 +85,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag
if (pystr) {
val = PyString_AsString(pystr);
}
-#endif /*PY_MAJOR_VERSION >= 3*/
+# endif /*PY_MAJOR_VERSION >= 3*/
}
PyGILState_Release(gstate);
#endif /* HAVE_PYTHON */
@@ -133,26 +126,47 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag
}
#ifdef HAVE_PYTHON
-#if PY_MAJOR_VERSION >= 3
-void *pcilib_py_run_side_thread(void *arg) {
- pcilib_t *ctx = (pcilib_t*)(arg);
- //Initializing python
- Py_Initialize();
- PyEval_InitThreads();
- PyEval_ReleaseLock();
+# if PY_MAJOR_VERSION >= 3
+/**
+ * Python3 specially treats the main thread intializing Python. It crashes if
+ * the Lock is released and any Python code is executed under the GIL compaling
+ * that GIL is not locked. Python3 assumes that the main thread most of the time
+ * holds the Lock, only shortly giving it away to other threads and re-obtaining
+ * it hereafter. This is not possible to do with GILs, but instead (probably)
+ * PyEval_{Save,Restore}Thread() should be used. On other hand, the other threads
+ * are working fine with GILs. This makes things complicated as we need to know
+ * if we are running in main thread or not.
+ * To simplify matters, during initalization we start a new thread which will
+ * performa actual initialization of Python and, hence, act as main thread.
+ * We only intialize here. No python code is executed afterwards. So we don't
+ * need to care about special locking mechanisms in main thread. Instead all
+ * our user threads can use GILs normally.
+ * See more details here:
+ * http://stackoverflow.com/questions/24499393/cpython-locking-the-gil-in-the-main-thread
+ * http://stackoverflow.com/questions/15470367/pyeval-initthreads-in-python-3-how-when-to-call-it-the-saga-continues-ad-naus
+ */
+static void *pcilib_py_run_init_thread(void *arg) {
+ pcilib_py_t *py = (pcilib_py_t*)(arg);
+
+ Py_Initialize();
+ PyEval_InitThreads();
+ PyEval_ReleaseLock();
+
+ // Ensure that main thread waiting for our signal
+ pthread_lock(&(py->lock));
- //send initialization finish signal
- pthread_cond_signal(&(ctx->py->thr_ctl->cond_finished));
- pthread_mutex_unlock(&(ctx->py->thr_ctl->cond_finished_lock));
- pthread_mutex_destroy(&(ctx->py->thr_ctl->cond_finished_lock));
-
- //wait untill finish signal
- pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock));
- pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished),
- &(ctx->py->thr_ctl->cond_finished_lock));
- return NULL;
+ // Inform the parent thread that initialization is finished
+ pthread_cond_signal(&(py->cond));
+
+ // Wait untill cleanup is requested
+ pthread_cond_wait(&(py->cond), &(py->lock));
+ pthread_unlock(&(py->lock)));
+
+ Py_Finalize();
+
+ return NULL;
}
-#endif /* PY_MAJOR_VERSION < 3 */
+# endif /* PY_MAJOR_VERSION < 3 */
#endif /* HAVE_PYTHON */
int pcilib_init_py(pcilib_t *ctx) {
@@ -161,28 +175,42 @@ int pcilib_init_py(pcilib_t *ctx) {
if (!ctx->py) return PCILIB_ERROR_MEMORY;
memset(ctx->py, 0, sizeof(pcilib_py_t));
- if(!Py_IsInitialized()) {
-#if PY_MAJOR_VERSION >= 3
- //create thread controller
- ctx->py->thr_ctl = malloc(sizeof(pcilib_py_s_thread_control));
- if(!ctx->py->thr_ctl) return PCILIB_ERROR_MEMORY;
- memset(ctx->py->thr_ctl, 0, sizeof(pcilib_py_s_thread_control));
-
- //create side thread with python main loop
- pthread_create(&(ctx->py->thr_ctl->pth), NULL, pcilib_py_run_side_thread, ctx);
- pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock));
-
- //wait until Python initializes
- pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished),
- &(ctx->py->thr_ctl->cond_finished_lock));
-
-#else /* PY_MAJOR_VERSION < 3 */
- Py_Initialize();
- // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
- PyEval_InitThreads();
- PyEval_ReleaseLock();
-#endif /* PY_MAJOR_VERSION < 3 */
- ctx->py->finalyze = 1;
+ if (!Py_IsInitialized()) {
+# if PY_MAJOR_VERSION < 3
+ Py_Initialize();
+ // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads
+ PyEval_InitThreads();
+ PyEval_ReleaseLock();
+# else /* PY_MAJOR_VERSION < 3 */
+ err = pthread_mutex_init(&(ctx->py.lock));
+ if (err) return PCILIB_ERROR_FAILED;
+
+ err = pthread_cond_init(&(ctx->py.cond));
+ if (err) {
+ pthread_mutex_destroy(&(ctx->py.lock));
+ return PCILIB_ERROR_FAILED;
+ }
+
+ err = pthread_mutex_lock(&(ctx->py.lock));
+ if (err) {
+ pthread_cond_destroy(&(ctx->py.lock));
+ pthread_mutex_destroy(&(ctx->py.lock));
+ return PCILIB_ERROR_FAILED;
+ }
+
+ // Create initalizer thread and wait until it releases the Lock
+ err = pthread_create(&(ctx->py.pth), NULL, pcilib_py_run_init_thread, &(ctx->py));
+ if (err) {
+ pthread_mutex_unlock(&(ctx->py.lock));
+ pthread_cond_destroy(&(ctx->py.cond));
+ pthread_mutex_destroy(&(ctx->py.lock));
+ return PCILIB_ERROR_FAILED;
+ }
+
+ // Wait until initialized and keep the lock afterwards until free executed
+ pthread_cond_wait(&(ctx->py.cond), (ctx->py.lock));
+# endif /* PY_MAJOR_VERSION < 3 */
+ ctx->py->finalyze = 1;
}
@@ -190,22 +218,22 @@ int pcilib_init_py(pcilib_t *ctx) {
ctx->py->main_module = PyImport_AddModule("__parser__");
if (!ctx->py->main_module) {
- pcilib_python_warning("Error importing python parser");
PyGILState_Release(gstate);
+ pcilib_python_warning("Error importing python parser");
return PCILIB_ERROR_FAILED;
}
ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module);
if (!ctx->py->global_dict) {
- pcilib_python_warning("Error locating global python dictionary");
PyGILState_Release(gstate);
+ pcilib_python_warning("Error locating global python dictionary");
return PCILIB_ERROR_FAILED;
}
PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER);
if (!pywrap) {
- pcilib_python_warning("Error importing pcilib python wrapper");
PyGILState_Release(gstate);
+ pcilib_python_warning("Error importing pcilib python wrapper");
return PCILIB_ERROR_FAILED;
}
@@ -216,8 +244,8 @@ int pcilib_init_py(pcilib_t *ctx) {
Py_XDECREF(mod_name);
if (!ctx->py->pcilib_pywrap) {
- pcilib_python_warning("Error initializing python wrapper");
PyGILState_Release(gstate);
+ pcilib_python_warning("Error initializing python wrapper");
return PCILIB_ERROR_FAILED;
}
@@ -253,15 +281,15 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
pypath = PySys_GetObject("path");
if (!pypath) {
- pcilib_python_warning("Can't get python path");
PyGILState_Release(gstate);
+ pcilib_python_warning("Can't get python path");
return PCILIB_ERROR_FAILED;
}
pynewdir = PyUnicode_FromString(script_dir);
if (!pynewdir) {
- pcilib_python_warning("Can't create python string");
PyGILState_Release(gstate);
+ pcilib_python_warning("Can't create python string");
return PCILIB_ERROR_MEMORY;
}
@@ -290,13 +318,12 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
if (pyret) Py_DECREF(pyret);
Py_DECREF(pynewdir);
+ PyGILState_Release(gstate);
+
if (err) {
pcilib_python_warning("Can't add directory (%s) to python path", script_dir);
- PyGILState_Release(gstate);
return err;
}
-
- PyGILState_Release(gstate);
#endif /* HAVE_PYTHON */
return 0;
@@ -305,14 +332,13 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) {
void pcilib_free_py(pcilib_t *ctx) {
#ifdef HAVE_PYTHON
int finalyze = 0;
- PyGILState_STATE gstate;
-#if PY_MAJOR_VERSION >= 3
- pcilib_py_s_thread_control *thr_ctl = ctx->py->thr_ctl;
-#endif /* PY_MAJOR_VERSION < 3 */
-
if (ctx->py) {
+ PyGILState_STATE gstate;
+
if (ctx->py->finalyze) finalyze = 1;
+
+ gstate = PyGILState_Ensure();
if (ctx->py->script_hash) {
pcilib_script_t *script, *script_tmp;
@@ -325,12 +351,11 @@ void pcilib_free_py(pcilib_t *ctx) {
ctx->py->script_hash = NULL;
}
- if (ctx->py->pcilib_pywrap) {
- gstate = PyGILState_Ensure();
+ if (ctx->py->pcilib_pywrap)
Py_DECREF(ctx->py->pcilib_pywrap);
- PyGILState_Release(gstate);
- }
-
+
+ PyGILState_Release(gstate);
+
free(ctx->py);
ctx->py = NULL;
@@ -339,26 +364,16 @@ void pcilib_free_py(pcilib_t *ctx) {
if (finalyze) {
#if PY_MAJOR_VERSION >= 3
-
- //stop python side thread
- pthread_cond_signal(&(thr_ctl->cond_finished));
- pthread_mutex_unlock(&(thr_ctl->cond_finished_lock));
- pthread_join(thr_ctl->pth, NULL);
-
- //free python
- //must be finalized in main thread to correctly stop python threading
- PyGILState_Ensure();
- Py_Finalize();
-
- //destroy thread controllers
- pthread_mutex_destroy(&(thr_ctl->cond_finished_lock));
- pthread_cond_destroy(&(thr_ctl->cond_finished));
- free(thr_ctl);
+ // singal python init thread to stop and wait it to finish
+ pthread_cond_signal(&(ctx->py.cond));
+ pthread_mutex_unlock(&(ctx->py.lock));
+ pthread_join(ctx->py.pth, NULL);
+ // destroy synchronization primitives
+ pthread_cond_destroy(&(ctx->py.cond));
+ pthread_mutex_destroy(&(ctx->py.lock));
#else /* PY_MAJOR_VERSION < 3 */
-
Py_Finalize();
-
#endif /* PY_MAJOR_VERSION < 3 */
}
@@ -388,14 +403,12 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) {
if (module) return 0;
gstate = PyGILState_Ensure();
-
pymodule = PyImport_ImportModule(module_name);
if (!pymodule) {
- pcilib_python_error("Error importing script (%s)", script_name);
PyGILState_Release(gstate);
+ pcilib_python_error("Error importing script (%s)", script_name);
return PCILIB_ERROR_FAILED;
}
-
PyGILState_Release(gstate);
module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
@@ -433,8 +446,8 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_
dict = PyModule_GetDict(module->module);
if (!dict) {
- pcilib_python_error("Error getting dictionary for script (%s)", script_name);
PyGILState_Release(gstate);
+ pcilib_python_error("Error getting dictionary for script (%s)", script_name);
return PCILIB_ERROR_FAILED;
}
diff --git a/pcitool.spec.in b/pcitool.spec.in
new file mode 100644
index 0000000..a8b1d9b
--- /dev/null
+++ b/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
diff --git a/pcitool/cli.c b/pcitool/cli.c
index caa55a9..1fc2abb 100644
--- a/pcitool/cli.c
+++ b/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;
diff --git a/protocols/software.c b/protocols/software.c
index 5b217d4..ca15d8d 100644
--- a/protocols/software.c
+++ b/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;
}
diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt
index 933d2ff..033298e 100644
--- a/pywrap/CMakeLists.txt
+++ b/pywrap/CMakeLists.txt
@@ -23,5 +23,4 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pcilib.py DESTINATION ${PYTHON_INSTALL
if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_pcilib.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
- configure_file(pcilib.py pcilib.py)
endif(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
diff --git a/tests/reload.sh b/tests/reload.sh
index 62c6e22..13a8c63 100755
--- a/tests/reload.sh
+++ b/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