Browse Source

First stand-alone ipecamera implementation

Suren A. Chilingaryan 9 years ago
parent
commit
e1265fa328
100 changed files with 206 additions and 14400 deletions
  1. 2 24
      .bzrignore
  2. 0 18
      BUGS
  3. 19 60
      CMakeLists.txt
  4. 0 311
      NOTES
  5. 0 22
      ToDo
  6. 0 19
      apps/CMakeLists.txt
  7. 0 45
      apps/check_counter.c
  8. 0 66
      apps/compare_to_value.c
  9. 0 98
      apps/heb_strip_bad_values.c
  10. 0 749
      apps/lorenzo_ipedma_test.c
  11. 0 96
      apps/pio_test.c
  12. 0 225
      apps/xilinx.c
  13. 32 43
      base.c
  14. 4 5
      base.h
  15. 0 3101
      cli.c
  16. 24 19
      cmosis.c
  17. 9 0
      cmosis.h
  18. 0 61
      common.mk
  19. 3 3
      data.c
  20. 0 0
      data.h
  21. 0 34
      default.c
  22. 0 9
      default.h
  23. 0 327
      dma.c
  24. 0 52
      dma.h
  25. 0 9
      dma/CMakeLists.txt
  26. 0 541
      dma/ipe.c
  27. 0 42
      dma/ipe.h
  28. 0 59
      dma/ipe_private.h
  29. 0 44
      dma/ipe_registers.h
  30. 0 139
      dma/nwl.c
  31. 0 46
      dma/nwl.h
  32. 0 145
      dma/nwl_defines.h
  33. 0 318
      dma/nwl_engine.c
  34. 0 12
      dma/nwl_engine.h
  35. 0 412
      dma/nwl_engine_buffers.h
  36. 0 119
      dma/nwl_irq.c
  37. 0 10
      dma/nwl_irq.h
  38. 0 255
      dma/nwl_loopback.c
  39. 0 7
      dma/nwl_loopback.h
  40. 0 67
      dma/nwl_private.h
  41. 0 77
      dma/nwl_register.c
  42. 0 97
      dma/nwl_register.h
  43. 0 49
      driver/Makefile
  44. 0 676
      driver/base.c
  45. 0 85
      driver/base.h
  46. 0 108
      driver/common.h
  47. 0 198
      driver/compat.h
  48. 0 23
      driver/config.h
  49. 0 258
      driver/int.c
  50. 0 9
      driver/int.h
  51. 0 471
      driver/ioctl.c
  52. 0 5
      driver/ioctl.h
  53. 0 657
      driver/kmem.c
  54. 0 9
      driver/kmem.h
  55. 0 217
      driver/pciDriver.h
  56. 0 308
      driver/sysfs.c
  57. 0 23
      driver/sysfs.h
  58. 0 438
      driver/umem.c
  59. 0 5
      driver/umem.h
  60. 0 27
      error.c
  61. 0 34
      error.h
  62. 0 450
      event.c
  63. 0 69
      event.h
  64. 4 4
      events.c
  65. 0 0
      events.h
  66. 1 0
      ipecamera.h
  67. 0 12
      ipecamera/CMakeLists.txt
  68. 0 55
      irq.c
  69. 0 5
      irq.h
  70. 0 9
      kapture/CMakeLists.txt
  71. 0 62
      kapture/kapture.c
  72. 0 6
      kapture/kapture.h
  73. 0 81
      kapture/model.h
  74. 0 10
      kapture/private.h
  75. 0 81
      kernel.h
  76. 0 310
      kmem.c
  77. 0 80
      kmem.h
  78. 0 1
      misc/50-pcidriver.rules
  79. 60 45
      model.c
  80. 18 0
      model.h
  81. 0 473
      pci.c
  82. 0 85
      pci.h
  83. 0 380
      pcilib.h
  84. 0 44
      pcilib_types.h
  85. 0 8
      pcitool/CMakeLists.txt
  86. 0 47
      pcitool/formaters.c
  87. 0 12
      pcitool/formaters.h
  88. 0 172
      pcitool/sysinfo.c
  89. 0 7
      pcitool/sysinfo.h
  90. 12 8
      private.h
  91. 12 16
      reader.c
  92. 0 0
      reader.h
  93. 0 362
      register.c
  94. 0 14
      register.h
  95. 3 2
      tests/autotrigger.sh
  96. 3 2
      tests/debug/incomplete.sh
  97. 0 19
      tests/dma/debug/test-iommu.sh
  98. 0 40
      tests/dma/ipe/bench.sh
  99. 0 30
      tests/dma/nwl/bench.sh
  100. 0 13
      tests/dma/nwl/cleanup.sh

+ 2 - 24
.bzrignore

@@ -1,27 +1,5 @@
-*.cmd
-pciDriver.ko
-pciDriver.mod.c
-pci.d
-tools.d
-modules.order
-Module.symvers
-./pci
-.tmp_versions
-cli.d
-ipecamera.d
-pci.d
-tools.d
-*.d
-CMakeCache.txt
 CMakeFiles
-cmake_install.cmake
 Makefile
-*.so.*
+cmake_install.cmake
+CMakeCache.txt
 install_manifest.txt
-apps/xilinx
-apps/pio_test
-apps/compare_to_value
-apps/heb_strip_bad_values
-*.out
-apps/check_counter
-apps/lorenzo_ipedma_test

+ 0 - 18
BUGS

@@ -1,18 +0,0 @@
-IPECamera Hardware Bugs
-=======================
- 1. Strange sequence writting CMOSIS registers
- 2. Extra 8 byte padding in the end of frames
- 3. Solve the conflict between DMA packet_length register and FPGA registers
- 4. Some frame requests are lost
-
-Incomplete Frames
------------------
- If I'm trying to stream the data, the camera from time to time returns 
- incomplete frames. The provided part of the frame is coherent. But instead 
- of at least 3063824 bytes (just full frame without padding, normally I get 
- more due to the padding) I get only 3063808 bytes. This number 3063808 looks 
- like to be constant.
-
- If I send another frame request, however, it looks I got the missing data with 
- the next frame.
-

+ 19 - 60
CMakeLists.txt

@@ -1,81 +1,40 @@
-project(pcitool)
+project(ipecamera)
 
-set(PCILIB_VERSION "0.1.0")
-set(PCILIB_ABI_VERSION "1")
+set(IPECAMERA_VERSION "0.0.1")
+set(IPECAMERA_ABI_VERSION "0")
 
 cmake_minimum_required(VERSION 2.6)
-
-set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library") 
-
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 find_package(PkgConfig REQUIRED)
 find_package(Threads REQUIRED)
+pkg_check_modules(UFODECODE ufodecode>=0.3 REQUIRED)
 
-#Check in sibling directory
-pkg_check_modules(UFODECODE ufodecode>=0.2 REQUIRED)
-
-if (NOT DISABLE_PCITOOL)
-    pkg_check_modules(FASTWRITER fastwriter REQUIRED)
-endif (NOT DISABLE_PCITOOL)
-
-set(HEADERS pcilib.h pci.h register.h kmem.h irq.h dma.h event.h default.h tools.h error.h)
-add_definitions("-fPIC --std=c99 -Wall -O2")
-#add_definitions("-fPIC --std=c99 -Wall -O2 -pthread")
-
-add_subdirectory(dma)
-add_subdirectory(ipecamera)
-add_subdirectory(kapture)
-add_subdirectory(pcitool)
-add_subdirectory(apps)
+pkg_check_modules(PCILIB pcitool>=0.2 REQUIRED)
+exec_program("pkg-config --variable=plugindir pcitool" OUTPUT_VARIABLE PCILIB_PLUGIN_DIR)
 
 include_directories(
-    ${FASTWRITER_INCLUDE_DIRS}
+    ${CMAKE_SOURCE_DIR}
+    ${UFODECODE_INCLUDE_DIRS}
+    ${PCILIB_INCLUDE_DIRS}
 )
 
 link_directories(
-    ${FASTWRITER_LIBRARY_DIRS}
     ${UFODECODE_LIBRARY_DIRS}
+    ${PCILIB_LIBRARY_DIRS}
 )
 
-add_library(pcilib SHARED pci.c register.c kmem.c irq.c dma.c event.c default.c tools.c error.c) 
-target_link_libraries(pcilib dma ipecamera kapture ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} )
-add_dependencies(pcilib dma ipecamera)
-
-set_target_properties(pcilib PROPERTIES
-    VERSION ${PCILIB_VERSION}
-    SOVERSION ${PCILIB_ABI_VERSION}
-#    LINK_FLAGS "-pthread"
-#    LINK_FLAGS "-pthread -Wl,--whole-archive,dma/libdma.a,ipecamera/libipecamera.a,--no-whole-archive"
-)
+set(HEADERS ${HEADERS} model.h cmosis.h base.h reader.h events.h data.h private.h ipecamera.h)
 
-if (NOT DISABLE_PCITOOL)
-    add_executable(pci cli.c)
-    add_dependencies(pci pcitool)
-    target_link_libraries(pci pcilib pcitool ${FASTWRITER_LIBRARIES})
-    set_target_properties(pci PROPERTIES
-	LINK_FLAGS ${CMAKE_THREAD_LIBS_INIT}
-    )
-endif (NOT DISABLE_PCITOOL)
+add_library(ipecamera SHARED model.c cmosis.c base.c reader.c events.c data.c)
 
-#set_target_properties(pci PROPERTIES
-#    LINK_FLAGS "-Wl,pcitool/libpcitool.a"
-#)
+target_link_libraries(ipecamera ${PCILIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
 
-if(NOT DEFINED BIN_INSTALL_DIR)
-    set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
-endif(NOT DEFINED BIN_INSTALL_DIR)
-
-
-install(TARGETS pcilib
-    LIBRARY DESTINATION lib${LIB_SUFFIX}
+install(FILES ipecamera.h
+    DESTINATION include
 )
 
-if (NOT DISABLE_PCITOOL)
-    install(TARGETS pci
-	DESTINATION ${BIN_INSTALL_DIR}
-    )
-endif (NOT DISABLE_PCITOOL)
-
-install(FILES pcilib.h
-    DESTINATION include
+install(TARGETS ipecamera
+    DESTINATION ${PCILIB_PLUGIN_DIR}
 )
+

+ 0 - 311
NOTES

@@ -1,311 +0,0 @@
-Memory Addressing
-=================
- There is 3 types of addresses: virtual, physical, and bus. For DMA a bus
- address is used. However, on x86 physical and  bus addresses are the same (on
- other architectures it is not guaranteed). Anyway, this assumption is still
- used by xdma driver, it uses phiscal address for DMA access. I have ported
- in the same way. Now, we need to provide additionaly bus-addresses in kmem
- abstraction and use it in NWL DMA implementation.
-
-DMA Access Synchronization
-==========================
- - At driver level, few types of buffers are supported:
-    * SIMPLE - non-reusable buffers, the use infomation can be used for cleanup
-    after crashed applications.
-    * EXCLUSIVE - reusable buffers which can be mmaped by a single appliction
-    only. There is two modes of these buffers:
-	+ Buffers in a STANDARD mode are created for a single DMA operation and
-	if such buffer is detected while trying to reuse, the last operation
-	has failed and reset is needed.
-	+ Buffers in a PERSISTENT mode are preserved between invocations of
-	control application and cleaned up only after the PERSISTENT flag is 
-	removed
-    * SHARED - reusable buffers shared by multiple processes. Not really 
-    needed at the moment.
-
-    KMEM_FLAG_HW - indicates that buffer can be used by hardware, acually this
-    means that DMA will be enabled afterwards. The driver is not able to check
-    if it really was enable and therefore will block any attempt to release 
-    buffer until KMEM_HW_FLAG is passed to kmem_free routine as well. The later
-    should only called with KMEM_HW_FLAG after the DMA engine is stopped. Then,
-    the driver can be realesd by kmem_free if ref count reaches 0.
-    
-    KMEM_FLAG_EXCLUSIVE - prevents multiple processes mmaping the buffer 
-    simultaneously. This is used to prevent multiple processes use the same
-    DMA engine at the same time. When passed to kmem_free, allows to clean
-    buffers with lost clients even for shared buffers.
-    
-    KMEM_FLAG_REUSE - requires reuse of existing buffer. If reusable buffer is 
-    found (non-reusable buffers, i.e. allocated without KMEM_FLAG_REUSE are
-    ignored), it is returned instead of allocation. Three types of usage 
-    counters are used. At moment of allocation, the HW reference is set if 
-    neccessary. The usage counter is increased by kmem_alloc function and
-    decreased by kmem_free. Finally, the reference is obtained at returned
-    during mmap/munmap. So, on kmem_free, we do not clean
-	a) buffers with reference count above zero or hardware reference set.
-	REUSE flag should be supplied, overwise the error is returned
-	b) PERSISTENT buffer. REUSE flash should be supplied, overwise the 
-	error is returned
-	c) non-exclusive buffers with usage counter above zero (For exclusive
-	buffer the value of usage counter above zero just means that application
-        have failed without cleaning buffers first. There is no easy way to 
-        detect that for shared buffers, so it is left as manual operation in
-        this case)
-        d) any buffer if KMEM_FLAG_REUSE was provided to function
-    During module unload, only buffers with references can prevent cleanup. In
-    this case the only possiblity to free the driver is to call kmem_free 
-    passing FORCE flags.
-    
-    KMEM_FLAG_PERSISTENT - if passed to allocation routine, changes mode of 
-    buffer to PERSISTENT, if passed to free routine, vice-versa changes mode
-    of buffer to NORMAL. Basically, if we call 'pci --dma-start' this flag
-    should be passed to alloc and if we call 'pci --dma-stop' it should be
-    passed to free. In other case, the flag should not be present.
-
-    If application crashed, the munmap while be still called cleaning software
-    references. However, the hardware reference will stay since it is not clear
-    if hardware channel was closed or not. To lift hardware reference, the 
-    application can be re-executed (or dma_stop called, for instance).
-    * If there is no hardware reference, the buffers will be reused by next 
-    call to application and for EXCLUSIVE buffer cleaned at the end. For SHARED
-    buffers they will be cleaned during module cleanup only (no active 
-    references).
-    * The buffer will be reused by next call which can result in wrong behaviour
-    if buffer left in incoherent stage. This should be handled on upper level.
-    
- - At pcilib/kmem level synchronization of multiple buffers is performed
-    * The HW reference and following modes should be consistent between member 
-    parts: REUSABLE, PERSISTENT, EXCLUSIVE (only HW reference and PERSISTENT 
-    mode should be checked, others are handled on dirver level)
-    * It is fine if only part of buffers are reused and others are newly 
-    allocated. However, on higher level this can be checked and resulting
-    in failure.
-    
-    Treatment of inconsistencies:
-     * Buffers are in PRESISTENT mode, but newly allocated, OK
-     * Buffers are reused, but are not in PERSISTENT mode (for EXCLUSIVE buffers
-     this means that application has crashed during the last execution), OK
-     * Some of buffers are reused (not just REUSABLE, but actually reused), 
-     others - not, OK until 
-        a) either PERSISTENT flag is set or reused buffers are non-PERSISTENT
-	b) either HW flag is set or reused buffers does not hold HW reference
-     * PERSISTENT mode inconsistency, FAIL (even if we are going to set 
-     PERSISTENT mode anyway)
-     * HW reference inconsistency, FAIL (even if we are going to set 
-     HW flag anyway)
-     
-    On allocation error at some of the buffer, call clean routine and
-     * Preserve PERSISTENT mode and HW reference if buffers held them before
-     unsuccessful kmem initialization. Until the last failed block, the blocks
-     of kmem should be consistent. The HW/PERSISTENT flags should be removed
-     if all reused blocks were in HW/PERSISTENT mode. The last block needs
-     special treatment. The flags may be removed for the block if it was
-     HW/PERSISTENT state (and others not).
-     * Remove REUSE flag, we want to clean if allowed by current buffer status
-     * EXCLUSIVE flag is not important for kmem_free routine.
-    
- - At DMA level
-    There is 4 components of DMA access:
-    * DMA engine enabled/disabled
-    * DMA engine IRQs enabled/disabled - always enabled at startup
-    * Memory buffers
-    * Ring start/stop pointers
-    
-    To prevent multiple processes accessing DMA engine in parallel, the first
-    action is buffer initialization which will fail if buffers already used
-	* Always with REUSE, EXCLUSIVE, and HW flags 
-	* Optionally with PERSISTENT flag (if DMA_PERSISTENT flag is set)
-    If another DMA app is running, the buffer allocation will fail (no dma_stop 
-    is executed in this case) 
-
-    Depending on PRESERVE flag, kmem_free will be called with REUSE flag 
-    keeping buffer in memory (this is redundant since HW flag is enough) or HW
-    flag indicating that DMA engine is stopped and buffer could be cleaned.
-    PERSISTENT flag is defined by DMA_PERSISTENT flag passed to stop routine.
-    
-    PRESERVE flag is enforced if DMA_PERSISTENT is not passed to dma_stop
-    routine and either it:
-	a) Explicitely set by DMA_PERMANENT flag passed to dma_start 
-	function 
-	b) Implicitely set if DMA engine is already enabled during dma_start, 
-	all buffers are reused, and are in persistent mode.
-    If PRESERVE flag is on, the engine will not be stopped at the end of
-    execution (and buffers will stay because of HW flag).
-    
-    If buffers are reused and are already in PERSISTENT mode, DMA engine was on 
-    before dma_start (PRESERVE flag is ignored, because it can be enforced), 
-    ring pointers are calculated from LAST_BD and states of ring elements.
-    If previous application crashed (i.e. buffers may be corrupted). Two
-    cases are possible:
-    * If during the call buffers were in non-PERSISTENT mode, it can be 
-    easily detected - buffers are reused, but are not in PERSISTENT mode 
-    (or at least was not before we set them to). In this case we just 
-    reinitialize all buffers.
-    * If during the call buffers were in PERSISTENT mode, it is up to 
-    user to check their consistency and restart DMA engine.]
-    
-    IRQs are enabled and disabled at each call
-
-DMA Reads
-=========
-standard: 		default reading mode, reads a single full packet
-multipacket:		reads all available packets
-waiting multipacket:	reads all available packets, after finishing the
-			last one waiting if new data arrives
-exact read:		read exactly specified number of bytes (should be
-			only supported if it is multiple of packets, otherwise
-			error should be returned)
-ignore packets:		autoterminate each buffer, depends on engine 
-			configuration
-
- To handle differnt cases, the value returned by callback function instructs
-the DMA library how long to wait for the next data to appear before timing 
-out. The following variants are possible:
-terminate:		just bail out
-check:			no timeout, just check if there is data, otherwise 
-			terminate
-timeout:		standard DMA timeout, normaly used while receiving
-			fragments of packet: in this case it is expected 
-			that device has already prepared data and only
-			the performance of DMA engine limits transfer speed
-wait:			wait until the data is prepared by the device, this
-			timeout is specified as argument to the dma_stream
-			function (standard DMA timeout is used by default)
-
-			first |  new_pkt  | bufer 
-			--------------------------	
-standard		wait  | term      | timeout  
-multiple packets	wait  | check	  | timeout 	- DMA_READ_FLAG_MULTIPACKET 	
-waiting multipacket	wait  | wait      | timeout 	- DMA_READ_FLAG_WAIT
-exact			wait  | wait/term | timeout	- limited by size parameter
-ignore packets		wait  | wait/check| wait/check 	- just autoterminated
-
-Shall we do a special handling in case of overflow?
-    
-
-Buffering
-=========
- The DMA addresses are limited to 32 bits (~4GB for everything). This means we 
- can't really use DMA pages are sole buffers. Therefore, a second thread, with
- a realtime scheduling policy if possible, will be spawned and will copy the 
- data from the DMA pages into the allocated buffers. On expiration of duration
- or number of events set by autostop call, this thread will be stopped but 
- processing in streaming mode will continue until all copyied data is passed 
- to the callbacks.
-
- To avoid stalls, the IPECamera requires data to be read continuously read out.
- For this reason, there is no locks in the readout thread. It will simplify
- overwrite the old frames if data is not copied out timely. To handle this case
- after getting the data and processing it, the calling application should use
- return_data function and check return code. This function may return error
- indicating that the data was overwritten meanwhile. Hence, the data is 
- corrupted and shoud be droped by the application. The copy_data function
- performs this check and user application can be sure it get coherent data
- in this case.
- 
- There is a way to avoid this problem. For raw data, the rawdata callback
- can be requested. This callback blocks execution of readout thread and 
- data may be treated safely by calling application. However, this may 
- cause problems to electronics. Therefore, only memcpy should be performed
- on the data normally. 
-
- The reconstructed data, however, may be safely accessed. As described above,
- the raw data will be continuously overwritten by the reader thread. However,
- reconstructed data, upon the get_data call, will be protected by the mutex.
-
-
-Register Access Synchronization
-===============================
- We need to serialize access to the registers by the different running 
- applications and handle case when registers are accessed indirectly by
- writting PCI BARs (DMA implementations, for instance).
-
- - Module-assisted locking:
- * During initialization the locking context is created (which is basicaly
- a kmem_handle of type LOCK_PAGE. 
- * This locking context is passed to the kernel module along with lock type 
- (LOCK_BANK) and lock item (BANK ADDRESS). If lock context is already owns
- lock on the specified bank, just reference number is increased, otherwise
- we are trying to obtain new lock.
- * Kernel module just iterates over all registered lock pages and checks if
- any holds the specified lock. if not, the lock is obtained and registered
- in the our lock page.
- * This allows to share access between multiple threads of single application
- (by using the same lock page) or protect (by using own lock pages by each of
- the threads)
- * Either on application cleanup or if application crashed, the memory mapping
- of lock page is removed and, hence, locks are freed.
- 
- - Multiple-ways of accessing registers
- Because of reference counting, we can successfully obtain locks multiple 
- times if necessary. The following locks are protecting register access:
-  a) Global register_read/write lock bank before executing implementation
-  b) DMA bank is locked by global DMA functions. So we can access the 
-  registers using plain PCI bar read/write.
-  c) Sequence of register operations can be protected with pcilib_lock_bank
-  function
- Reading raw register space or PCI bank is not locked.
-  * Ok. We can detect banks which will be affected by PCI read/write and 
-  lock them. But shall we do it?
- 
-Register/DMA Configuration
-==========================
- - XML description of registers
- - Formal XML-based (or non XML-based) language for DMA implementation. 
-   a) Writting/Reading register values
-   b) Wait until <register1>=<value> on <register2>=<value> report error
-   c) ... ?
-
-IRQ Handling
-============
- IRQ types: DMA IRQ, Event IRQ, other types
- IRQ hardware source: To allow purely user-space implementation, as general
- rule, only a  single (standard) source should be used.
- IRQ source: The dma/event engines, however, may detail this hardware source
- and produce real IRQ source basing on the values of registers. For example, 
- for DMA IRQs the source may present engine number and for Event IRQs the 
- source may present event type.
-
- Only types can be enabled or disabled. The sources are enabled/disabled
- by enabling/disabling correspondent DMA engines or Event types. The expected
- workflow is following:
- * We enabling IRQs in user-space (normally setting some registers). Normally,
- just an Event IRQs, the DMA if necessary will be managed by DMA engine itself.
- * We waiting for standard IRQ from hardware (driver)
- * In the user space, we are checking registers to find out the real source
- of IRQ (driver reports us just hardware source), generating appropriate 
- events, and acknowledge IRQ. This is dependent on implementation and should 
- be managed inside event API.
- 
- I.e. the driver implements just two methods pcilib_wait_irq(hw_source), 
- pcilib_clear_irq(hw_source). Only a few hardware IRQ sources are defined.
- In most cirstumances, the IRQ_SOURCE_DEFAULT is used. 
- 
- The DMA engine may provide 3 additional methods, to enable, disable,
- and acknowledge IRQ.
- 
- ... To be decided in details upon the need...
-
-Updating Firmware
-=================
- - JTag should be connected to USB connector on the board (next to Ethernet)
- - The computer should be tourned off and on before programming
- - The environment variable should be loaded
-    . /home/uros/.bashrc
- - The application is called 'impact'
-    No project is needed, cancel initial proposals (No/Cancel)
-    Double-click on "Boundary Scan"
-    Right click in the right window and select "Init Chain"
-    We don't want to select bit file now (Yes and, then, click Cancel)
-    Right click on second (right) item and choose "Assign new CF file"
-    Select a bit file. Answer No, we don't want to attach SPI to SPI Prom
-    Select xv6vlx240t and program it
- - Shutdown and start computer
- 
- Firmware are in
-    v.2: /home/uros/Repo/UFO2_last_good_version_UFO2.bit
-    v.3: /home/uros/Repo/UFO3 
-	Step5 - best working revision
-	Step6 - last revision
-
-    

+ 0 - 22
ToDo

@@ -1,22 +0,0 @@
-High Priority (we would need it for IPE Camera)
-=============
- 1. Serialize access to the registers across applications
- 2. Protect kmem_entries in the driver using spinlock
- 3. Implement pcilib_configure_autotrigger
- 
-Normal Priority (it would make just few things a bit easier)
-===============
- 1. Implement software registers (stored in kernel-memory)
- 2. Support FIFO reads/writes from/to registers
- 3. Provide OR and AND operations on registers in cli
- 4. Support writting a data from a binary file in cli
- 5. Use bus-addresses instead of physcial addresses for DMA 
- 
-Low Priority (only as generalization for other projects)
-============
- 1. XML configurations describing registers (and DMA engines?)
- 2. Access register/bank lookups using hash tables
- 3. Support for Network Registers and Network DMA
- 4. Define a syntax for register dependencies / delays (?)
- 5. Use pthread_condition_t instead of polling
-

+ 0 - 19
apps/CMakeLists.txt

@@ -1,19 +0,0 @@
-include_directories(
-    ${CMAKE_SOURCE_DIR}
-)
-
-link_directories(${UFODECODE_LIBRARY_DIRS})
-
-add_executable(xilinx xilinx.c)
-target_link_libraries(xilinx pcilib rt)
-
-add_executable(lorenzo_ipedma_test lorenzo_ipedma_test.c)
-target_link_libraries(lorenzo_ipedma_test pcilib rt)
-
-add_executable(pio_test pio_test.c)
-target_link_libraries(pio_test pcilib rt)
-
-add_executable(compare_to_value compare_to_value.c)
-
-add_executable(heb_strip_bad_values heb_strip_bad_values.c)
-add_executable(check_counter check_counter.c)

+ 0 - 45
apps/check_counter.c

@@ -1,45 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-int main(int argc, char *argv[]) {
-    int block = 0;
-    uint32_t value = 0;
-    uint32_t buf[1024];
-    
-    if (argc < 2) {
-	printf("Usage:\n\t\t%s <file-to-check>\n", argv[0]);
-	exit(0);
-    }
-    
-    FILE *f = fopen(argv[1], "r");
-    if (!f) {
-	printf("Failed to open file %s\n", argv[1]);
-	exit(1);
-    }
-    
-    
-    while (!feof(f)) {
-	int i, n = fread(buf, 4, 1024, f);
-
-	if (block) i = 0;
-	else {
-	    i = 1;
-	    value = (buf[0]);
-	}
-
-	for (; i < n; i++) {
-	    if ((buf[i]) != ++value) {
-		printf("Pos %lx (Block %i, dword %i) expected %x, but got %x\n", block * 4096 + i * 4, block, i, value, (buf[i]));
-		exit(1);
-	    }
-	}
-	
-	if (n) block++;
-    }
-
-    fclose(f);
-    
-    printf("Checked %i blocks. All is fine\n", block);
-    return 0;
-}

+ 0 - 66
apps/compare_to_value.c

@@ -1,66 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-int main(int argc, char *argv[]) {
-    long i, j, size, num;
-    size_t count = 0, total = 0;
-    int offset = 0, toread = 1, toskip = 0;
-    uint32_t value;
-    uint32_t *buf;
-    
-    if ((argc != 4)&&(argc != 7)) {
-	printf("Usage: %s <file> <dwords> <value> [offset_dwords read_dwords skip_dwords] \n", argv[0]);
-	exit(0);
-    }
-    
-    FILE *f = fopen(argv[1], "r");
-    if (!f) {
-	printf("Can't open %s\n", argv[1]);
-	exit(1);
-    }
-    
-    size = atol(argv[2]);
-    if (size <= 0) {
-	printf("Can't parse size %s\n", argv[2]);
-	exit(1);
-    }
-    
-    if (sscanf(argv[3], "%x", &value) != 1) {
-	printf("Can't parse register %s\n", argv[3]);
-	exit(1);
-    }
-
-    buf = malloc(size * sizeof(uint32_t));
-    if (!buf) {
-	printf("Can't allocate %lu bytes of memory\n", size * sizeof(uint32_t));
-	exit(1);
-    }
-    
-    if (argc == 7) {
-	offset = atoi(argv[4]);
-	toread = atoi(argv[5]);
-	toskip = atoi(argv[6]);
-    }
-    
-
-    num = fread(buf, 4, size, f);
-    if (num != size) {
-	printf("Only %lu of %lu dwords in the file\n", num, size);
-	exit(1);
-    }
-    fclose(f);
-    
-    for (i = offset; i < size; i += toskip) {
-	for (j = 0; j < toread; j++, i++) {
-	    total++;
-	    if (buf[i] != value) {
-		count++;
-	    }
-	}
-    }
-    free(buf);
-    
-    printf("%lu of %lu is wrong\n", count, total);
-    return 0;
-}

+ 0 - 98
apps/heb_strip_bad_values.c

@@ -1,98 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-int main(int argc, char *argv[]) {
-    long i, num;
-    size_t count = 0, total = 0, size;
-    int offset = 3, toread = 1, toskip = 3;
-    uint32_t value;
-    uint32_t *buf;
-    uint32_t expected = 0;
-    uint32_t blocks = 0, status_good = 0;
-    
-    char fixed[4096];
-    struct stat st_buf;
-    
-    if ((argc != 2)&&(argc != 5)) {
-	printf("Usage: %s <file> [offset_dwords read_dwords skip_dwords] \n", argv[0]);
-	exit(0);
-    }
-    
-    FILE *f = fopen(argv[1], "r");
-    if (!f) {
-	printf("Can't open %s\n", argv[1]);
-	exit(1);
-    }
-
-    stat(argv[1], &st_buf);
-    size = st_buf.st_size / sizeof(uint32_t);
-
-
-    buf = malloc(size * sizeof(uint32_t));
-    if (!buf) {
-	printf("Can't allocate %lu bytes of memory\n", size * sizeof(uint32_t));
-	exit(1);
-    }
-    
-    if (argc == 5) {
-	offset = atoi(argv[2]);
-	toread = atoi(argv[3]);
-	toskip = atoi(argv[4]);
-    }
-    
-
-    num = fread(buf, 4, size, f);
-    if (num != size) {
-	printf("Failed to read %lu dwords, only %lu read\n", size, num);
-	exit(1);
-    }
-    fclose(f);
-    
-    sprintf(fixed, "%s.fixed", argv[1]);
-    f = fopen(fixed, "w");
-    if (!f) {
-	printf("Failed to open %s for output\n", fixed);
-	exit(1);
-    }
-    
-    expected = (buf[offset]>>24) + 2;
-    for (i = 1; i < size; i += (toread + toskip)) {
-	total++;
-	    
-	value = buf[i + offset] >> 24;
-//	printf("0x%lx: value (%lx) = expected (%lx)\n", i + offset, value, expected);
-	if (value == expected) {
-	    if (!status_good) {
-		status_good = 1;
-		blocks++;
-	    }
-	    fwrite(&buf[i], 4, toread + toskip, f);
-	    expected += 2;
-	    if (expected == 0xb8) 
-		expected = 0;
-	} else if ((!status_good)&&(value == 0)&&((i + toread + toskip)< size)) {
-	    value = buf[i + offset + toread + toskip] >> 24;
-	    if (value == 2) {
-		status_good = 1;
-		blocks++;
-		fwrite(&buf[i], 4, toread + toskip, f);
-		expected = 2;
-	    } else {
-		count++;
-	    }
-	} else {
-	    printf("0x%lx: value (%x) = expected (%x)\n", (i + offset)*sizeof(uint32_t), value, expected);
-	    status_good = 0;
-	    count++;
-	}
-    }
-    fclose(f);
-    free(buf);
-    
-    printf("%lu of %lu is wrong\n", count, total);
-    return 0;
-}

+ 0 - 749
apps/lorenzo_ipedma_test.c

@@ -1,749 +0,0 @@
-#define _POSIX_C_SOURCE 199309L
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <time.h>
-#include <sched.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <sched.h>
-#include <errno.h>
-
-#include "pcilib.h"
-#include "irq.h"
-#include "kmem.h"
-
-//#include <sys/ipc.h>
-//#include <sys/shm.h>
-
-
-#define DEVICE "/dev/fpga0"
-
-#define BAR PCILIB_BAR0
-#define USE_RING PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1)
-#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 2)
-//#define STATIC_REGION 0x80000000 //  to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters
-
-#define BUFFERS         128
-#define ITERATIONS      1000
-#define DESC_THRESHOLD  BUFFERS/8   // Lorenzo: after how many desc the FPGA must update the "written descriptor counter" in PC mem
-                                    // if set to 0, the update only happens when INT is received
-
-#define HUGE_PAGE       1           // number of pages per huge page
-#define TLP_SIZE        32          // TLP SIZE = 64 for 256B payload, 32 for 128B payload
-#define PAGE_SIZE       4096        // other values are not supported in the kernel
-
-//#define USE_64                    // Lorenzo: use 64bit addressing
-
-//#define DUAL_CORE                 // Lorenzo: DUAL Core
-
-//#define SHARED_MEMORY               // Lorenzo: Test for fast GUI
-
-#define CHECK_READY                 // Lorenzo: Check if PCI-Express is ready by reading 0x0
-#define CHECK_RESULTS               // Lorenzo: Check if data received is ok (only for counter!)
-//#define PRINT_RESULTS               // Lorenzo: Save the received data in "data.out"
-//#define EXIT_ON_EMPTY               // Lorenzo: Exit if an "empty_detected" signal is received
-
-//#define HEB                       // Lorenzo: Testing HEB
-//#define SWITCH_GENERATOR          // Lorenzo: Testing HEB -> Turn data gen on/off
-
-//#define TEST_DDR                    // Lorenzo: Testing DDR
-
-#define TIMEOUT         1000000
-
-
-
-/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help,
-   otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite 
-   much extra time */
-
-//#define USE_IRQ
-//#define REALTIME
-//#define ADD_DELAYS
-
-
-#define FPGA_CLOCK 250 // Lorenzo: in MHz !
-
-
-
-//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); }
-//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; }
-#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; }
-#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); }
-
-// **************************************************************************************
-// Progress BAR
-// Process has done x out of n rounds,
-// and we want a bar of width w and resolution r.
-   static inline void loadBar(int x, int n, int r, int w)
-   {
-    // Only update r times.
-    if ( x % (n/r +1) != 0 ) return;
-
-    // Calculuate the ratio of complete-to-incomplete.
-    float ratio = x/(float)n;
-    int   c     = ratio * w;
-
-    // Show the percentage complete.
-    printf("%3d%% [", (int)(ratio*100) );
-
-    // Show the load bar.
-        for (x=0; x<c; x++)
-           printf("=");
-
-       for (x=c; x<w; x++)
-           printf(" ");
-
-    // ANSI Control codes to go back to the
-    // previous line and clear it.
-       printf("]\n\033[F\033[J");
-   }
-// **************************************************************************************
-
-
-   static void fail(const char *msg, ...) {
-    va_list va;
-
-    va_start(va, msg);
-    vprintf(msg, va);
-    va_end(va);
-    printf("\n");
-
-    exit(-1);
-}
-
-void hpsleep(size_t ns) {
-    struct timespec wait, tv;
-
-    clock_gettime(CLOCK_REALTIME, &wait);
-
-    wait.tv_nsec += ns;
-    if (wait.tv_nsec > 999999999) {
-        wait.tv_sec += 1;
-        wait.tv_nsec = 1000000000 - wait.tv_nsec;
-    }
-
-    do {
-        clock_gettime(CLOCK_REALTIME, &tv);
-    } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec)));
-}
-
-
-// **************************************************************************************
-int main() {
-
-
-
-    int err;
-    long i, j, k;
-    int mem_diff;
-    pcilib_t *pci;
-    pcilib_kmem_handle_t *kdesc;
-    pcilib_kmem_handle_t *kbuf;
-    struct timeval start, end;
-    size_t run_time, size;
-    long long int size_mb;
-    void* volatile bar;
-    uintptr_t bus_addr[BUFFERS];
-    uintptr_t kdesc_bus;
-    volatile uint32_t *desc;
-    typedef volatile uint32_t *Tbuf;
-    Tbuf ptr[BUFFERS];
-    int switch_generator = 0;
-   
-    float performance, perf_counter; 
-    pcilib_bar_t bar_tmp = BAR; 
-    uintptr_t offset = 0;
-
-    unsigned int temp;
-    int iterations_completed, buffers_filled;
-
-
-//    int shmid;
-    
-
-    printf("\n\n**** **** **** KIT-DMA TEST **** **** ****\n\n");
-
-    size = ITERATIONS * BUFFERS * HUGE_PAGE * PAGE_SIZE;
-    size_mb = ITERATIONS * BUFFERS * HUGE_PAGE * 4 / 1024;
-    printf("Total size of memory buffer: \t %.3lf GBytes\n", (float)size_mb/1024 );
-    printf("Using %d Buffers with %d iterations\n\n", BUFFERS, ITERATIONS );
-
-#ifdef ADD_DELAYS
-    long rpt = 0, rpt2 = 0;
-    size_t best_time;
-    best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024);
-#endif /* ADD_DELAYS */
-
-
-    pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE/*|PCILIB_KMEM_FLAG_REUSE*/; // Lorenzo: if REUSE = 1, the re-allocation fails!
-    pcilib_kmem_flags_t free_flags = PCILIB_KMEM_FLAG_HARDWARE/*|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_REUSE*/;
-    pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE;
-
-    pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT);
-    if (!pci) fail("pcilib_open");
-
-    bar = pcilib_map_bar(pci, BAR);
-    if (!bar) {
-        pcilib_close(pci);
-        fail("map bar");
-    }
-
-    pcilib_detect_address(pci, &bar_tmp, &offset, 1);
-
-    pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0);
-    pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT);
-
-    pcilib_clean_kernel_memory(pci, USE, clean_flags);
-    pcilib_clean_kernel_memory(pci, USE_RING, clean_flags);
-
-    kdesc = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, USE_RING, flags);
-    kdesc_bus = pcilib_kmem_get_block_ba(pci, kdesc, 0);
-    desc = (uint32_t*)pcilib_kmem_get_block_ua(pci, kdesc, 0);
-    memset((void*)desc, 0, 5*sizeof(uint32_t));
-
-#ifdef REALTIME
-    pid_t pid;
-    struct sched_param sched = {0};
-
-    pid = getpid();
-    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
-    if (sched_setscheduler(pid, SCHED_FIFO, &sched))
-        printf("Warning: not able to get real-time priority\n");
-#endif /* REALTIME */
-
-    // ******************************************************************
-    // ****      MEM: check 4k boundary                             ***** 
-    // ******************************************************************
-
-    do  {
-        printf("* Allocating KMem, ");
-#ifdef STATIC_REGION
-        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, flags);
-#else
-        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, flags);
-#endif
-
-        if (!kbuf) {
-            printf("KMem allocation failed\n");
-            exit(0);
-        }
-
-        // Pointers for Virtualized Mem
-        for (j = 0; j < BUFFERS; j++) {
-            ptr[j] = (volatile uint32_t*)pcilib_kmem_get_block_ua(pci, kbuf, j);
-            memset((ptr[j]), 0, HUGE_PAGE * PAGE_SIZE);
-        }
-
-        err = 0;
-
-        // Check if HW addresses satisfy 4k boundary condition, if not -> free (!!) and reallocate memory
-        printf("4k boundary test: ");
-        for (j = 0; j < BUFFERS; j++) {
-            temp = (((unsigned int)pcilib_kmem_get_block_ba(pci, kbuf, j)) % 4096);
-            //printf("%u", temp);
-            if (temp  != 0) {
-                err = 1;
-            }
-        }
-        if (err == 1) {
-            pcilib_clean_kernel_memory(pci, USE, clean_flags);
-            pcilib_clean_kernel_memory(pci, USE_RING, clean_flags);
-            pcilib_free_kernel_memory(pci, kbuf,  free_flags);
-            printf("failed \xE2\x9C\x98\n");
-        }
-        else printf("passed \xE2\x9C\x93\n");
-
-    } while (err == 1);
-
-
-    // ******************************************************************
-    // ****      Allocate RAM buffer Memory                         ***** 
-    // ******************************************************************
-    
-    FILE * Output;
-    FILE * error_log;
-
-#ifdef CHECK_RESULTS
-
-    uint32_t *temp_data[ITERATIONS][BUFFERS];
-
-    for (j=0; j < ITERATIONS; j++) {
-        for (i=0; i < BUFFERS; i++) {
-            temp_data[j][i] = (uint32_t *)malloc(HUGE_PAGE*PAGE_SIZE);
-            if (temp_data[j][i] == 0) {
-                printf("******* Error: could not allocate memory! ********\n");
-                exit(0);
-            }
-            memset((void*)(temp_data[j][i]), 0, HUGE_PAGE * PAGE_SIZE);
-        }
-    }
-#endif
-
-#ifdef SHARED_MEMORY
-    // give your shared memory an id, anything will do
-    key_t key = 123456;
-    char *shared_memory;
-
-    // Setup shared memory, 11 is the size
-/*    if ((shmid = shmget(key, HUGE_PAGE*PAGE_SIZE, IPC_CREAT | 0666)) < 0)
-    {
-      printf("Error getting shared memory id");
-      exit(1);
-    }
-
-    // Attached shared memory
-    if ((shared_memory = shmat(shmid, NULL, 0)) == (char *) -1)
-    {
-      printf("Error attaching shared memory id");
-      exit(1);
-    }
-    printf("* Shared memory created... Id:\t %d\n", key);
-    //////////////// SHARED MEMORY TEST */
-#endif
-
-    Output = fopen ("data.out", "w");
-    fclose(Output);
-
-    error_log = fopen ("error_log.txt", "w");
-    fclose(error_log);
-   
-   // *************************************
-    Output = fopen("data.txt", "w");
-    fclose(Output);
-
-    // ******************************************************************
-    // ****      PCIe TEST                                          ***** 
-    // ******************************************************************
-
-    // Reset DMA
-    printf("* DMA: Reset...\n");
-    WR(0x00, 0x1);
-    usleep(100000);
-    WR(0x00, 0x0);
-    usleep(100000);
- 
-#ifdef CHECK_READY       
-    printf("* PCIe: Testing...");
-    RD(0x0, err);
-    if (err != 335746816) {
-        printf("\xE2\x9C\x98\n PCIe not ready!\n");
-        exit(0);
-    } else {
-        printf("\xE2\x9C\x93 \n");
-    }
-#endif
-    
-
-    // ******************************************************************
-    // ****      DMA CONFIGURATION                                  ***** 
-    // ******************************************************************
-
-    
-    printf("* DMA: Start Data Generator...\n");
-    WR(0x04, 0x10) // Start data generator
-
-    printf("* DMA: Send Data Fill Pattern 55aa55aa\n");
-    WR(0x14, 0xbeef);
-
-    printf("* DMA: Send Data Amount\n");
-#ifdef DUAL_CORE
-    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))/2);
-#else  
-    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE))));
-#endif   
-
-    printf("* DMA: Running mode: ");
-#ifdef USE_64   
-    if (TLP_SIZE == 64) 
-    {
-        WR(0x0C, 0x80040);
-        printf ("64bit - 256B Payload\n");
-    }
-    else if (TLP_SIZE == 32) 
-    {
-        WR(0x0C, 0x80020);
-        printf ("64bit - 128B Payload\n");
-    }
-#else  
-    if (TLP_SIZE == 64) 
-    {
-        WR(0x0C, 0x0040);
-        printf ("32bit - 256B Payload\n");
-    }
-    else if (TLP_SIZE == 32) 
-    {
-        WR(0x0C, 0x0020);
-        printf ("32bit - 128B Payload\n");
-    }
-#endif
-    
-    printf("* DMA: Reset Desc Memory...\n");
-    WR(0x5C, 0x00); // RST Desc Memory
-
-    //printf("Writing SW Read Descriptor\n");
-    WR(0x58, BUFFERS-1);
-    //WR(0x58, 0x01);
-
-    //printf("Writing the Descriptor Threshold\n");
-    WR(0x60, DESC_THRESHOLD);
-
-    //printf("Writing HW write Descriptor Address: %lx\n", kdesc_bus);
-    WR(0x54, kdesc_bus);
-    usleep(100000);
-
-    printf("* DMA: Writing Descriptors\n");
-    for (j = 0; j < BUFFERS; j++ ) {
-        bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j);
-        // LEAVE THIS DELAY???!?!?!?!
-        usleep(1000);
-        printf("Writing descriptor num. %ld: \t %08lx \r", j, bus_addr[j]);
-        WR(0x50, bus_addr[j]);
-    }
-
-    // ******************************************************************
-    // ****      HEB CONFIGURATION                                  ***** 
-    // ******************************************************************
-#ifdef HEB
-
-
-    printf("* DDR REGISTERS: AXI_BUF_SIZE \n");
-    WR(0x9130, 0x1000);
-
-    usleep(100000);
-
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x00000001);
-
-    usleep(100000);
-
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x00000004);
-
-    usleep(100000);
-
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x00000000);
-
-    usleep(100000);
-
-    printf("* HEB: Writing Total Orbit Num\n");
-    WR(0x9020, 0x2000);
-
-    printf("* HEB: Orbit Skip Num h9028\n");
-    WR(0x9028, 0x4);
-
-    //printf("* HEB: LVDS_DELAY h9080\n");
-    //WR(0x9080, 0x10101010);
-
-    //printf("* HEB: Delay ADCs \n");
-    //WR(0x9088, 0x001);
-    //WR(0x9090, 0x001);
-    //WR(0x9094, 0x001);
-    //WR(0x9098, 0x001);
-
-    //printf("* HEB: Delay TH \n");
-    //WR(0x90a0, 0x005);
-
-    //printf("* HEB: Delay_FPGA_reg \n");
-    //WR(0x90a8, 0x006);
-
-    //printf("* HEB: Control \n");
-    //WR(0x9040, 0x40000000);
-
-    //usleep(1000000);
- 
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x40000bf0);
-
-    usleep(100000);
-
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x400003f0);
-
-    usleep(100000);
-
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x480007F0);
-
-    usleep(100000);
-
-    printf("* HEB: Control \n");
-    WR(0x9040, 0x48000FF0);
-
-
-#endif
-
-    // ******************************************************************
-    // ****      TEST DDR conf                                      ***** 
-    // ******************************************************************
-#ifdef TEST_DDR
-
-
-    printf("* DDR: AXI_BUF_SIZE_ADDR: 4k\n");
-    WR(0x9010, 0x04000);
-
-    printf("* DDR: Control \n");
-    WR(0x9000, 0x000000F);
-
-    usleep(100000);
-    WR(0x9000, 0x00000008);
-    usleep(100000);
-    WR(0x9000, 0x08000008);
-
-    usleep(50000);
-
-    printf("* DDR: Control \n");
-    WR(0x9000, 0x08000208);
-
-
-#endif
-
-    // ******************************************************************
-    // ****     START DMA                                           *****
-    // ******************************************************************
-
-    //printf ("\n ---- Press ENTER to start DMA ---- \n");
-    //getchar();
-
-    printf("* DMA: Start \n");
-    WR(0x04, 0x1f);
-    gettimeofday(&start, NULL);
-
-    // ******************************************************************
-    // ****     Handshaking DMA                                     *****
-    // ******************************************************************
-
-    uint32_t curptr = 0, hwptr;
-    uint32_t curbuf = 0;
-    int empty = 0;
-    i = 0;
-
-
-    while (i < ITERATIONS) {
-        j = 0;
-        // printf("\ndesc0: %lx", htonl(desc[0])); 
-        // printf("\ndesc1: %lx", htonl(desc[1])); 
-        // printf("\ndesc2: %lx", htonl(desc[2])); 
-        // printf("\ndesc3: %lx", htonl(desc[3])); 
-        // printf("\ndesc4: %lx", htonl(desc[4]));
-        // printf("\ndesc5: %lx", htonl(desc[5]));
-        //printf("Iteration: %li of %li \r", i+1, ITERATIONS); 
-        //loadBar(i+1, ITERATIONS, ITERATIONS, 30);
-        // printf("\nhwptr: %zu", hwptr);  
-        // printf("\ncurptr: %zu", curptr); 
-
-        do {
-#ifdef USE_64   
-                hwptr = htonl(desc[3]);
-#else // 32-bit
-                hwptr = htonl(desc[4]);
-#endif
-        j++;    
-        //printf("\rcurptr: %lx \t \t hwptr: %lx", curptr, hwptr);
-        } while (hwptr == curptr);
-
-        do {    
-            pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, curbuf);
-#ifdef CHECK_RESULTS   
-            memcpy(temp_data[i][curbuf], ptr[curbuf], 4096);
-#endif
-#ifdef SHARED_MEMORY
-            memcpy(shared_memory, ptr[curbuf], 4096); 
-#endif            
-            //printf("\ncurbuf: %08x", curbuf); 
-            //printf("\nbus_addr[curbuf]\n: %08x",bus_addr[curbuf]);
-            // for (k = 0; k < 63; k++){
-            // if (k%16 == 0) printf("\n# %d # :", k);
-            // printf(" %08x", ptr[curbuf][k]);
-            // }
-            //pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_TODEVICE, curbuf);
-            curbuf++;
-            if (curbuf == BUFFERS) {
-                i++;
-                curbuf = 0;
-#ifdef SWITCH_GENERATOR                 
-                if (switch_generator == 1) {
-                    switch_generator = 0;
-                    WR(0x9040, 0x100007F0);
-                } else {
-                    WR(0x9040, 0x180007F0);
-                    switch_generator = 1;
-                }
-#endif
-                if (i >= ITERATIONS) break;
-                //if (i >= (ITERATIONS - 4) ) WR(0x04, 0x0f); 
-            }
-        } while (bus_addr[curbuf] != hwptr);
-
-#ifdef EXIT_ON_EMPTY
-#ifdef USE_64                 
-        if (desc[1] != 0) 
-#else // 32bit  
-        if (desc[2] != 0)  
-#endif                                 
-        {
-            if (bus_addr[curbuf] == hwptr) {
-                empty = 1;
-                break;
-            }
-        }
-#endif  
-
-        WR(0x58, curbuf + 1); 
-        //printf("WR %d\n", curbuf + 1); 
-        //printf("%u (%lu)\n", curbuf, j);
-        curptr = hwptr;
-
-    }
-    
-
-
-    // ******************************************************************
-    // **** Read performance and stop DMA                         *******
-    // ******************************************************************
-
-    gettimeofday(&end, NULL);
-    WR(0x04, 0x00);
-    WR(0x01, 0x00);
-    RD(0x28, perf_counter);
-
-
-
-    iterations_completed   = i;
-    buffers_filled      = curbuf;
-    if (empty) printf("* DMA: Empty FIFO! Last iteration: %li of %li\n", i+1, ITERATIONS);
-    printf ("* DMA: Stop\n\n");
-
-#ifdef CHECK_RESULTS
-    printf ("First value:\t %08x\n", temp_data[0][0][0]);
-    printf ("Last value:\t %08x\n\n", temp_data[ITERATIONS-1][BUFFERS-1][(PAGE_SIZE/4)-4]);
-#endif
-    
-    // ******************************************************************
-    // **** Performance                                           *******
-    // ******************************************************************
-    printf("Iterations done: %d\n", iterations_completed);
-    printf("Buffers filled on last iteration: %d\n", buffers_filled);
-
-
-    run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
-    size = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * PAGE_SIZE);
-    size_mb = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * 4 / 1024);
-    printf("Performance: transfered %zu Mbytes in %zu us using %d buffers\n", (size_mb), run_time, BUFFERS);
-    //printf("Buffers: \t %d \n", BUFFERS);
-    //printf("Buf_Size: \t %d \n", PAGE_SIZE);
-    //printf("Perf_counter: \t %f \n", perf_counter);
-    performance = ((size_mb * FPGA_CLOCK * 1000000)/(perf_counter*256));
-    printf("DMA perf counter:\t%d\n", (int)perf_counter); 
-    printf("DMA side:\t\t%.3lf MB/s\n", performance);  
-    printf("PC side:\t\t%.3lf MB/s\n\n", 1000000. * size_mb / run_time );
-
-    // ******************************************************************
-    // **** Read Data                                             *******
-    // ******************************************************************
-
-
-    #ifdef PRINT_RESULTS
-    printf("Writing Data to HDD... \n");
-    for (i=0; i < iterations_completed; i++) {
-        for (j=0; j < BUFFERS; j++)
-        {
-            Output = fopen("data.out", "a");
-            fwrite(temp_data[i][j], 4096, 1, Output);
-            fclose(Output);
-        }   
-        loadBar(i+1, ITERATIONS, ITERATIONS, 30);
-    }
-    // Save last partially filled iteration
-    for (j=0; j < buffers_filled; j++)
-    {
-        Output = fopen("data.out", "a");
-        fwrite(temp_data[iterations_completed][j], 4096, 1, Output);
-        fclose(Output);
-    }   
-    printf("Data saved in data.out. \n");
-    #endif
-
-   #ifdef CHECK_RESULTS
-    err = 0;
-    error_log = fopen ("error_log.txt", "a");
-    printf("\nChecking data ...\n");
-    for (i=0; i < iterations_completed; i++) {
-        for (j = 0; j < BUFFERS; j++) {
-            for (k = 0; k < 1024 ; k++) 
-            {
-                mem_diff = ((uint32_t)temp_data[i][j][k] - (uint32_t)temp_data[i][j][k+1]);
-                //if ((mem_diff == 1) || (mem_diff == (-7)) || (k == 1023) ) 
-                if ((mem_diff == -1) || (k == 1023) ) 
-                    {;}
-                else {
-                    fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j][k], temp_data[i][j][k+1], mem_diff);
-                    err++;
-                }
-            }
-            if (j != BUFFERS-1) {
-            // Check first and Last
-                mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]);
-                if (mem_diff == (1)) 
-                    {;}
-                else {
-                    fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j+1][0], temp_data[i][j][1023], mem_diff);
-                    err++;
-                }
-            }
-
-        }
-        loadBar(i+1, ITERATIONS, ITERATIONS, 30);
-    }
-    for (j = 0; j < buffers_filled; j++) {
-        for (k = 0; k < 1024 ; k++) 
-        {
-            mem_diff = ((uint32_t)temp_data[iterations_completed][j][k] - (uint32_t)temp_data[iterations_completed][j][k+1]);
-                if ((mem_diff == -1) || (k == 1023) ) 
-                {;}
-            else {
-                fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j][k], temp_data[iterations_completed][j][k+1], mem_diff);
-                err++;
-            }
-        }
-        if (j != buffers_filled-1) {
-        // Check first and Last
-            mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]);
-            if (mem_diff == (1)) 
-                {;}
-            else {
-                fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j+1][0], temp_data[iterations_completed][j][1023], mem_diff);
-                err++;
-            }
-        }
-    }
-    if (err != 0) printf("\rChecking data: \xE2\x9C\x98 %d errors found  \n See \"error_log.txt\" for details \n\n", err);
-    else printf("\rChecking data: \xE2\x9C\x93 no errors found  \n\n");
-    fclose(error_log);
-    #endif
-
-
-    // *********** Free Memory
-#ifdef CHECK_RESULTS
-    for (i=0; i < ITERATIONS; i++) {
-        for (j=0; j < BUFFERS; j++)
-        {
-            free(temp_data[i][j]);
-        }
-    }
-#endif CHECK_RESULTS
-
-    pcilib_free_kernel_memory(pci, kbuf,  free_flags);
-    pcilib_free_kernel_memory(pci, kdesc,  free_flags);
-    pcilib_disable_irq(pci, 0);
-    pcilib_unmap_bar(pci, BAR, bar);
-    pcilib_close(pci);
-
-//    shmdt(shmid);
-//    shmctl(shmid, IPC_RMID, NULL);
-
-}

+ 0 - 96
apps/pio_test.c

@@ -1,96 +0,0 @@
-#define _BSD_SOURCE
-#define _POSIX_C_SOURCE 199309L
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <time.h>
-#include <sched.h>
-#include <sys/time.h>
-
-#include "pcilib.h"
-#include "irq.h"
-#include "kmem.h"
-
-#define DEVICE "/dev/fpga0"
-//#define REALTIME
-
-#define BAR PCILIB_BAR0
-#define BITS 32
-#define MASK ((1ll << BITS) - 1)
-
-
-#define WR(addr, value) { *(uint32_t*)(bar + addr) = value; }
-#define RD(addr, value) { value = *(uint32_t*)(bar + addr); }
-
-unsigned long long bits[BITS];
-
-int main(int argc, char *argv[]) {
-    uint32_t i, j;
-    pcilib_t *pci;
-    uint32_t reg, value, diff, errors;
-    void* volatile bar;
-    
-    unsigned long long attempts = 0, failures = 0;
-
-    if (argc < 2) {
-	printf("Usage: %s <register>\n", argv[0]);
-	exit(0);
-    }
-    
-    if (sscanf(argv[1], "%x", &reg) != 1) {
-	printf("Can't parse register %s\n", argv[1]);
-	exit(1);
-    }
-    
-#ifdef REALTIME
-    pid_t pid;
-    struct sched_param sched = {0};
-
-    pid = getpid();
-    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
-    if (sched_setscheduler(pid, SCHED_FIFO, &sched))
-	printf("Warning: not able to get real-time priority\n");
-#endif /* REALTIME */
-
-    pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT);
-    if (!pci) {
-	printf("pcilib_open\n");
-	exit(1);
-    }
-
-    bar = pcilib_map_bar(pci, BAR);
-    if (!bar) {
-	pcilib_close(pci);
-	printf("map bar\n");
-	exit(1);
-    }
-    
-    for (i = 0; 1; i++) {
-	WR(reg, (i%MASK));
-	RD(reg, value);
-	
-	attempts++;
-	if (value != (i%MASK)) {
-	    failures++;
-
-	    diff = value ^ (i%MASK);
-	    for (errors = 0, j = 0; j < BITS; j++)
-		if (diff&(1<<j)) errors++;
-	    bits[errors]++;
-		
-	    //printf("written: %x, read: %x\n", i, value);
-	}
-
-	if ((i % 1048576 ) == 0) {
-	    printf("Attempts %llu, failures %llu (", attempts, failures);
-	    for (j = 1; j < BITS; j++)
-		printf("%llu ", bits[j]);
-	    printf(")\n");
-	}
-
-    }
-
-    pcilib_unmap_bar(pci, BAR, bar);
-    pcilib_close(pci);
-}

+ 0 - 225
apps/xilinx.c

@@ -1,225 +0,0 @@
-#define _BSD_SOURCE
-#define _POSIX_C_SOURCE 199309L
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <time.h>
-#include <sched.h>
-#include <sys/time.h>
-
-#include "pcilib.h"
-#include "irq.h"
-#include "kmem.h"
-
-#define DEVICE "/dev/fpga0"
-#define BAR PCILIB_BAR0
-#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1)
-#define STATIC_REGION 0x80000000 //  to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters
-#define BUFFERS 1
-#define ITERATIONS 100
-#define TLP_SIZE 64
-#define HUGE_PAGE 4096	// number of pages per huge page
-#define PAGE_SIZE 4096	// other values are not supported in the kernel
-#define TIMEOUT 100000
-
-/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help,
-otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite 
-much extra time */
-#define USE_IRQ
-//#define CHECK_READY
-//#define REALTIME
-//#define ADD_DELAYS
-#define CHECK_RESULT
-
-//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); }
-//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; }
-#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; }
-#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); }
-
-static void fail(const char *msg, ...) {
-    va_list va;
-    
-    va_start(va, msg);
-    vprintf(msg, va);
-    va_end(va);
-    printf("\n");
-
-    exit(-1);
-}
-
-void hpsleep(size_t ns) {
-    struct timespec wait, tv;
-
-    clock_gettime(CLOCK_REALTIME, &wait);
-
-    wait.tv_nsec += ns;
-    if (wait.tv_nsec > 999999999) {
-	wait.tv_sec += 1;
-	wait.tv_nsec = 1000000000 - wait.tv_nsec;
-    }
-
-    do {
-	clock_gettime(CLOCK_REALTIME, &tv);
-    } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec)));
-}
-
-
-int main() {
-    int err;
-    long i, j;
-    pcilib_t *pci;
-    pcilib_kmem_handle_t *kbuf;
-    uint32_t status;
-    struct timeval start, end;
-    size_t size, run_time;
-    void* volatile bar;
-    uintptr_t bus_addr[BUFFERS];
-
-    pcilib_bar_t bar_tmp = BAR; 
-    uintptr_t offset = 0;
-
-    pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE;
-
-#ifdef ADD_DELAYS
-    long rpt = 0, rpt2 = 0;
-    size_t best_time;
-    best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024);
-#endif /* ADD_DELAYS */
-
-#ifdef REALTIME
-    pid_t pid;
-    struct sched_param sched = {0};
-
-    pid = getpid();
-    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
-    if (sched_setscheduler(pid, SCHED_FIFO, &sched))
-	printf("Warning: not able to get real-time priority\n");
-#endif /* REALTIME */
-
-    pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT);
-    if (!pci) fail("pcilib_open");
-
-    bar = pcilib_map_bar(pci, BAR);
-    if (!bar) {
-	pcilib_close(pci);
-	fail("map bar");
-    }
-
-    pcilib_detect_address(pci, &bar_tmp, &offset, 1);
-
-	// Reset
-    WR(0x00, 1)
-    usleep(1000);
-    WR(0x00, 0)
-
-    pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0);
-    pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT);
-
-    pcilib_clean_kernel_memory(pci, USE, clean_flags);
-
-#ifdef STATIC_REGION
-    kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, 0);
-#else /* STATIC_REGION */
-    kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, 0);
-#endif /* STATIC_REGION */
-
-    if (!kbuf) {
-	printf("KMem allocation failed\n");
-	exit(0);
-    }
-
-
-#ifdef CHECK_RESULT    
-    volatile uint32_t *ptr0 = pcilib_kmem_get_block_ua(pci, kbuf, 0);
-
-    memset((void*)ptr0, 0, (HUGE_PAGE * PAGE_SIZE));
-    
-    for (i = 0; i < (HUGE_PAGE * PAGE_SIZE / 4); i++) {
-	if (ptr0[i] != 0) break;
-    }
-    if (i < (HUGE_PAGE * PAGE_SIZE / 4)) {
-	printf("Initialization error in position %lu, value = %x\n", i * 4, ptr0[i]);
-    }
-#endif /* CHECK_RESULT */
-
-    WR(0x04, 0)
-    WR(0x0C, TLP_SIZE)
-    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE))))
-    WR(0x14, 0x13131313)
-
-    for (j = 0; j < BUFFERS; j++ ) {
-        bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j);
-    }
-
-    gettimeofday(&start, NULL);
-
-    for (i = 0; i < ITERATIONS; i++) {
-	for (j = 0; j < BUFFERS; j++ ) {
-//	    uintptr_t ba = pcilib_kmem_get_block_ba(pci, kbuf, j);
-//	    WR(0x08, ba)
-	    WR(0x08, bus_addr[j]);
-	    WR(0x04, 0x01)
-
-#ifdef USE_IRQ
-	    err = pcilib_wait_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT, TIMEOUT, NULL);
-	    if (err) printf("Timeout waiting for IRQ, err: %i\n", err);
-
-	    RD(0x04, status);
-	    if ((status&0xFFFF) != 0x101) printf("Invalid status %x\n", status);
-//	    WR(0x04, 0x00);
-#else /* USE_IRQ */
-# ifdef ADD_DELAYS
-//	    hpsleep(best_time);
-	    do {
-		rpt++;
-		RD(0x04, status);
-	    } while (status != 0x101);
-# else /* ADD_DELAYS */
-	    do {
-		RD(0x04, status);
-	    } while (status != 0x101);
-# endif /* ADD_DELAYS */
-#endif /* USE_IRQ */
-
-	    WR(0x00, 1)
-#ifdef CHECK_READY
-	    do {
-		rpt2++;
-		RD(0x04, status);
-	    } while (status != 0);
-#endif /* CHECK_READY */
-	    WR(0x00, 0)
-	}
-    }
-    gettimeofday(&end, NULL);
-
-#ifdef CHECK_RESULT    
-    pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, 0);
-
-    for (i = 0; i < (HUGE_PAGE * PAGE_SIZE / 4); i++) {
-//	printf("%lx ", ptr0[i]);
-	if (ptr0[i] != 0x13131313) break;
-    }
-    if (i < (HUGE_PAGE * PAGE_SIZE / 4)) {
-	printf("Error in position %lu, value = %x\n", i * 4, ptr0[i]);
-    }
-#endif /* CHECK_RESULT */
-
-    pcilib_free_kernel_memory(pci, kbuf,  0);
-    pcilib_disable_irq(pci, 0);
-    pcilib_unmap_bar(pci, BAR, bar);
-    pcilib_close(pci);
-
-    run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
-    size = (long long int)ITERATIONS * BUFFERS * HUGE_PAGE * PAGE_SIZE;
-
-    printf("%.3lf GB/s: transfered %zu bytes in %zu us using %u buffers\n", 1000000. * size / run_time / 1024 / 1024 / 1024, size, run_time, BUFFERS);
-
-# ifdef ADD_DELAYS
-    printf("Repeats: %lf, %lf\n",1. * rpt / (ITERATIONS * BUFFERS), 1. * rpt2 / (ITERATIONS * BUFFERS));
-#endif /* USE_IRQ */	    
-
-
-}

+ 32 - 43
ipecamera/ipecamera.c → base.c

@@ -12,11 +12,11 @@
 
 #include <ufodecode.h>
 
-#include "../tools.h"
-#include "../error.h"
-#include "../event.h"
+#include <pcilib.h>
+#include <pcilib/tools.h>
+#include <pcilib/error.h>
+#include <pcilib/event.h>
 
-#include "pcilib.h"
 #include "private.h"
 #include "model.h"
 #include "reader.h"
@@ -24,8 +24,6 @@
 #include "data.h"
 
 
-#include "dma/nwl.h"
-
 #define FIND_REG(var, bank, name)  \
         ctx->var = pcilib_find_register(pcilib, bank, name); \
 	if (ctx->var ==  PCILIB_REGISTER_INVALID) { \
@@ -38,7 +36,7 @@
     if (!err) { \
 	err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
 	if (err) { \
-	    pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
+	    pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
 	} \
     }
 
@@ -46,7 +44,7 @@
     if (!err) { \
 	err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
 	if (err) { \
-	    pcilib_error("Error writting %s register", ipecamera_registers[ctx->reg].name); \
+	    pcilib_error("Error writting %s register", model_info->registers[ctx->reg].name); \
 	} \
     }
 
@@ -54,16 +52,16 @@
     if (!err) { \
 	err = pcilib_read_register_by_id(pcilib, ctx->reg, &value); \
 	if (err) { \
-	    pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
+	    pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
 	} \
 	if (value != check) { \
-	    pcilib_error("Unexpected value (0x%lx) of register %s", value, ipecamera_registers[ctx->reg].name); \
+	    pcilib_error("Unexpected value (0x%lx) of register %s", value, model_info->registers[ctx->reg].name); \
 	    err = PCILIB_ERROR_INVALID_DATA; \
 	} \
     }
 
-#define IPECAMERA_GET_EXPECTED_STATUS(ctx) ((ctx->firmware == 4)?IPECAMERA_EXPECTED_STATUS_4:IPECAMERA_EXPECTED_STATUS)
-#define CHECK_STATUS_REG() CHECK_REG(status_reg, IPECAMERA_GET_EXPECTED_STATUS(ctx))
+#define CHECK_STATUS()
+	    //CHECK_REG(status_reg, IPECAMERA_GET_EXPECTED_STATUS(ctx))
 
 #define CHECK_VALUE(value, val) \
     if ((!err)&&(value != val)) { \
@@ -81,6 +79,8 @@
 pcilib_context_t *ipecamera_init(pcilib_t *pcilib) {
     int err = 0; 
     
+    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
+
     ipecamera_t *ctx = malloc(sizeof(ipecamera_t));
 
     if (ctx) {
@@ -115,13 +115,12 @@ pcilib_context_t *ipecamera_init(pcilib_t *pcilib) {
 
 	GET_REG(firmware_version_reg, value);
 	switch (value) {
-	 case 4:
 	 case 5:
 	    ctx->firmware = value;
 	    break;
 	 default:
-//    	    pcilib_error("Unsupported version of firmware (%lu)", value);
-	    ctx->firmware = 0;
+	    ctx->firmware = 5;
+    	    pcilib_warning("Unsupported version of firmware (%lu)", value);
 	}
 
 #ifdef IPECAMERA_BUG_POSTPONED_READ
@@ -153,26 +152,19 @@ void ipecamera_free(pcilib_context_t *vctx) {
 }
 
 pcilib_dma_context_t *ipecamera_init_dma(pcilib_context_t *vctx) {
-#ifdef IPECAMERA_DMA_R3
     ipecamera_t *ctx = (ipecamera_t*)vctx;
-#endif
     
-    pcilib_model_description_t *model_info = pcilib_get_model_description(vctx->pcilib);
-    if ((!model_info->dma_api)||(!model_info->dma_api->init)) {
+    const pcilib_model_description_t *model_info = pcilib_get_model_description(vctx->pcilib);
+    if ((!model_info->dma)||(!model_info->dma->api)||(!model_info->dma->api->init)) {
 	pcilib_error("The DMA engine is not configured in model");
 	return NULL;
     }
 
-
-#ifdef IPECAMERA_DMA_R3
     if (ctx->firmware) {
-	return model_info->dma_api->init(vctx->pcilib, PCILIB_NWL_MODIFICATION_IPECAMERA, NULL);
+	return model_info->dma->api->init(vctx->pcilib, NULL, NULL);
     } else {
-	return model_info->dma_api->init(vctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
+	return model_info->dma->api->init(vctx->pcilib, "pci", NULL);
     }
-#else
-    return model_info->dma_api->init(vctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
-#endif
 }
 
 
@@ -258,17 +250,19 @@ int ipecamera_reset(pcilib_context_t *vctx) {
 
     usleep(10000);
 
-    err = pcilib_read_register_by_id(pcilib, status, &value);
+
+    CHECK_STATUS();
     if (err) {
-	pcilib_error("Error reading status register");
-	return err;
-    }
+	err = pcilib_read_register_by_id(pcilib, status, &value);
+
+	if (err) pcilib_error("Error reading status register");
+	else pcilib_error("Camera returns unexpected status (status: %lx)", value);
 
-    if (value != IPECAMERA_GET_EXPECTED_STATUS(ctx)) {
-	pcilib_error("Unexpected value (%lx) of status register, expected %lx", value, IPECAMERA_GET_EXPECTED_STATUS(ctx));
 	return PCILIB_ERROR_VERIFY;
     }
 
+    // DS: Get rid of pending DMA data
+
     return 0;    
 }
 
@@ -276,10 +270,13 @@ int ipecamera_reset(pcilib_context_t *vctx) {
 int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
     int i;
     int err = 0;
+
     ipecamera_t *ctx = (ipecamera_t*)vctx;
     pcilib_t *pcilib = vctx->pcilib;
     pcilib_register_value_t value;
     
+    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
+
     pthread_attr_t attr;
     struct sched_param sched;
     
@@ -298,16 +295,6 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev
 	return PCILIB_ERROR_INVALID_REQUEST;
     }
 
-	// Allow readout and clean the FRAME_REQUEST mode if set for some reason
-    usleep(IPECAMERA_SLEEP_TIME);
-    if (value&0x1000) ctx->fr_mode = 1;
-    else {
-	ctx->fr_mode = 0;
-	
-//	CHECK_STATUS_REG();
-//	if (err) return err;
-    }
-
     ctx->event_id = 0;
     ctx->preproc_id = 0;
     ctx->reported_id = 0;
@@ -642,6 +629,8 @@ int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigg
     ipecamera_t *ctx = (ipecamera_t*)vctx;
     pcilib_t *pcilib = vctx->pcilib;
 
+    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
+
     if (!ctx) {
 	pcilib_error("IPECamera imaging is not initialized");
 	return PCILIB_ERROR_NOTINITIALIZED;
@@ -685,7 +674,7 @@ int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigg
     GET_REG(control_reg, value); 
     SET_REG(control_reg, value|IPECAMERA_FRAME_REQUEST);
     usleep(IPECAMERA_WAIT_FRAME_RCVD_TIME);
-    //CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS);
+    //DS: CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS);
     SET_REG(control_reg, value);
 
 	// We need to compute it differently, on top of that add exposure time and the time FPGA takes to read frame from CMOSIS

+ 4 - 5
ipecamera/public.h → base.h

@@ -1,11 +1,10 @@
-#ifndef _IPECAMERA_PUBLIC_H
-#define _IPECAMERA_PUBLIC_H
+#ifndef _IPECAMERA_BASE_H
+#define _IPECAMERA_BASE_H
 
 #include <stdio.h>
 
+#include <pcilib.h>
 #include "ipecamera.h"
-#include "../pcilib.h"
-
 
 pcilib_context_t *ipecamera_init(pcilib_t *pcilib);
 void ipecamera_free(pcilib_context_t *ctx);
@@ -22,4 +21,4 @@ int ipecamera_next_event(pcilib_context_t *vctx, pcilib_timeout_t timeout, pcili
 int ipecamera_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **buf);
 int ipecamera_return(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data);
 
-#endif /* _IPECAMERA_PUBLIC_H */
+#endif /* _IPECAMERA_BASE_H */

+ 0 - 3101
cli.c

@@ -1,3101 +0,0 @@
-#define _POSIX_C_SOURCE 200112L
-#define _BSD_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <alloca.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <getopt.h>
-
-#include <fastwriter.h>
-
-#include "pcitool/sysinfo.h"
-#include "pcitool/formaters.h"
-
-//#include "pci.h"
-#include "tools.h"
-#include "kernel.h"
-#include "error.h"
-
-/* defines */
-#define MAX_KBUF 14
-//#define BIGBUFSIZE (512*1024*1024)
-#define BIGBUFSIZE (1024*1024)
-
-
-#define DEFAULT_FPGA_DEVICE "/dev/fpga0"
-
-#define LINE_WIDTH 80
-#define SEPARATOR_WIDTH 2
-#define BLOCK_SEPARATOR_WIDTH 2
-#define BLOCK_SIZE 8
-#define BENCHMARK_ITERATIONS 128
-#define STATUS_MESSAGE_INTERVAL	5	/* seconds */
-
-
-#define isnumber pcilib_isnumber
-#define isxnumber pcilib_isxnumber
-#define isnumber_n pcilib_isnumber_n
-#define isxnumber_n pcilib_isxnumber_n
-
-typedef uint8_t access_t;
-
-typedef enum {
-    GRAB_MODE_GRAB = 1,
-    GRAB_MODE_TRIGGER = 2
-} GRAB_MODE;
-
-typedef enum {
-    MODE_INVALID,
-    MODE_INFO,
-    MODE_LIST,
-    MODE_BENCHMARK,
-    MODE_READ,
-    MODE_READ_REGISTER,
-    MODE_WRITE,
-    MODE_WRITE_REGISTER,
-    MODE_RESET,
-    MODE_GRAB,
-    MODE_START_DMA,
-    MODE_STOP_DMA,
-    MODE_LIST_DMA,
-    MODE_LIST_DMA_BUFFERS,
-    MODE_READ_DMA_BUFFER,
-    MODE_ENABLE_IRQ,
-    MODE_DISABLE_IRQ,
-    MODE_ACK_IRQ,
-    MODE_WAIT_IRQ,
-    MODE_ALLOC_KMEM,
-    MODE_LIST_KMEM,
-    MODE_READ_KMEM,
-    MODE_FREE_KMEM
-} MODE;
-
-typedef enum {
-    ACCESS_BAR,
-    ACCESS_DMA,
-    ACCESS_FIFO, 
-    ACCESS_CONFIG
-} ACCESS_MODE;
-
-typedef enum {
-    FLAG_MULTIPACKET = 1,
-    FLAG_WAIT = 2
-} FLAGS;
-
-
-typedef enum {
-    FORMAT_DEFAULT = 0,
-    FORMAT_RAW,
-    FORMAT_HEADER,
-    FORMAT_RINGFS
-} FORMAT;
-
-typedef enum {
-    PARTITION_UNKNOWN,
-    PARTITION_RAW,
-    PARTITION_EXT4,
-    PARTITION_NULL
-} PARTITION;
-
-typedef enum {
-    OPT_DEVICE = 'd',
-    OPT_MODEL = 'm',
-    OPT_BAR = 'b',
-    OPT_ACCESS = 'a',
-    OPT_ENDIANESS = 'e',
-    OPT_SIZE = 's',
-    OPT_OUTPUT = 'o',
-    OPT_TIMEOUT = 't',
-    OPT_INFO = 'i',
-    OPT_LIST = 'l',
-    OPT_READ = 'r',
-    OPT_WRITE = 'w',
-    OPT_GRAB = 'g',
-    OPT_QUIETE = 'q',
-    OPT_HELP = 'h',
-    OPT_RESET = 128,
-    OPT_BENCHMARK,
-    OPT_TRIGGER,
-    OPT_DATA_TYPE,
-    OPT_EVENT,
-    OPT_TRIGGER_RATE,
-    OPT_TRIGGER_TIME,
-    OPT_RUN_TIME,
-    OPT_FORMAT,
-    OPT_BUFFER,
-    OPT_THREADS,
-    OPT_LIST_DMA,
-    OPT_LIST_DMA_BUFFERS,
-    OPT_READ_DMA_BUFFER,
-    OPT_START_DMA,
-    OPT_STOP_DMA,
-    OPT_ENABLE_IRQ,
-    OPT_DISABLE_IRQ,
-    OPT_ACK_IRQ,
-    OPT_WAIT_IRQ,
-    OPT_ITERATIONS,
-    OPT_ALLOC_KMEM,
-    OPT_LIST_KMEM,
-    OPT_FREE_KMEM,
-    OPT_READ_KMEM,
-    OPT_BLOCK_SIZE,
-    OPT_ALIGNMENT,
-    OPT_TYPE,
-    OPT_FORCE,
-    OPT_VERIFY,
-    OPT_WAIT,
-    OPT_MULTIPACKET,
-    OPT_VERBOSE
-} OPTIONS;
-
-static struct option long_options[] = {
-    {"device",			required_argument, 0, OPT_DEVICE },
-    {"model",			required_argument, 0, OPT_MODEL },
-    {"bar",			required_argument, 0, OPT_BAR },
-    {"access",			required_argument, 0, OPT_ACCESS },
-    {"endianess",		required_argument, 0, OPT_ENDIANESS },
-    {"size",			required_argument, 0, OPT_SIZE },
-    {"output",			required_argument, 0, OPT_OUTPUT },
-    {"timeout",			required_argument, 0, OPT_TIMEOUT },
-    {"iterations",		required_argument, 0, OPT_ITERATIONS },
-    {"info",			no_argument, 0, OPT_INFO },
-    {"list",			no_argument, 0, OPT_LIST },
-    {"reset",			no_argument, 0, OPT_RESET },
-    {"benchmark",		optional_argument, 0, OPT_BENCHMARK },
-    {"read",			optional_argument, 0, OPT_READ },
-    {"write",			optional_argument, 0, OPT_WRITE },
-    {"grab",			optional_argument, 0, OPT_GRAB },
-    {"trigger",			optional_argument, 0, OPT_TRIGGER },
-    {"data",			required_argument, 0, OPT_DATA_TYPE },
-    {"event",			required_argument, 0, OPT_EVENT },
-    {"run-time",		required_argument, 0, OPT_RUN_TIME },
-    {"trigger-rate",		required_argument, 0, OPT_TRIGGER_RATE },
-    {"trigger-time",		required_argument, 0, OPT_TRIGGER_TIME },
-    {"format",			required_argument, 0, OPT_FORMAT },
-    {"buffer",			optional_argument, 0, OPT_BUFFER },
-    {"threads",			optional_argument, 0, OPT_THREADS },
-    {"start-dma",		required_argument, 0, OPT_START_DMA },
-    {"stop-dma",		optional_argument, 0, OPT_STOP_DMA },
-    {"list-dma-engines",	no_argument, 0, OPT_LIST_DMA },
-    {"list-dma-buffers",	required_argument, 0, OPT_LIST_DMA_BUFFERS },
-    {"read-dma-buffer",		required_argument, 0, OPT_READ_DMA_BUFFER },
-    {"enable-irq",		optional_argument, 0, OPT_ENABLE_IRQ },
-    {"disable-irq",		optional_argument, 0, OPT_DISABLE_IRQ },
-    {"acknowledge-irq",		optional_argument, 0, OPT_ACK_IRQ },
-    {"wait-irq",		optional_argument, 0, OPT_WAIT_IRQ },
-    {"list-kernel-memory",	optional_argument, 0, OPT_LIST_KMEM },
-    {"read-kernel-memory",	required_argument, 0, OPT_READ_KMEM },
-    {"alloc-kernel-memory",	required_argument, 0, OPT_ALLOC_KMEM },
-    {"free-kernel-memory",	required_argument, 0, OPT_FREE_KMEM },
-    {"type",			required_argument, 0, OPT_TYPE },
-    {"block-size",		required_argument, 0, OPT_BLOCK_SIZE },
-    {"alignment",		required_argument, 0, OPT_ALIGNMENT },
-    {"quiete",			no_argument, 0, OPT_QUIETE },
-    {"verbose",			optional_argument, 0, OPT_VERBOSE },
-    {"force",			no_argument, 0, OPT_FORCE },
-    {"verify",			no_argument, 0, OPT_VERIFY },
-    {"multipacket",		no_argument, 0, OPT_MULTIPACKET },
-    {"wait",			no_argument, 0, OPT_WAIT },
-    {"help",			no_argument, 0, OPT_HELP },
-    { 0, 0, 0, 0 }
-};
-
-
-void Usage(int argc, char *argv[], const char *format, ...) {
-    if (format) {
-	va_list ap;
-    
-	va_start(ap, format);
-	printf("Error %i: ", errno);
-	vprintf(format, ap);
-	printf("\n");
-	va_end(ap);
-    
-        printf("\n");
-    }
-
-
-    printf(
-"Usage:\n"
-" %s <mode> [options] [hex data]\n"
-"  Modes:\n"
-"   -i				- Device Info\n"
-"   -l[l]			- List (detailed) Data Banks & Registers\n"
-"   -r <addr|reg|dmaX>		- Read Data/Register\n"
-"   -w <addr|reg|dmaX>		- Write Data/Register\n"
-"   --benchmark <barX|dmaX>	- Performance Evaluation\n"
-"   --reset			- Reset board\n"
-"   --help			- Help message\n"
-"\n"
-"  Event Modes:\n"
-"   --trigger [event]		- Trigger Events\n"
-"   -g [event]			- Grab Events\n"
-"\n"
-"  IRQ Modes:\n"
-"   --enable-irq [type]		- Enable IRQs\n"
-"   --disable-irq [type]	- Disable IRQs\n"
-"   --acknowledge-irq <source>	- Clean IRQ queue\n"
-"   --wait-irq <source>		- Wait for IRQ\n"
-
-"  DMA Modes:\n"
-"   --start-dma <num>[r|w]	- Start specified DMA engine\n"
-"   --stop-dma [num[r|w]]	- Stop specified engine or DMA subsystem\n"
-"   --list-dma-engines		- List active DMA engines\n"
-"   --list-dma-buffers <dma>	- List buffers for specified DMA engine\n"
-"   --read-dma-buffer <dma:buf>	- Read the specified buffer\n"
-"\n"
-"  Kernel Modes:\n"
-"   --list-kernel-memory [use] 	- List kernel buffers\n"
-"   --read-kernel-memory <blk>	- Read the specified block of the kernel memory\n"
-"				  block is specified as: use:block_number\n"
-"   --alloc-kernel-memory <use>	- Allocate kernel buffers (DANGEROUS)\n"
-"   --free-kernel-memory <use>	- Cleans lost kernel space buffers (DANGEROUS)\n"
-"	dma			- Remove all buffers allocated by DMA subsystem\n"
-"	#number			- Remove all buffers with the specified use id\n"
-"\n"
-"  Addressing:\n"
-"   -d <device>			- FPGA device (/dev/fpga0)\n"
-"   -m <model>			- Memory model (autodetected)\n"
-"	pci			- Plain\n"
-"	ipecamera		- IPE Camera\n"
-"   -b <bank>			- PCI bar, Register bank, or DMA channel\n"
-"\n"
-"  Options:\n"
-"   -s <size>			- Number of words (default: 1)\n"
-"   -a [fifo|dma|config]<bits>	- Access type and bits per word (default: 32)\n"
-"   -e <l|b>			- Endianess Little/Big (default: host)\n"
-"   -o <file>			- Append output to file (default: stdout)\n"
-"   -t <timeout|unlimited> 	- Timeout in microseconds\n"
-"   --check			- Verify write operations\n"
-"\n"
-"  Event Options:\n"
-"   --event <evt>		- Specifies event for trigger and grab modes\n"
-"   --data <type>		- Data type to request for the events\n"
-"   --run-time <us>		- Limit time to grab/trigger events\n"
-"   -t <timeout|unlimited>	- Timeout to stop if no events triggered\n"
-"   --trigger-rate <tps>		- Generate tps triggers per second\n"
-"   --trigger-time <us>		- Specifies delay between triggers (us)\n"
-"   -s <num|unlimited> 		- Number of events to grab and trigger\n"
-"   --format [type]		- Specifies how event data should be stored\n"
-"	raw			- Just write all events sequentially\n"
-"	add_header		- Prefix events with 512 bit header:\n"
-"				  event(64), data(64), nope(64), size(64)\n"
-"				  seqnum(64), offset(64), timestamp(128)\n"
-//"	ringfs			- Write to RingFS\n"
-"   --buffer [size]		- Request data buffering, size in MB\n"
-"   --threads [num]		- Allow multithreaded processing\n"
-"\n"
-"  DMA Options:\n"
-"   --multipacket		- Read multiple packets\n"
-"   --wait			- Wait until data arrives\n"
-"\n"
-"  Kernel Options:\n"
-"   --type <type>		- Type of kernel memory to allocate\n"
-"   	consistent		- Consistent memory\n"
-"   	s2c			- DMA S2C (write) memory\n"
-"   	c2s			- DMA C2S (read) memory\n"
-"   --page-size <size>		- Size of kernel buffer in bytes (default: page)\n"
-"   -s <size>			- Number of buffers to allocate (default: 1)\n"
-"   --allignment <alignment>	- Buffer alignment (default: page)\n"
-"\n"
-"  Information:\n"
-"   --verbose [level]		- Announce details of ongoing operations\n"
-"   -q				- Quiete mode (suppress warnings)\n"
-"\n"
-"  Data:\n"
-"	Data can be specified as sequence of hexdecimal number or\n"
-"	a single value prefixed with '*'. In this case it will be\n"
-"	replicated the specified amount of times\n"
-"\n\n",
-argv[0]);
-
-    exit(0);
-}
-
-static int StopFlag = 0;
-
-static void signal_exit_handler(int signo) { 
-    if (++StopFlag > 2)
-	exit(-1);
-}
-
-
-void Error(const char *format, ...) {
-    va_list ap;
-    
-    va_start(ap, format);
-    printf("Error %i: ", errno);
-    vprintf(format, ap);
-    if (errno) printf("\n errno: %s", strerror(errno));
-    printf("\n\n");
-    va_end(ap);
-    
-    exit(-1);
-}
-
-void Silence(const char *format, ...) {
-}
-
-void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, int details) {
-    int i,j;
-    pcilib_register_bank_description_t *banks;
-    pcilib_register_description_t *registers;
-    pcilib_event_description_t *events;
-    pcilib_event_data_type_description_t *types;
-
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
-    const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle);
-    
-    for (i = 0; i < PCILIB_MAX_BANKS; i++) {
-	if (board_info->bar_length[i] > 0) {
-	    printf(" BAR %d - ", i);
-
-	    switch ( board_info->bar_flags[i]&IORESOURCE_TYPE_BITS) {
-		case IORESOURCE_IO:  printf(" IO"); break;
-		case IORESOURCE_MEM: printf("MEM"); break;
-		case IORESOURCE_IRQ: printf("IRQ"); break;
-		case IORESOURCE_DMA: printf("DMA"); break;
-	    }
-	    
-	    if (board_info->bar_flags[i]&IORESOURCE_MEM_64) printf("64");
-	    else printf("32");
-	    
-	    printf(", Start: 0x%08lx, Length: 0x%8lx, Flags: 0x%08lx\n", board_info->bar_start[i], board_info->bar_length[i], board_info->bar_flags[i] );
-	}
-    }
-    printf("\n");
-    
-    if ((dma_info)&&(dma_info->engines)) {
-	printf("DMA Engines: \n");
-	for (i = 0; dma_info->engines[i]; i++) {
-	    pcilib_dma_engine_description_t *engine = dma_info->engines[i];
-	    printf(" DMA %2d ", engine->addr);
-	    switch (engine->direction) {
-		case PCILIB_DMA_FROM_DEVICE:
-		    printf("C2S");
-		break;
-		case PCILIB_DMA_TO_DEVICE:
-		    printf("S2C");
-		break;
-		case PCILIB_DMA_BIDIRECTIONAL:
-		    printf("BI ");
-		break;
-	    }
-	    printf(" - Type: ");
-	    switch (engine->type) {
-		case PCILIB_DMA_TYPE_BLOCK:
-		    printf("Block");
-		break;
-		case PCILIB_DMA_TYPE_PACKET:
-		    printf("Packet");
-		break;
-		default:
-		    printf("Unknown");
-	    }
-	    
-	    printf(", Address Width: %02lu bits\n", engine->addr_bits);
-	}
-	printf("\n");
-    }
-
-    if ((bank)&&(bank != (char*)-1)) banks = NULL;
-    else banks = model_info->banks;
-    
-    if (banks) {
-	printf("Banks: \n");
-	for (i = 0; banks[i].access; i++) {
-	    printf(" 0x%02x %s", banks[i].addr, banks[i].name);
-	    if ((banks[i].description)&&(banks[i].description[0])) {
-		printf(": %s", banks[i].description);
-	    }
-	    printf("\n");
-	}
-	printf("\n");
-    }
-    
-    if (bank == (char*)-1) registers = NULL;
-    else registers = model_info->registers;
-    
-    if (registers) {
-        pcilib_register_bank_addr_t bank_addr = 0;
-	if (bank) {
-	    pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank);
-	    pcilib_register_bank_description_t *b = model_info->banks + bank_id;
-
-	    bank_addr = b->addr;
-	    if (b->description) printf("%s:\n", b->description);
-	    else if (b->name) printf("Registers of bank %s:\n", b->name);
-	    else printf("Registers of bank 0x%x:\n", b->addr);
-	} else {
-	    printf("Registers: \n");
-	}
-	for (i = 0; registers[i].bits; i++) {
-	    const char *mode;
-	    
-	    if ((bank)&&(registers[i].bank != bank_addr)) continue;
-	    if (registers[i].type == PCILIB_REGISTER_BITS) {
-		if (!details) continue;
-		
-		if (registers[i].bits > 1) {
-		    printf("    [%2u:%2u] - %s\n", registers[i].offset, registers[i].offset + registers[i].bits, registers[i].name);
-		} else {
-		    printf("    [   %2u] - %s\n", registers[i].offset, registers[i].name);
-		}
-		
-		continue;
-	    }
-
-	    if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW";
-	    else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R ";
-	    else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W";
-	    else mode = "  ";
-	    
-	    printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name);
-	    if ((details > 0)&&(registers[i].description)&&(registers[i].description[0])) {
-		printf(": %s", registers[i].description);
-	    }
-	    printf("\n");
-
-	}
-	printf("\n");
-    }
-
-    if (bank == (char*)-1) events = NULL;
-    else {
-	events = model_info->events;
-	types = model_info->data_types;
-    }
-
-    if (events) {
-	printf("Events: \n");
-	for (i = 0; events[i].name; i++) {
-	    printf(" %s", events[i].name);
-	    if ((events[i].description)&&(events[i].description[0])) {
-		printf(": %s", events[i].description);
-	    }
-	    
-	    if (types) {
-		for (j = 0; types[j].name; j++) {
-		    if (types[j].evid & events[i].evid) {
-			printf("\n    %s", types[j].name);
-			if ((types[j].description)&&(types[j].description[0])) {
-			    printf(": %s", types[j].description);
-			}
-		    }
-		}
-	    }
-	}
-	printf("\n");
-    }
-}
-
-void Info(pcilib_t *handle, pcilib_model_description_t *model_info) {
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
-
-    printf("Vendor: %x, Device: %x, Bus: %x, Slot: %x, Function: %x\n", board_info->vendor_id, board_info->device_id, board_info->bus, board_info->slot, board_info->func);
-    printf(" Interrupt - Pin: %i, Line: %i\n", board_info->interrupt_pin, board_info->interrupt_line);
-    List(handle, model_info, (char*)-1, 0);
-}
-
-
-#define BENCH_MAX_DMA_SIZE 4 * 1024 * 1024
-#define BENCH_MAX_FIFO_SIZE 1024 * 1024
-
-int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, size_t iterations) {
-    int err;
-    int i, j, errors;
-    void *data, *buf, *check;
-    void *fifo = NULL;
-    struct timeval start, end;
-    unsigned long time;
-    size_t size, min_size, max_size;
-    double mbs_in, mbs_out, mbs;
-    size_t irqs;
-    
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
-    
-    if (mode == ACCESS_CONFIG)
-	Error("No benchmarking of configuration space acess is allowed");
-
-    if (mode == ACCESS_DMA) {
-	if (n) {
-	    min_size = n * access;
-	    max_size = n * access;
-	} else {
-	    min_size = 1024;
-	    max_size = BENCH_MAX_DMA_SIZE;
-	}
-	
-        for (size = min_size; size <= max_size; size *= 4) {
-	    mbs_in = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_FROM_DEVICE);
-	    mbs_out = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_TO_DEVICE);
-	    mbs = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_BIDIRECTIONAL);
-	    err = pcilib_wait_irq(handle, 0, 0, &irqs);
-	    if (err) irqs = 0;
-	    
-	    printf("%8zu KB - ", size / 1024);
-	    
-	    printf("RW: ");
-	    if (mbs < 0) printf("failed ...   ");
-	    else printf("%8.2lf MB/s", mbs);
-
-	    printf(", R: ");
-	    if (mbs_in < 0) printf("failed ...   ");
-	    else printf("%8.2lf MB/s", mbs_in);
-
-	    printf(", W: ");
-	    if (mbs_out < 0) printf("failed ...   ");
-	    else printf("%8.2lf MB/s", mbs_out);
-	    
-	    if (irqs) {
-	        printf(", IRQs: %lu", irqs);
-	    }
-
-	    printf("\n");
-	}
-	
-	return 0;
-    }
-
-    if (bar == PCILIB_BAR_INVALID) {
-	unsigned long maxlength = 0;
-	
-
-	for (i = 0; i < PCILIB_MAX_BANKS; i++) {
-	    if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + access))) {
-		bar = i;
-		break;
-	    }
-
-	    if (board_info->bar_length[i] > maxlength) {
-		maxlength = board_info->bar_length[i];
-		bar = i;
-	    }
-	}
-	
-	if (bar < 0) Error("Data banks are not available");
-    }
-    
-    if (n) {
-	if ((mode == ACCESS_BAR)&&(n * access > board_info->bar_length[bar])) Error("The specified size (%i) exceeds the size of bar (%i)", n * access, board_info->bar_length[bar]);
-
-	min_size = n * access;
-	max_size = n * access;
-    } else {
-	min_size = access;
-	if (mode == ACCESS_BAR) max_size = board_info->bar_length[bar];
-	else max_size = BENCH_MAX_FIFO_SIZE;
-    }
-    
-    err = posix_memalign( (void**)&buf, 256, max_size );
-    if (!err) err = posix_memalign( (void**)&check, 256, max_size );
-    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size);
-
-    data = pcilib_map_bar(handle, bar);
-    if (!data) Error("Can't map bar %i", bar);
-
-    if (mode == ACCESS_FIFO) {
-        fifo = data + (addr - board_info->bar_start[bar]) + (board_info->bar_start[bar] & pcilib_get_page_mask());
-//	pcilib_resolve_register_address(handle, bar, addr);
-	if (!fifo) Error("Can't resolve address (%lx) in bar (%u)", addr, bar);
-    }
-
-    if (mode == ACCESS_FIFO)
-	printf("Transfer time (Bank: %i, Fifo: %lx):\n", bar, addr);
-    else
-	printf("Transfer time (Bank: %i):\n", bar);
-	
-    for (size = min_size ; size < max_size; size *= 8) {
-	gettimeofday(&start,NULL);
-	if (mode == ACCESS_BAR) {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_memcpy(buf, data, size);
-	    }
-	} else {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		for (j = 0; j < (size/access); j++) {
-		    pcilib_memcpy(buf + j * access, fifo, access);
-		}
-	    }
-	}
-	gettimeofday(&end,NULL);
-
-	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
-	printf("%8zu bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
-	
-	fflush(0);
-
-	gettimeofday(&start,NULL);
-	if (mode == ACCESS_BAR) {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_memcpy(data, buf, size);
-	    }
-	} else {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		for (j = 0; j < (size/access); j++) {
-		    pcilib_memcpy(fifo, buf + j * access, access);
-		}
-	    }
-	}
-	gettimeofday(&end,NULL);
-
-	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
-	printf(", write: %8.2lf MB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
-    }
-    
-    pcilib_unmap_bar(handle, bar, data);
-
-    printf("\n\nOpen-Transfer-Close time: \n");
-    
-    for (size = 4 ; size < max_size; size *= 8) {
-	gettimeofday(&start,NULL);
-	if (mode == ACCESS_BAR) {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_read(handle, bar, 0, size, buf);
-	    }
-	} else {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_read_fifo(handle, bar, addr, access, size / access, buf);
-	    }
-	}
-	gettimeofday(&end,NULL);
-
-	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
-	printf("%8zu bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
-	
-	fflush(0);
-
-	gettimeofday(&start,NULL);
-	if (mode == ACCESS_BAR) {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_write(handle, bar, 0, size, buf);
-	    }
-	} else {
-	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_write_fifo(handle, bar, addr, access, size / access, buf);
-	    }
-	}
-	
-	gettimeofday(&end,NULL);
-
-	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
-	printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
-
-	if (mode == ACCESS_BAR) {
-	    gettimeofday(&start,NULL);
-	    for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) {
-		pcilib_write(handle, bar, 0, size, buf);
-		pcilib_read(handle, bar, 0, size, check);
-		if (memcmp(buf, check, size)) ++errors;
-	    }
-	    gettimeofday(&end,NULL);
-
-	    time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
-	    printf(", write-verify: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
-	    if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS);
-	}
-	printf("\n");
-    }
-    
-    printf("\n\n");
-
-    free(check);
-    free(buf);
-    
-    return 0;
-}
-
-#define pci2host16(endianess, value) endianess?
-
-/*
-typedef struct {
-    size_t size;
-    void *data;
-    size_t pos;
-
-    int multi_mode;
-} DMACallbackContext;
-
-static int DMACallback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
-    DMACallbackContext *ctx = (DMACallbackContext*)arg;
-    
-    if ((ctx->pos + bufsize > ctx->size)||(!ctx->data)) {
-	ctx->size *= 2;
-	ctx->data = realloc(ctx->data, ctx->size);
-	if (!ctx->data) {
-	    Error("Allocation of %i bytes of memory have failed", ctx->size);
-	    return 0;
-	}
-    }
-    
-    memcpy(ctx->data + ctx->pos, buf, bufsize);
-    ctx->pos += bufsize;
-
-    if (flags & PCILIB_DMA_FLAG_EOP) return 0;
-    return 1;
-}
-*/
-
-
-int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, size_t timeout, FILE *o) {
-    void *buf;
-    int i, err;
-    size_t ret, bytes;
-    size_t size = n * abs(access);
-    int block_width, blocks_per_line;
-    int numbers_per_block, numbers_per_line; 
-    pcilib_dma_engine_t dmaid;
-    pcilib_dma_flags_t dma_flags = 0;
-
-    int fd;
-    char stmp[256];
-    struct stat st;
-    const pcilib_board_info_t *board_info;
-
-    numbers_per_block = BLOCK_SIZE / access;
-
-    block_width = numbers_per_block * ((access * 2) +  SEPARATOR_WIDTH);
-    blocks_per_line = (LINE_WIDTH - 10) / (block_width +  BLOCK_SEPARATOR_WIDTH);
-    if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line;
-    numbers_per_line = blocks_per_line * numbers_per_block;
-
-    if (size) {
-	buf = malloc(size);
-        if (!buf) Error("Allocation of %zu bytes of memory has failed", size);
-    } else {
-	buf = NULL;
-    }
-    
-    switch (mode) {
-      case ACCESS_DMA:
-        if (timeout == (size_t)-1) timeout = PCILIB_DMA_TIMEOUT;
-    
-	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma);
-	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma);
-	
-	if (flags&FLAG_MULTIPACKET) dma_flags |= PCILIB_DMA_FLAG_MULTIPACKET;
-	if (flags&FLAG_WAIT) dma_flags |= PCILIB_DMA_FLAG_WAIT;
-	
-	if (size) {
-	    err = pcilib_read_dma_custom(handle, dmaid, addr, size, dma_flags, timeout, buf, &bytes);
-	    if (err) Error("Error (%i) is reported by DMA engine", err);
-	} else {
-	    dma_flags |= PCILIB_DMA_FLAG_IGNORE_ERRORS;
-	    
-	    size = 2048; bytes = 0;
-	    do {
-		size *= 2;
-		buf = realloc(buf, size);
-		if (!buf) Error("Allocation of %zu bytes of memory has failed", size);
-	        err = pcilib_read_dma_custom(handle, dmaid, addr, size - bytes, dma_flags, timeout, buf + bytes, &ret);
-		bytes += ret;
-		
-		if ((!err)&&(flags&FLAG_MULTIPACKET)) {
-		    err = PCILIB_ERROR_TOOBIG;
-		    if ((flags&FLAG_WAIT)==0) timeout = 0;
-		}
-	    } while (err == PCILIB_ERROR_TOOBIG);
-	}
-
-	if ((err)&&(err != PCILIB_ERROR_TIMEOUT)) {
-	    Error("Error (%i) during DMA read", err);
-	}
-	if (bytes <= 0) {
-	    pcilib_warning("No data is returned by DMA engine");
-	    return 0;
-	}
-	size = bytes;
-	n = bytes / abs(access);
-	addr = 0;
-      break;
-      case ACCESS_FIFO:
-	pcilib_read_fifo(handle, bar, addr, access, n, buf);
-	addr = 0;
-      break;
-      case ACCESS_CONFIG:
-	board_info = pcilib_get_board_info(handle);
-	sprintf(stmp, "/sys/bus/pci/devices/0000:%02x:%02x.%1x/config", board_info->bus, board_info->slot, board_info->func);
-	fd = open(stmp, O_RDONLY);
-
-	if ((!fd)||(fstat(fd, &st))) Error("Can't open %s", stmp);
-	
-        if (st.st_size < addr) 
-    	    Error("Access beyond the end of PCI configuration space");
-    	
-	if (st.st_size < (addr + size)) {
-	    n = (st.st_size - addr) / abs(access);
-	    size = n * abs(access);
-	    if (!n) Error("Access beyond the end of PCI configuration space");
-	}
-	
-	lseek(fd, addr, SEEK_SET);
-	ret = read(fd, buf, size);
-	if (ret == (size_t)-1) Error("Error reading %s", stmp);
-	
-	if (ret < size) {
-	    size = ret;
-	    n = ret / abs(access);
-	}
-	
-	close(fd);
-      break;
-      default:
-	pcilib_read(handle, bar, addr, size, buf);
-    }
-    
-    if (endianess) pcilib_swap(buf, buf, abs(access), n);
-
-    if (o) {
-	printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access));
-	fwrite(buf, abs(access), n, o);
-    } else {
-	for (i = 0; i < n; i++) {
-	    if (i) {
-		if (i%numbers_per_line == 0) printf("\n");
-		else {
-		    printf("%*s", SEPARATOR_WIDTH, "");
-		    if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
-		}
-	    }
-	    
-	    if (i%numbers_per_line == 0) printf("%8lx:  ", addr + i * abs(access));
-
-	    switch (access) {
-		case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break;
-		case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break;
-		case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break;
-		case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break;
-	    }
-	}
-	printf("\n\n");
-    }
-
-    
-    free(buf);
-    return 0;
-}
-
-
-
-
-int ReadRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg) {
-    int i;
-    int err;
-    const char *format;
-
-    pcilib_register_bank_t bank_id;
-    pcilib_register_bank_addr_t bank_addr = 0;
-
-    pcilib_register_value_t value;
-    
-    if (reg) {
-	pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
-        bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
-        format = model_info->banks[bank_id].format;
-        if (!format) format = "%lu";
-
-        err = pcilib_read_register_by_id(handle, regid, &value);
-    //    err = pcilib_read_register(handle, bank, reg, &value);
-        if (err) printf("Error reading register %s\n", reg);
-        else {
-	    printf("%s = ", reg);
-	    printf(format, value);
-	    printf("\n");
-	}
-    } else {
-	    // Adding DMA registers
-	pcilib_get_dma_info(handle);	
-    
-	if (model_info->registers) {
-	    if (bank) {
-		bank_id = pcilib_find_bank(handle, bank);
-		bank_addr = model_info->banks[bank_id].addr;
-	    }
-	    
-	    printf("Registers:\n");
-	    for (i = 0; model_info->registers[i].bits; i++) {
-		if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { 
-		    bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[i].bank);
-		    format = model_info->banks[bank_id].format;
-		    if (!format) format = "%lu";
-
-		    err = pcilib_read_register_by_id(handle, i, &value);
-		    if (err) printf(" %s = error reading value", model_info->registers[i].name);
-	    	    else {
-			printf(" %s = ", model_info->registers[i].name);
-			printf(format, value);
-		    }
-
-		    printf(" [");
-		    printf(format, model_info->registers[i].defvalue);
-		    printf("]");
-		    printf("\n");
-		}
-	    }
-	} else {
-	    printf("No registers");
-	}
-	printf("\n");
-    }
-    
-    return 0;
-}
-
-#define WRITE_REGVAL(buf, n, access, o) {\
-    uint##access##_t tbuf[n]; \
-    for (i = 0; i < n; i++) { \
-	tbuf[i] = (uint##access##_t)buf[i]; \
-    } \
-    fwrite(tbuf, access/8, n, o); \
-}
-
-int ReadRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, FILE *o) {
-    int err;
-    int i;
-
-    pcilib_register_bank_description_t *banks = model_info->banks;
-    pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank);
-
-    if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
-	if (bank) Error("Invalid register bank is specified (%s)", bank);
-	else Error("Register bank should be specified");
-    }
-
-    int access = banks[bank_id].access / 8;
-//    int size = n * abs(access);
-    int block_width, blocks_per_line;
-    int numbers_per_block, numbers_per_line; 
-    
-    numbers_per_block = BLOCK_SIZE / access;
-
-    block_width = numbers_per_block * ((access * 2) +  SEPARATOR_WIDTH);
-    blocks_per_line = (LINE_WIDTH - 6) / (block_width +  BLOCK_SEPARATOR_WIDTH);
-    if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line;
-    numbers_per_line = blocks_per_line * numbers_per_block;
-
-
-    pcilib_register_value_t buf[n];
-    err = pcilib_read_register_space(handle, bank, addr, n, buf);
-    if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
-
-
-    if (o) {
-	printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access));
-	switch (access) {
-	    case 1: WRITE_REGVAL(buf, n, 8, o) break;
-	    case 2: WRITE_REGVAL(buf, n, 16, o) break;
-	    case 4: WRITE_REGVAL(buf, n, 32, o) break;
-	    case 8: WRITE_REGVAL(buf, n, 64, o) break;
-	}
-    } else {
-	for (i = 0; i < n; i++) {
-	    if (i) {
-		if (i%numbers_per_line == 0) printf("\n");
-		else {
-		    printf("%*s", SEPARATOR_WIDTH, "");
-		    if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
-		}
-	    }
-	    
-	    if (i%numbers_per_line == 0) printf("%4lx:  ", addr + 4 * i - addr_shift);
-	    printf("%0*lx", access * 2, (unsigned long)buf[i]);
-	}
-	printf("\n\n");
-    }
-    
-    return 0;
-}
-
-int WriteData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, char ** data, int verify) {
-    int read_back = 0;
-    void *buf, *check;
-    int res = 0, i, err;
-    int size = n * abs(access);
-    size_t ret;
-    pcilib_dma_engine_t dmaid;
-
-    if (mode == ACCESS_CONFIG)
-	Error("Writting to PCI configuration space is not supported");
-
-    err = posix_memalign( (void**)&buf, 256, size );
-    if (!err) err = posix_memalign( (void**)&check, 256, size );
-    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
-
-    for (i = 0; i < n; i++) {
-	switch (access) {
-	    case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break;
-	    case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break;
-	    case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break;
-	    case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break;
-	    default: Error("Unexpected data size (%lu)", access);
-	}
-	if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
-    }
-
-    if (endianess) pcilib_swap(buf, buf, abs(access), n);
-
-    switch (mode) {
-      case ACCESS_DMA:
-	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma);
-	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma);
-	err = pcilib_write_dma(handle, dmaid, addr, size, buf, &ret);
-	if ((err)||(ret != size)) {
-	    if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout writting the data to DMA"); 
-	    else if (err) Error("DMA engine returned a error while writing the data");
-	    else if (!ret) Error("No data is written by DMA engine");
-	    else Error("Only %lu bytes of %lu is written by DMA engine", ret, size);
-	}
-      break;
-      case ACCESS_FIFO:
-	pcilib_write_fifo(handle, bar, addr, access, n, buf);
-      break;
-      default:
-	pcilib_write(handle, bar, addr, size, buf);
-	if (verify) {
-	    pcilib_read(handle, bar, addr, size, check);
-	    read_back = 1;
-	}
-    }
-
-    if ((read_back)&&(memcmp(buf, check, size))) {
-	printf("Write failed: the data written and read differ, the foolowing is read back:\n");
-        if (endianess) pcilib_swap(check, check, abs(access), n);
-	ReadData(handle, mode, 0, dma, bar, addr, n, access, endianess, (size_t)-1, NULL);
-	exit(-1);
-    }
-
-    free(check);
-    free(buf);
-    
-    return 0;
-}
-
-int WriteRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, char ** data) {
-    pcilib_register_value_t *buf, *check;
-    int res, i, err;
-    unsigned long value;
-    int size = n * sizeof(pcilib_register_value_t);
-
-    err = posix_memalign( (void**)&buf, 256, size );
-    if (!err) err = posix_memalign( (void**)&check, 256, size );
-    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
-
-    for (i = 0; i < n; i++) {
-	res = sscanf(data[i], "%lx", &value);
-	if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
-	buf[i] = value;
-    }
-
-    err = pcilib_write_register_space(handle, bank, addr, n, buf);
-    if (err) Error("Error writting register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
-    
-    err = pcilib_read_register_space(handle, bank, addr, n, check);
-    if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
-
-    if (memcmp(buf, check, size)) {
-	printf("Write failed: the data written and read differ, the foolowing is read back:\n");
-	ReadRegisterRange(handle, model_info, bank, addr, addr_shift, n, NULL);
-	exit(-1);
-    }
-
-    free(check);
-    free(buf);
-    
-    return 0;
-
-}
-
-int WriteRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg, char ** data) {
-    int err;
-
-    unsigned long val;
-    pcilib_register_value_t value;
-
-    const char *format = NULL;
-
-    pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
-    if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected");
-
-/*
-    pcilib_register_bank_t bank_id;
-    pcilib_register_bank_addr_t bank_addr;
-
-    bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
-    if (bank_id == PCILIB_REGISTER_BANK_INVALID) Error("Can't find bank of the register (%s)", reg);
-    format = model_info->banks[bank_id].format;
-    if (!format) format = "%lu";
-*/
-
-    if (isnumber(*data)) {
-	if (sscanf(*data, "%li", &val) != 1) {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
-	}
-
-	format = "%li";
-    } else if (isxnumber(*data)) {
-	if (sscanf(*data, "%lx", &val) != 1) {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
-	}
-	
-	format = "0x%lx";
-    } else {
-	    Error("Can't parse data value (%s) is not valid decimal number", *data);
-    }
-
-    value = val;
-    
-    err = pcilib_write_register(handle, bank, reg, value);
-    if (err) Error("Error writting register %s\n", reg);
-
-    if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) {
-	err = pcilib_read_register(handle, bank, reg, &value);
-	if (err) Error("Error reading back register %s for verification\n", reg);
-    
-	if (val != value) {
-	    Error("Failed to write register %s: %lu is written and %lu is read back", reg, val, value);
-	} else {
-	    printf("%s = ", reg);
-	    printf(format, value);
-	    printf("\n");
-	}
-    } else {
-        printf("%s is written\n ", reg);
-    }
-    
-    return 0;
-}
-
-typedef struct {
-    pcilib_t *handle;
-    pcilib_event_t event;
-    pcilib_event_data_type_t data;
-
-    fastwriter_t *writer;
-
-    int verbose;
-    pcilib_timeout_t timeout;
-    size_t run_time;
-    size_t trigger_time;    
-    size_t max_triggers;
-    pcilib_event_flags_t flags;
-    FORMAT format;
-    
-    volatile int event_pending;			/**< Used to detect that we have read previously triggered event */
-    volatile int trigger_thread_started;	/**< Indicates that trigger thread is ready and we can't procced to start event recording */
-    volatile int started;			/**< Indicates that recording is started */
-    
-    volatile int run_flag;
-    volatile int writing_flag;
-
-    struct timeval first_frame;    
-    struct timeval last_frame;
-    size_t last_num;
-    
-    size_t trigger_failed;
-    size_t trigger_count;
-    size_t event_count;
-    size_t incomplete_count;
-    size_t broken_count;
-    size_t missing_count;
-    size_t storage_count;
-    
-    struct timeval start_time;
-    struct timeval stop_time;
-} GRABContext;
-
-int GrabCallback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) {
-    int err = 0;
-    void *data;
-    size_t size;
-    
-    GRABContext *ctx = (GRABContext*)user;
-    pcilib_t *handle = ctx->handle;
-
-    gettimeofday(&ctx->last_frame, NULL);
-
-    if (!ctx->event_count) {
-	memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval));
-    }
-
-    ctx->event_pending = 0;
-    ctx->event_count++;
-    
-    if (ctx->last_num)
-	ctx->missing_count += (info->seqnum - ctx->last_num) - 1;
-    ctx->last_num = info->seqnum;
-    
-    if (info->flags&PCILIB_EVENT_INFO_FLAG_BROKEN) {
-	ctx->incomplete_count++;
-	return PCILIB_STREAMING_CONTINUE;
-    }
-    
-    switch (ctx->format) {
-     case FORMAT_DEFAULT:
-	data = pcilib_get_data(handle, event_id, PCILIB_EVENT_DATA, &size);
-	break;
-     default:
-	data = pcilib_get_data(handle, event_id, PCILIB_EVENT_RAW_DATA, &size);
-    }
-        
-    if (!data) {
-	ctx->broken_count++;
-	return PCILIB_STREAMING_CONTINUE;
-    }
-
-    if (ctx->format == FORMAT_HEADER) {
-	uint64_t header[8];
-	header[0] = info->type;
-	header[1] = ctx->data;
-	header[2] = 0;
-	header[3] = size;
-	header[4] = info->seqnum;
-	header[5] = info->offset;
-	memcpy(header + 6, &info->timestamp, 16);
-	
-	err = fastwriter_push(ctx->writer, 64, header);
-    }
-
-    if (!err) 
-	err = fastwriter_push(ctx->writer, size, data);
-
-    if (err) {
-	fastwriter_cancel(ctx->writer);
-
-	if (err != EWOULDBLOCK)
-	    Error("Storage error %i", err);
-
-	ctx->storage_count++;
-	pcilib_return_data(handle, event_id, ctx->data, data);
-	return PCILIB_STREAMING_CONTINUE;
-    }
-
-    err = pcilib_return_data(handle, event_id, ctx->data, data);
-    if (err) {
-	ctx->missing_count++;
-	fastwriter_cancel(ctx->writer);
-	return PCILIB_STREAMING_CONTINUE;
-    }
-
-    err = fastwriter_commit(ctx->writer);
-    if (err) Error("Error commiting data to storage, Error: %i", err);
-    
-    return PCILIB_STREAMING_CONTINUE;
-}
-
-int raw_data(pcilib_event_id_t event_id, pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user) {
-    int err;
-
-    GRABContext *ctx = (GRABContext*)user;
-//    pcilib_t *handle = ctx->handle;
-
-
-    if ((info)&&(info->seqnum != ctx->last_num)) {
-        gettimeofday(&ctx->last_frame, NULL);
-	if (!ctx->event_count) {
-	    memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval));
-	}
-
-	ctx->event_count++;
-	ctx->missing_count += (info->seqnum - ctx->last_num) - 1;
-	ctx->last_num = info->seqnum;
-    }
-
-    err = fastwriter_push_data(ctx->writer, size, data);
-    if (err) {
-	if (err == EWOULDBLOCK) Error("Storage is not able to handle the data stream, buffer overrun");
-	Error("Storage error %i", err);
-    }
-    
-    return PCILIB_STREAMING_CONTINUE;
-}
-
-
-void *Trigger(void *user) {
-    int err;
-    struct timeval start;
-
-    GRABContext *ctx = (GRABContext*)user;
-    size_t trigger_time = ctx->trigger_time;
-    size_t max_triggers = ctx->max_triggers;
-    
-    ctx->trigger_thread_started = 1;
-    ctx->event_pending = 1;
-
-    while (!ctx->started) ;
-
-    gettimeofday(&start, NULL);
-    do {
-        err = pcilib_trigger(ctx->handle, ctx->event, 0, NULL);
-        if (err) ctx->trigger_failed++;
-	if ((++ctx->trigger_count == max_triggers)&&(max_triggers)) break;
-	
-	if (trigger_time) {
-	    pcilib_add_timeout(&start, trigger_time);
-	    if ((ctx->stop_time.tv_sec)&&(pcilib_timecmp(&start, &ctx->stop_time)>0)) break;
-	    pcilib_sleep_until_deadline(&start);
-	}  else {
-	    while ((ctx->event_pending)&&(ctx->run_flag)) usleep(10);
-	    ctx->event_pending = 1;
-	}
-    } while (ctx->run_flag);
-
-    ctx->trigger_thread_started = 0;
-
-    return NULL;
-}
-
-void GrabStats(GRABContext *ctx, struct timeval *end_time) {
-    int verbose;
-    pcilib_timeout_t duration, fps_duration;
-    struct timeval cur;
-    double fps = 0, good_fps = 0;
-    size_t total, good, pending = 0;
-
-    verbose = ctx->verbose;
-    
-    if (end_time) {
-	if (verbose++) {
-	    printf("-------------------------------------------------------------------------------\n");
-	}
-    } else {
-	gettimeofday(&cur, NULL);
-	end_time = &cur;
-    }
-
-//    if ((ctx->event_count + ctx->missing_count) == 0) 
-//	return;
-    
-    duration = pcilib_timediff(&ctx->start_time, end_time);
-    fps_duration = pcilib_timediff(&ctx->first_frame, &ctx->last_frame);
-    
-    if (ctx->trigger_count) {
-	total = ctx->trigger_count;
-	pending = ctx->trigger_count - ctx->event_count - ctx->missing_count - ctx->trigger_failed;
-    } else {
-	total = ctx->event_count + ctx->missing_count;
-    }
-    
-    good = ctx->event_count - ctx->broken_count - ctx->incomplete_count - ctx->storage_count;
-
-    if (ctx->event_count > 1) {
-	fps = (ctx->event_count - 1) / (1.*fps_duration/1000000);
-    }
-    
-    if (good > 1) {
-	good_fps = (good - 1) / (1.*fps_duration/1000000);
-    }
-
-    printf("Run: ");
-    PrintTime(duration);    
-    
-    if (ctx->trigger_count) {
-	printf(", Triggers: ");
-	PrintNumber(ctx->trigger_count);
-    }
-    
-    printf(", Captured: ");
-    PrintNumber(ctx->event_count);
-    printf(" FPS %5.0lf", fps);
-
-    if ((ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) == 0) {
-	printf(", Stored: ");
-	PrintNumber(good);
-	printf(" FPS %5.0lf", good_fps);
-    }
-
-    printf("\n");    
-
-    if (verbose > 2) {
-	if (ctx->trigger_count) {
-	    printf("Trig: ");
-	    PrintNumber(ctx->trigger_count);
-	    printf(" Issued: ");
-	    PrintNumber(ctx->trigger_count - ctx->trigger_failed);
-	    printf(" (");
-	    PrintPercent(ctx->trigger_count - ctx->trigger_failed, ctx->trigger_count);
-	    printf("%%) Failed: ");
-	    PrintNumber(ctx->trigger_failed);
-	    printf( " (");
-	    PrintPercent(ctx->trigger_failed, ctx->trigger_count);
-	    printf( "%%); Pending: ");
-	    PrintNumber(pending);
-	    printf( " (");
-	    PrintPercent(pending, ctx->trigger_count);
-	    printf( "%%)\n");
-	}
-	
-	if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
-	    printf("Captured: ");
-	    PrintNumber(good);
-	} else {
-	    printf("Good: ");
-	    PrintNumber(good);
-	    printf(", Dropped: ");
-    	    PrintNumber(ctx->storage_count);
-	    printf(", Bad: ");
-	    PrintNumber(ctx->incomplete_count);
-	    printf(", Empty: ");
-    	    PrintNumber(ctx->broken_count);
-	}
-	printf(", Lost: ");
-	PrintNumber(ctx->missing_count);
-	printf("\n");
-    }
-
-    if (verbose > 1) {
-	if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
-	    printf("Captured: ");
-	    PrintPercent(good, total);
-	} else {
-	    printf("Good: ");
-	    PrintPercent(good, total);
-	    printf("%% Dropped: ");
-	    PrintPercent(ctx->storage_count, total);
-	    printf("%% Bad: ");
-	    PrintPercent(ctx->incomplete_count, total);
-	    printf("%% Empty: ");
-	    PrintPercent(ctx->broken_count, total);
-	}
-
-	printf("%% Lost: ");
-	PrintPercent(ctx->missing_count, total);
-        printf("%%");
-	printf("\n");
-    }
-}
-
-void StorageStats(GRABContext *ctx) {
-    int err;
-    fastwriter_stats_t st;
-
-    pcilib_timeout_t duration;
-    struct timeval cur;
-
-    gettimeofday(&cur, NULL);
-    duration = pcilib_timediff(&ctx->start_time, &cur);
-
-    
-    err = fastwriter_get_stats(ctx->writer, &st);
-    if (err) return;
-
-    printf("Wrote ");
-    PrintSize(st.written);
-    printf(" of ");
-    PrintSize(st.commited);
-    printf(" at ");
-    PrintSize(1000000.*st.written / duration);
-    printf("/s, %6.2lf%% ", 100.*st.buffer_used / st.buffer_size);
-    printf(" of ");
-    PrintSize(st.buffer_size);
-    printf(" buffer (%6.2lf%% max)\n", 100.*st.buffer_max / st.buffer_size);
-}
-
-void *Monitor(void *user) {
-    struct timeval deadline;
-    struct timeval nextinfo;
-    
-    GRABContext *ctx = (GRABContext*)user;
-    int verbose = ctx->verbose;
-    pcilib_timeout_t timeout = ctx->timeout;
-    
-    
-    if (timeout == PCILIB_TIMEOUT_INFINITE) timeout = 0;
-
-//    while (!ctx->started);
-    
-    if (timeout) {
-	memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval));
-	pcilib_add_timeout(&deadline, timeout);
-    }
-    
-    if (verbose > 0) {
-	pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
-    }
-    
-    while (ctx->run_flag) {
-	if (StopFlag) {
-	    pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
-	    break;
-	}
-	
-	if (timeout) {
-	    if (pcilib_calc_time_to_deadline(&deadline) == 0) {
-		memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval));
-		pcilib_add_timeout(&deadline, timeout);
-		
-		if (pcilib_calc_time_to_deadline(&deadline) == 0) {
-		    pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
-		    break;
-		}
-	    }
-	}
-	
-	if (verbose > 0) {
-	    if (pcilib_calc_time_to_deadline(&nextinfo) == 0) {
-		GrabStats(ctx, NULL);
-		StorageStats(ctx);
-		pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
-	    }
-	}
-	
-	usleep(100000);
-    }
-    
-    pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
-    while (ctx->writing_flag) {
-        if (pcilib_calc_time_to_deadline(&nextinfo) == 0) {
-	    if (verbose >= 0) StorageStats(ctx);
-	    pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
-	}
-    
-	usleep(100000);
-    }
-    
-    return NULL;
-}
-
-int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, const char *data_type, size_t num, size_t run_time, size_t trigger_time, pcilib_timeout_t timeout, PARTITION partition, FORMAT format, size_t buffer_size, size_t threads, int verbose, const char *output) {
-    int err;
-    GRABContext ctx;
-//    void *data = NULL;
-//    size_t size, written;
-
-    pcilib_event_t event;
-    pcilib_event_t listen_events;
-    pcilib_event_data_type_t data;
-
-    pthread_t monitor_thread;
-    pthread_t trigger_thread;
-    pthread_attr_t attr;
-    struct sched_param sched;
-
-    struct timeval end_time;
-    pcilib_event_flags_t flags;
-
-    if (evname) {
-	event = pcilib_find_event(handle, evname);
-	if (event == PCILIB_EVENT_INVALID) 
-	    Error("Can't find event (%s)", evname);
-
-	listen_events = event;
-    } else {
-	listen_events = PCILIB_EVENTS_ALL;
-	event = PCILIB_EVENT0;
-    }
-    
-    if (data_type) {
-	data = pcilib_find_event_data_type(handle, event, data_type);
-	if (data == PCILIB_EVENT_DATA_TYPE_INVALID)
-	    Error("Can't find data type (%s)", data_type);
-    } else {
-	data = PCILIB_EVENT_DATA;
-    }
-    
-    memset(&ctx, 0, sizeof(GRABContext));
-    
-    ctx.handle = handle;
-    ctx.event = event;
-    ctx.data = data;
-    ctx.run_time = run_time;
-    ctx.timeout = timeout;
-    ctx.format = format;
-
-    if (grab_mode&GRAB_MODE_GRAB) ctx.verbose = verbose;
-    else ctx.verbose = 0;
-    
-    if (grab_mode&GRAB_MODE_GRAB) {
-	ctx.writer =  fastwriter_init(output, 0);
-	if (!ctx.writer)
-	    Error("Can't initialize fastwritter library");
-
-	fastwriter_set_buffer_size(ctx.writer, buffer_size);
-	
-	err = fastwriter_open(ctx.writer, output, 0);
-	if (err)
-	    Error("Error opening file (%s), Error: %i\n", output, err);
-
-	ctx.writing_flag = 1;
-    }
-
-    ctx.run_flag = 1;
-
-    flags = PCILIB_EVENT_FLAGS_DEFAULT;
-    
-    if (data == PCILIB_EVENT_RAW_DATA) {
-	if (format == FORMAT_RAW) {
-	    flags |= PCILIB_EVENT_FLAG_RAW_DATA_ONLY;
-	}
-    } else {
-	flags |= PCILIB_EVENT_FLAG_PREPROCESS;
-    }
-    
-    ctx.flags = flags;
-
-//    printf("Limits: %lu %lu %lu\n", num, run_time, timeout);
-    pcilib_configure_autostop(handle, num, run_time);
-    
-    if (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
-	pcilib_configure_rawdata_callback(handle, &raw_data, &ctx);
-    }
-    
-    if (flags&PCILIB_EVENT_FLAG_PREPROCESS) {
-	pcilib_configure_preprocessing_threads(handle, threads);
-    }
-    
-    if (grab_mode&GRAB_MODE_TRIGGER) {
-	if (trigger_time) {
-	    if ((timeout)&&(trigger_time * 2 > timeout)) {
-		timeout = 2 * trigger_time;
-		ctx.timeout = timeout;
-	    }
-	} else {
-		// Otherwise, we will trigger next event after previous one is read
-	    if (((grab_mode&GRAB_MODE_GRAB) == 0)||(flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)) trigger_time = PCILIB_TRIGGER_TIMEOUT;
-	}
-	
-	ctx.max_triggers = num;
-	ctx.trigger_count = 0;
-	ctx.trigger_time = trigger_time;
-
-	    // We don't really care if RT priority is imposible
-	pthread_attr_init(&attr);
-	if (!pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
-	    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
-	    pthread_attr_setschedparam(&attr, &sched);
-	}
-    
-	    // Start triggering thread and wait until it is schedulled
-	if (pthread_create(&trigger_thread, &attr, Trigger, (void*)&ctx))
-	    Error("Error spawning trigger thread");
-
-	while (!ctx.trigger_thread_started) usleep(10);
-    }
-
-    gettimeofday(&ctx.start_time, NULL);
-
-    if (grab_mode&GRAB_MODE_GRAB) {
-	err = pcilib_start(handle, listen_events, flags);
-	if (err) Error("Failed to start event engine, error %i", err);
-    }
-    
-    ctx.started = 1;
-    
-    if (run_time) {
-	ctx.stop_time.tv_usec = ctx.start_time.tv_usec + run_time%1000000;
-	if (ctx.stop_time.tv_usec > 999999) {
-	    ctx.stop_time.tv_usec -= 1000000;
-	    __sync_synchronize();
-	    ctx.stop_time.tv_sec = ctx.start_time.tv_sec + 1 + run_time / 1000000;
-	} else {
-	    __sync_synchronize();
-	    ctx.stop_time.tv_sec = ctx.start_time.tv_sec + run_time / 1000000;
-	}
-    }
-    
-    memcpy(&ctx.last_frame, &ctx.start_time, sizeof(struct timeval));
-    if (pthread_create(&monitor_thread, NULL, Monitor, (void*)&ctx))
-	Error("Error spawning monitoring thread");
-
-    if (grab_mode&GRAB_MODE_GRAB) {
-	err = pcilib_stream(handle, &GrabCallback, &ctx);
-	if (err) Error("Error streaming events, error %i", err);
-    }
-    
-    ctx.run_flag = 0;
-
-    if (grab_mode&GRAB_MODE_TRIGGER) {
-	while (ctx.trigger_thread_started) usleep(10);
-    }
-    
-    if (grab_mode&GRAB_MODE_GRAB) {
-        pcilib_stop(handle, PCILIB_EVENT_FLAGS_DEFAULT);
-    }
-
-    gettimeofday(&end_time, NULL);
-
-    if (grab_mode&GRAB_MODE_TRIGGER) {
-	pthread_join(trigger_thread, NULL);
-    }
-    
-
-    if (grab_mode&GRAB_MODE_GRAB) {
-	if (verbose >= 0)
-	    printf("Grabbing is finished, flushing results....\n");
-    
-	err = fastwriter_close(ctx.writer);
-	if (err) Error("Storage problems, error %i", err);
-    }
-
-    ctx.writing_flag = 0;
-
-    pthread_join(monitor_thread, NULL);
-
-    if ((grab_mode&GRAB_MODE_GRAB)&&(verbose>=0)) {
-	GrabStats(&ctx, &end_time);
-	StorageStats(&ctx);
-    }
-
-    fastwriter_destroy(ctx.writer);
-
-    return 0;
-}
-
-int StartStopDMA(pcilib_t *handle,  pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, int start) {
-    int err;
-    pcilib_dma_engine_t dmaid;
-    
-    if (dma == PCILIB_DMA_ENGINE_ADDR_INVALID) {
-        const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle);
-
-        if (start) Error("DMA engine should be specified");
-
-	for (dmaid = 0; dma_info->engines[dmaid]; dmaid++) {
-	    err = pcilib_start_dma(handle, dmaid, 0);
-	    if (err) Error("Error starting DMA Engine (%s %i)", ((dma_info->engines[dmaid]->direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid]->addr);
-	    err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
-	    if (err) Error("Error stopping DMA Engine (%s %i)", ((dma_info->engines[dmaid]->direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid]->addr);
-	}
-	
-	return 0;
-    }
-    
-    if (dma_direction&PCILIB_DMA_FROM_DEVICE) {
-	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma);
-	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (C2S %lu) is specified", dma);
-	
-	if (start) {
-	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
-    	    if (err) Error("Error starting DMA engine (C2S %lu)", dma);
-	} else {
-	    err = pcilib_start_dma(handle, dmaid, 0);
-    	    if (err) Error("Error starting DMA engine (C2S %lu)", dma);
-	    err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
-    	    if (err) Error("Error stopping DMA engine (C2S %lu)", dma);
-	}
-    }
-    
-    if (dma_direction&PCILIB_DMA_TO_DEVICE) {
-	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma);
-	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (S2C %lu) is specified", dma);
-	
-	if (start) {
-	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
-    	    if (err) Error("Error starting DMA engine (S2C %lu)", dma);
-	} else {
-	    err = pcilib_start_dma(handle, dmaid, 0);
-    	    if (err) Error("Error starting DMA engine (S2C %lu)", dma);
-	    err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
-    	    if (err) Error("Error stopping DMA engine (S2C %lu)", dma);
-	}
-    }
-
-    return 0;
-}
-
-
-typedef struct {
-    pcilib_kmem_use_t use;
-    
-    int referenced;
-    int hw_lock;
-    int reusable;
-    int persistent;
-    int open;
-    
-    size_t count;
-    size_t size;
-} kmem_use_info_t;
-
-#define MAX_USES 64
-
-pcilib_kmem_use_t ParseUse(const char *use) {
-    unsigned long utmp;
-
-    if (use) {
-        if ((!isxnumber(use))||(sscanf(use, "%lx", &utmp) != 1)) Error("Invalid use (%s) is specified", use);
-
-	if (strlen(use) < 5)
-	    return PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER,utmp);
-	else
-	    return utmp;
-    }
-
-    Error("Kernel memory use is not specified");
-    return 0;
-}
-
-size_t FindUse(size_t *n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) {
-    size_t i, n = *n_uses;
-    
-    if (uses[n - 1].use == use) return n - 1;
-
-    for (i = 1; i < (n - 1); i++) {
-	if (uses[i].use == use) return i;
-    }
-    
-    if (n == MAX_USES) return 0;
-
-    uses[n].use = use;
-    return (*n_uses)++;
-}
-
-
-kmem_use_info_t *GetUse(size_t n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) {
-    size_t i;
-    for (i = 0; i < n_uses; i++) {
-	if (uses[i].use == use) {
-	    if (uses[i].count) return uses + i;
-	    else return NULL;
-	}
-    }
-    return NULL;
-}
-
-
-int ParseKMEM(pcilib_t *handle, const char *device, size_t *uses_number, kmem_use_info_t *uses) {
-    DIR *dir;
-    struct dirent *entry;
-    const char *pos;
-    char sysdir[256];
-    char fname[256];
-    char info[256];
-
-    size_t useid, n_uses = 1;	// Use 0 is for others
-
-    memset(uses, 0, sizeof(uses));
-    
-    pos = strrchr(device, '/');
-    if (pos) ++pos;
-    else pos = device;
-    
-    snprintf(sysdir, 255, "/sys/class/fpga/%s", pos);
-
-    dir = opendir(sysdir);
-    if (!dir) Error("Can't open directory (%s)", sysdir);
-    
-    while ((entry = readdir(dir)) != NULL) {
-	FILE *f;
-	unsigned long use = 0;
-	unsigned long size = 0;
-	unsigned long refs = 0;
-	unsigned long mode = 0;
-	unsigned long hwref = 0;
-	
-	if (strncmp(entry->d_name, "kbuf", 4)) continue;
-	if (!isnumber(entry->d_name+4)) continue;
-	
-	snprintf(fname, 255, "%s/%s", sysdir, entry->d_name);
-	f = fopen(fname, "r");
-	if (!f) Error("Can't access file (%s)", fname);
-
-	while(!feof(f)) {
-	    fgets(info, 256, f);
-	    if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16);
-	    if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10);
-	    if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10);
-	    if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16);
-	    if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10);
-	}
-	fclose(f);
-
-	useid = FindUse(&n_uses, uses, use);
-	uses[useid].count++;
-	uses[useid].size += size;
-	if (refs) uses[useid].referenced = 1;
-	if (hwref) uses[useid].hw_lock = 1;
-	if (mode&KMEM_MODE_REUSABLE) uses[useid].reusable = 1;
-	if (mode&KMEM_MODE_PERSISTENT) uses[useid].persistent = 1;
-	if (mode&KMEM_MODE_COUNT) uses[useid].open = 1;
-    }
-    closedir(dir);
-
-    *uses_number = n_uses;
-
-    return 0;
-}
-
-int ListKMEM(pcilib_t *handle, const char *device) {
-    int err;
-    char stmp[256];
-
-    size_t i, useid, n_uses;	
-    kmem_use_info_t uses[MAX_USES];
-
-    err = ParseKMEM(handle, device, &n_uses, uses);
-    if (err) Error("Failed to parse kernel memory information provided through sysfs");
-
-    if ((n_uses == 1)&&(uses[0].count == 0)) {
-	printf("No kernel memory is allocated\n");
-	return 0;
-    }
-    
-    printf("Use      Type                  Count      Total Size       REF       Mode \n");
-    printf("--------------------------------------------------------------------------------\n");
-    for (useid = 0; useid < n_uses; useid++) {
-	if (useid + 1 == n_uses) {
-	    if (!uses[0].count) continue;
-	    i = 0;
-	} else i = useid + 1;
-	
-	printf("%08x  ", uses[i].use);
-	if (!i) printf("All Others         ");
-	else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_DMA_RING) printf("DMA%u %s Ring      ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S"));
-	else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_DMA_PAGES) printf("DMA%u %s Pages     ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S"));
-	else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_USER)	printf("User %04x         ", uses[i].use&0xFFFF);
-	else printf ("                   ");
-	printf("  ");
-	printf("% 6lu", uses[i].count);
-	printf("     ");
-	printf("% 10s", GetPrintSize(stmp, uses[i].size));
-	printf("      ");
-	if (uses[i].referenced&&uses[i].hw_lock) printf("HW+SW");
-	else if (uses[i].referenced) printf("   SW");
-	else if (uses[i].hw_lock) printf("HW   ");
-	else printf("  -  ");
-	printf("      ");
-	if (uses[i].persistent) printf("Persistent");
-	else if (uses[i].open) printf("Open      ");
-	else if (uses[i].reusable) printf("Reusable  ");
-	else printf("Closed    ");
-	printf("\n");
-    }
-    printf("--------------------------------------------------------------------------------\n");
-    printf("REF - Software/Hardware Reference, MODE - Reusable/Persistent/Open\n");
-
-
-    return 0;
-}
-
-int DetailKMEM(pcilib_t *handle, const char *device, const char *use, size_t block) {
-    int err;
-    size_t i, n;
-    pcilib_kmem_handle_t *kbuf;
-    pcilib_kmem_use_t useid = ParseUse(use); 
-
-    size_t n_uses;	
-    kmem_use_info_t uses[MAX_USES];
-    kmem_use_info_t *use_info;
-    
-    if (block == (size_t)-1) {
-        err = ParseKMEM(handle, device, &n_uses, uses);
-	if (err) Error("Failed to parse kernel memory information provided through sysfs");
-	use_info = GetUse(n_uses, uses, useid);
-	if (!use_info) Error("No kernel buffers is allocated for the specified use (%lx)", useid);
-
-	i = 0;    
-	n = use_info->count;
-    } else {
-	i = block;
-	n = block + 1;
-    }
-    
-    kbuf = pcilib_alloc_kernel_memory(handle, 0, n, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
-    if (!kbuf) {
-	Error("Allocation of kernel buffer (use %lx, count %lu) is failed\n", useid, n);
-	return 0;
-    }
-
-    printf("Buffer         Address          Hardware Address          Bus Address\n");
-    printf("--------------------------------------------------------------------------------\n");
-    for (; i < n; i++) {
-	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);
-    }
-    printf("\n");
-
-    pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
-
-    return 0;
-}
-
-
-int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size_t block, size_t max_size, FILE *o) {
-    int err;
-    void *data;
-    size_t size;
-    pcilib_kmem_handle_t *kbuf;
-
-    if (block == (size_t)-1) block = 0;
-
-    kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
-    if (!kbuf) {
-	Error("The specified kernel buffer is not allocated\n");
-	return 0;
-    }
-
-    err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block);
-    if (err) {
-	pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
-	Error("The synchronization of kernel buffer has failed\n");
-	return 0;
-    }
-
-    data = 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;
-	
-	fwrite(data, 1, size, o?o:stdout);
-    } else {
-	pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
-	Error("The specified block is not existing\n");
-	return 0;
-    }
-
-    pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
-
-    return 0;
-}
-
-int AllocKMEM(pcilib_t *handle, const char *device, const char *use, const char *type, size_t size, size_t block_size, size_t alignment) {
-    pcilib_kmem_type_t ktype = PCILIB_KMEM_TYPE_PAGE;
-    pcilib_kmem_flags_t flags = KMEM_FLAG_REUSE;
-    pcilib_kmem_handle_t *kbuf;
-    pcilib_kmem_use_t useid = ParseUse(use);
-
-    long page_size = sysconf(_SC_PAGESIZE);
-
-    if (type) {
-	if (!strcmp(type, "consistent")) ktype = PCILIB_KMEM_TYPE_CONSISTENT;
-	else if (!strcmp(type, "c2s")) ktype = PCILIB_KMEM_TYPE_DMA_C2S_PAGE;
-	else if (!strcmp(type, "s2c")) ktype = PCILIB_KMEM_TYPE_DMA_S2C_PAGE;
-	else Error("Invalid memory type (%s) is specified", type);
-    } 
-    
-    if ((block_size)&&(ktype != PCILIB_KMEM_TYPE_CONSISTENT))
-	Error("Selected memory type does not allow custom size");
-    
-    kbuf = pcilib_alloc_kernel_memory(handle, ktype, size, (block_size?block_size:page_size), (alignment?alignment:page_size), useid, flags|KMEM_FLAG_PERSISTENT);
-    if (!kbuf) Error("Allocation of kernel memory has failed");
-
-    pcilib_free_kernel_memory(handle, kbuf, flags);
-
-    return 0;
-}
-
-int FreeKMEM(pcilib_t *handle, const char *device, const char *use, int force) {
-    int err;
-    int i;
-
-    pcilib_kmem_use_t useid;
-
-    pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; 
-    if (force) flags |= PCILIB_KMEM_FLAG_FORCE; // this will ignore mmap locks as well.
-
-    if (!strcasecmp(use, "dma")) {
-	for (i = 0; i < PCILIB_MAX_DMA_ENGINES; i++) {
-	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, i), flags);
-	    if (err) Error("Error cleaning DMA%i C2S Ring buffer", i);
-	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x80|i), flags);
-	    if (err) Error("Error cleaning DMA%i S2C Ring buffer", i);
-	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, i), flags);
-	    if (err) Error("Error cleaning DMA%i C2S Page buffers", i);
-	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x80|i), flags);
-	    if (err) Error("Error cleaning DMA%i S2C Page buffers", i);
-	}
-	
-	return 0;
-    }
-
-    useid = ParseUse(use);
-    err = pcilib_clean_kernel_memory(handle, useid, flags);
-    if (err) Error("Error cleaning kernel buffers for use (0x%lx)", useid);
-
-    return 0;
-}
-
-int ListDMA(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info) {
-    int err;
-    
-    DIR *dir;
-    struct dirent *entry;
-    const char *pos;
-    char sysdir[256];
-    char fname[256];
-    char info[256];
-    char stmp[256];
-
-    pcilib_dma_engine_t dmaid;
-    pcilib_dma_engine_status_t status;
-    
-    pos = strrchr(device, '/');
-    if (pos) ++pos;
-    else pos = device;
-    
-    snprintf(sysdir, 255, "/sys/class/fpga/%s", pos);
-
-    dir = opendir(sysdir);
-    if (!dir) Error("Can't open directory (%s)", sysdir);
-    
-    printf("DMA Engine     Status      Total Size         Buffer Ring (1st used - 1st free)\n");
-    printf("--------------------------------------------------------------------------------\n");
-    while ((entry = readdir(dir)) != NULL) {
-	FILE *f;
-	unsigned long use = 0;
-//	unsigned long size = 0;
-//	unsigned long refs = 0;
-	unsigned long mode = 0;
-//	unsigned long hwref = 0;
-	
-	if (strncmp(entry->d_name, "kbuf", 4)) continue;
-	if (!isnumber(entry->d_name+4)) continue;
-	
-	snprintf(fname, 255, "%s/%s", sysdir, entry->d_name);
-	f = fopen(fname, "r");
-	if (!f) Error("Can't access file (%s)", fname);
-
-	while(!feof(f)) {
-	    fgets(info, 256, f);
-	    if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16);
-//	    if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10);
-//	    if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10);
-	    if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16);
-//	    if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10);
-	}
-	fclose(f);
-	
-	if ((mode&(KMEM_MODE_REUSABLE|KMEM_MODE_PERSISTENT|KMEM_MODE_COUNT)) == 0) continue;	// closed
-	if ((use >> 16) != PCILIB_KMEM_USE_DMA_RING) continue;
-
-	if (use&0x80) {
-	    dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, use&0x7F);
-	} else {
-	    dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, use&0x7F);
-	}
-	
-	if (dmaid == PCILIB_DMA_ENGINE_INVALID) continue;
-	
-	
-	printf("DMA%lu %s         ", use&0x7F, (use&0x80)?"S2C":"C2S");
-        err = pcilib_start_dma(handle, dmaid, 0);
-        if (err) {
-    	    printf("-- Wrong state, start is failed\n");
-	    continue;
-	}
-	
-	err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
-	if (err) {
-	    printf("-- Wrong state, failed to obtain status\n");
-	    pcilib_stop_dma(handle, dmaid, 0);
-	    continue;
-	}
-
-	pcilib_stop_dma(handle, dmaid, 0);
-	
-	if (status.started) printf("S");
-	else printf(" ");
-	
-	if (status.ring_head == status.ring_tail) printf(" ");
-	else printf("D");
-
-	printf("        ");
-	printf("% 10s", GetPrintSize(stmp, status.ring_size * status.buffer_size));
-	
-	printf("         ");
-	printf("%zu - %zu (of %zu)", status.ring_tail, status.ring_head, status.ring_size);
-
-	printf("\n");
-	
-    }
-    closedir(dir);
-
-    printf("--------------------------------------------------------------------------------\n");
-    printf("S - Started, D - Data in buffers\n");
-
-    return 0;
-}
-
-int ListBuffers(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction) {
-    int err;
-    size_t i;
-    pcilib_dma_engine_t dmaid;
-    pcilib_dma_engine_status_t status;
-    pcilib_dma_buffer_status_t *buffer;
-    char stmp[256];
-
-    dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
-    if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
-
-    err = pcilib_start_dma(handle, dmaid, 0);
-    if (err) Error("Error starting the specified DMA engine");
-
-    err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
-    if (err) Error("Failed to obtain status of the specified DMA engine");
-
-    buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
-    if (!buffer) Error("Failed to allocate memory for status buffer");
-
-    err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
-    if (err) Error("Failed to obtain extended status of the specified DMA engine");
-
-
-    printf("Buffer      Status      Total Size         \n");
-    printf("--------------------------------------------------------------------------------\n");
-
-    for (i = 0; i < status.ring_size; i++) {
-	printf("%8zu    ", i);
-        printf("%c%c %c%c ", buffer[i].used?'U':' ',  buffer[i].error?'E':' ', buffer[i].first?'F':' ', buffer[i].last?'L':' ');
-	printf("% 10s", GetPrintSize(stmp, buffer[i].size));
-	printf("\n");
-    }
-
-    printf("--------------------------------------------------------------------------------\n");
-    printf("U - Used, E - Error, F - First block, L - Last Block\n");
-
-    free(buffer);
-
-    pcilib_stop_dma(handle, dmaid, 0);
-
-    return 0;
-}
-
-int ReadBuffer(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, size_t block, FILE *o) {
-    int err;
-    pcilib_dma_engine_t dmaid;
-    pcilib_dma_engine_status_t status;
-    pcilib_dma_buffer_status_t *buffer;
-    size_t size;
-
-    dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
-    if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
-
-    err = pcilib_start_dma(handle, dmaid, 0);
-    if (err) Error("Error starting the specified DMA engine");
-    
-    err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
-    if (err) Error("Failed to obtain status of the specified DMA engine");
-    
-    buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
-    if (!buffer) Error("Failed to allocate memory for status buffer");
-
-    err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
-    if (err) Error("Failed to obtain extended status of the specified DMA engine");
-
-    if (block == (size_t)-1) {
-	// get current 
-    }
-
-    size = buffer[block].size;
-
-    free(buffer);
-
-    pcilib_stop_dma(handle, dmaid, 0);
-
-    return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o);
-}
-
-
-int EnableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
-    int err;
-
-    err = pcilib_enable_irq(handle, irq_type, 0);
-    if (err) {
-	if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
-	    Error("Error enabling IRQs");
-    }
-    
-    return err;
-}
-
-int DisableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
-    int err;
-    
-    err = pcilib_disable_irq(handle, 0);
-    if (err) {
-	if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
-	    Error("Error disabling IRQs");
-    }
-    
-    return err;
-}
-
-int AckIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source) {
-    pcilib_clear_irq(handle, irq_source);
-    return 0;
-}
-
-int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) {
-    int err;
-    size_t count;
-
-    err = pcilib_wait_irq(handle, irq_source, timeout, &count);
-    if (err) {
-	if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout waiting for IRQ");
-	else Error("Error waiting for IRQ");
-    }
-
-    return 0;
-}
-
-
-int main(int argc, char **argv) {
-    int i;
-    long itmp;
-    size_t ztmp;
-    unsigned char c;
-
-    const char *stmp;
-    const char *num_offset;
-
-    int details = 0;
-    int verbose = 0;
-    int quiete = 0;
-    int force = 0;
-    int verify = 0;
-    
-    pcilib_model_t model = PCILIB_MODEL_DETECT;
-    pcilib_model_description_t *model_info;
-    MODE mode = MODE_INVALID;
-    GRAB_MODE grab_mode = 0;
-    size_t trigger_time = 0;
-    size_t run_time = 0;
-    size_t buffer = 0;
-    size_t threads = 1;
-    FORMAT format = FORMAT_DEFAULT;
-    PARTITION partition = PARTITION_UNKNOWN;
-    FLAGS flags = 0;
-    const char *atype = NULL;
-    const char *type = NULL;
-    ACCESS_MODE amode = ACCESS_BAR;
-    const char *fpga_device = DEFAULT_FPGA_DEVICE;
-    pcilib_bar_t bar = PCILIB_BAR_DETECT;
-    const char *addr = NULL;
-    const char *reg = NULL;
-    const char *bank = NULL;
-    char **data = NULL;
-    const char *event = NULL;
-    const char *data_type = NULL;
-    const char *dma_channel = NULL;
-    const char *use = NULL;
-    size_t block = (size_t)-1;
-    pcilib_irq_type_t irq_type = PCILIB_IRQ_TYPE_ALL;
-    pcilib_irq_hw_source_t irq_source =  PCILIB_IRQ_SOURCE_DEFAULT;
-    pcilib_dma_direction_t dma_direction = PCILIB_DMA_BIDIRECTIONAL;
-    pcilib_kmem_use_t useid = 0;
-    
-    pcilib_dma_engine_addr_t dma = PCILIB_DMA_ENGINE_ADDR_INVALID;
-    long addr_shift = 0;
-    uintptr_t start = -1;
-    size_t block_size = 0;
-    size_t size = 1;
-    access_t access = 4;
-//    int skip = 0;
-    int endianess = 0;
-    size_t timeout = 0;
-    size_t alignment = 0;
-    const char *output = NULL;
-    FILE *ofile = NULL;
-    size_t iterations = BENCHMARK_ITERATIONS;
-
-    pcilib_t *handle;
-
-    int size_set = 0;
-    int timeout_set = 0;
-//    int run_time_set = 0;
-
-    while ((c = getopt_long(argc, argv, "hqilr::w::g::d:m:t:b:a:s:e:o:", long_options, NULL)) != (unsigned char)-1) {
-	extern int optind;
-	switch (c) {
-	    case OPT_HELP:
-		Usage(argc, argv, NULL);
-	    break;
-	    case OPT_INFO:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_INFO;
-	    break;
-	    case OPT_LIST:
-		if (mode == MODE_LIST) details++;
-		else if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_LIST;
-	    break;
-	    case OPT_RESET:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_RESET;
-	    break;
-	    case OPT_BENCHMARK:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_BENCHMARK;
-
-		if (optarg) addr = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
-	    break;
-	    case OPT_READ:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_READ;
-		if (optarg) addr = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
-	    break;
-	    case OPT_WRITE:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_WRITE;
-		if (optarg) addr = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
-	    break;
-	    case OPT_GRAB:
-		if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_GRAB))) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_GRAB;
-		grab_mode |= GRAB_MODE_GRAB;
-		
-		stmp = NULL;
-		if (optarg) stmp = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++];
-
-		if (stmp) {
-		    if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event");
-		    event = stmp;
-		}
-	    break;
-	    case OPT_TRIGGER:
-		if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_TRIGGER))) Usage(argc, argv, "Multiple operations are not supported");
-
-		mode = MODE_GRAB;
-		grab_mode |= GRAB_MODE_TRIGGER;
-		
-		stmp = NULL;
-		if (optarg) stmp = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++];
-
-		if (stmp) {
-		    if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event");
-		    event = stmp;
-		}
-	    break;
-	    case OPT_LIST_DMA:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_LIST_DMA;
-	    break;
-	    case OPT_LIST_DMA_BUFFERS:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_LIST_DMA_BUFFERS;
-		dma_channel = optarg;
-	    break;
-	    case OPT_READ_DMA_BUFFER:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_READ_DMA_BUFFER;
-
-		num_offset = strchr(optarg, ':');
-
-		if (num_offset) {
-		    if (sscanf(num_offset + 1, "%zu", &block) != 1)
-			Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1);
-
-		    *(char*)num_offset = 0;
-		} else block = (size_t)-1;
-		
-		dma_channel = optarg;
-	    break;
-	    case OPT_START_DMA:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_START_DMA;
-		if (optarg) dma_channel = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
-	    break;
-	    case OPT_STOP_DMA:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_STOP_DMA;
-		if (optarg) dma_channel = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
-	    break;
-	    case OPT_ENABLE_IRQ:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_ENABLE_IRQ;
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
-			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
-
-		    irq_type = itmp;
-		}
-	    break;
-	    case OPT_DISABLE_IRQ:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_DISABLE_IRQ;
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
-			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
-
-		    irq_type = itmp;
-		}
-	    break;
-	    case OPT_ACK_IRQ:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_ACK_IRQ;
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
-			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
-
-		    irq_source = itmp;
-		}
-	    break;
-	    case OPT_WAIT_IRQ:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		
-		mode = MODE_WAIT_IRQ;
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
-			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
-
-		    irq_source = itmp;
-		}
-	    break;
-	    case OPT_LIST_KMEM:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		mode = MODE_LIST_KMEM;
-		
-		if (optarg) use = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-'))  use = argv[optind++];
-		else use = NULL;
-		
-		if (use) {
-		    num_offset = strchr(use, ':');
-
-		    if (num_offset) {
-			if (sscanf(num_offset + 1, "%zu", &block) != 1)
-			    Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
-
-			*(char*)num_offset = 0;
-		    }
-		}
-	    break;
-	    case OPT_READ_KMEM:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		mode = MODE_READ_KMEM;
-
-		num_offset = strchr(optarg, ':');
-
-		if (num_offset) {
-		    if (sscanf(num_offset + 1, "%zu", &block) != 1)
-			Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
-
-		    *(char*)num_offset = 0;
-		}
-		
-		use = optarg;
-		useid = ParseUse(use);
-    	    break;
-	    case OPT_ALLOC_KMEM:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		mode = MODE_ALLOC_KMEM;
-
-		if (optarg) use = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
-	    break;
-	    case OPT_FREE_KMEM:
-		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
-		mode = MODE_FREE_KMEM;
-
-		if (optarg) use = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
-	    break;
-	    case OPT_DEVICE:
-		fpga_device = optarg;
-	    break;
-	    case OPT_MODEL:
-		if (!strcasecmp(optarg, "pci")) model = PCILIB_MODEL_PCI;
-		else if (!strcasecmp(optarg, "ipecamera")) model = PCILIB_MODEL_IPECAMERA;
-		else if (!strcasecmp(optarg, "kapture")) model = PCILIB_MODEL_KAPTURE;
-		else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg);
-	    break;
-	    case OPT_BAR:
-		bank = optarg;
-//		if ((sscanf(optarg,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg);
-//		else bar = itmp;
-	    break;
-	    case OPT_ALIGNMENT:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &alignment) != 1)) {
-		    Usage(argc, argv, "Invalid alignment is specified (%s)", optarg);
-		}
-	    break;
-	    case OPT_ACCESS:
-		if (!strncasecmp(optarg, "fifo", 4)) {
-		    atype = "fifo";
-		    num_offset = optarg + 4;
-		    amode = ACCESS_FIFO;
-		} else if (!strncasecmp(optarg, "dma", 3)) {
-		    atype = "dma";
-		    num_offset = optarg + 3;
-		    amode = ACCESS_DMA;
-		} else if (!strncasecmp(optarg, "bar", 3)) {
-		    atype = "plain";
-		    num_offset = optarg + 3;
-		    amode = ACCESS_BAR;
-		} else if (!strncasecmp(optarg, "config", 6)) {
-		    atype = "config";
-		    num_offset = optarg + 6;
-		    amode = ACCESS_CONFIG;
-		} else if (!strncasecmp(optarg, "plain", 5)) {
-		    atype = "plain";
-		    num_offset = optarg + 5;
-		    amode = ACCESS_BAR;
-		} else {
-		    num_offset = optarg;
-		}
-
-		if (*num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
-			Usage(argc, argv, "Invalid access type (%s) is specified", optarg);
-
-	    	    switch (itmp) {
-			case 8: access = 1; break;
-			case 16: access = 2; break;
-			case 32: access = 4; break;
-			case 64: access = 8; break;
-			default: Usage(argc, argv, "Invalid data width (%s) is specified", num_offset);
-		    }	
-		}
-	    break;
-	    case OPT_SIZE:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &size) != 1)) {
-		    if (strcasecmp(optarg, "unlimited"))
-			Usage(argc, argv, "Invalid size is specified (%s)", optarg);
-		    else
-			size = 0;//(size_t)-1;
-		}
-			
-		size_set = 1;
-	    break;
-	    case OPT_BLOCK_SIZE:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &block_size) != 1)) {
-		    Usage(argc, argv, "Invalid size is specified (%s)", optarg);
-		}
-	    break;
-	    case OPT_ENDIANESS:
-		if ((*optarg == 'b')||(*optarg == 'B')) {
-		    if (ntohs(1) == 1) endianess = 0;
-		    else endianess = 1;
-		} else if ((*optarg == 'l')||(*optarg == 'L')) {
-		    if (ntohs(1) == 1) endianess = 1;
-		    else endianess = 0;
-		} else Usage(argc, argv, "Invalid endianess is specified (%s)", optarg);
-		
-	    break;
-	    case OPT_TIMEOUT:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &timeout) != 1)) {
-		    if (strcasecmp(optarg, "unlimited"))
-			Usage(argc, argv, "Invalid timeout is specified (%s)", optarg);
-		    else
-			timeout = PCILIB_TIMEOUT_INFINITE;
-		}
-		timeout_set = 1;
-	    break;
-	    case OPT_OUTPUT:
-		output = optarg;
-	    break;
-	    case OPT_ITERATIONS:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &iterations) != 1))
-		    Usage(argc, argv, "Invalid number of iterations is specified (%s)", optarg);
-	    break;
-	    case OPT_EVENT:
-		event = optarg;
-	    break;
-	    case OPT_TYPE:
-		type = optarg;
-	    break;
-	    case OPT_DATA_TYPE:
-		data_type = optarg;
-	    break;
-	    case OPT_RUN_TIME:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &run_time) != 1)) {
-		    if (strcasecmp(optarg, "unlimited"))
-			Usage(argc, argv, "Invalid run-time is specified (%s)", optarg);
-		    else
-			run_time = 0;
-		}
-//		run_time_set = 1;
-	    break;
-	    case OPT_TRIGGER_TIME:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &trigger_time) != 1))
-		    Usage(argc, argv, "Invalid trigger-time is specified (%s)", optarg);
-	    break;	    
-	    case OPT_TRIGGER_RATE:
-		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &ztmp) != 1))
-		    Usage(argc, argv, "Invalid trigger-rate is specified (%s)", optarg);
-		    
-		    trigger_time = (1000000 / ztmp) + ((1000000 % ztmp)?1:0);
-	    break;
-	    case OPT_BUFFER:
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &buffer) != 1))
-			Usage(argc, argv, "Invalid buffer size is specified (%s)", num_offset);
-		    buffer *= 1024 * 1024;
-		} else {
-		    buffer = get_free_memory();
-		    if (buffer < 256) Error("Not enough free memory (%lz MB) for buffering", buffer / 1024 / 1024);
-		    
-		    buffer -= 128 + buffer/16;
-		}
-	    break;	   
-	    case OPT_THREADS:
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &threads) != 1))
-			Usage(argc, argv, "Invalid threads number is specified (%s)", num_offset);
-		} else {
-		    threads = 0;
-		}
-	    break;	   
-	    case OPT_FORMAT:
-		if (!strcasecmp(optarg, "raw")) format =  FORMAT_RAW;
-		else if (!strcasecmp(optarg, "add_header")) format =  FORMAT_HEADER;
-//		else if (!strcasecmp(optarg, "ringfs")) format =  FORMAT_RINGFS;
-		else if (strcasecmp(optarg, "default")) Error("Invalid format (%s) is specified", optarg);
-	    break; 
-	    case OPT_QUIETE:
-		quiete = 1;
-		verbose = -1;
-	    break;
-	    case OPT_VERBOSE:
-		if (optarg) num_offset = optarg;
-		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
-		else num_offset = NULL;
-		
-		if (num_offset) {
-		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%i", &verbose) != 1))
-			Usage(argc, argv, "Invalid verbosity level is specified (%s)", num_offset);
-		} else {
-		    verbose = 1;
-		}
-	    break;
-	    case OPT_FORCE:
-		force = 1;
-	    break;
-	    case OPT_VERIFY:
-		verify = 1;
-	    break;
-	    case OPT_MULTIPACKET:
-		flags |= FLAG_MULTIPACKET;
-	    break;
-	    case OPT_WAIT:
-		flags |= FLAG_WAIT;
-	    break;
-	    default:
-		Usage(argc, argv, "Unknown option (%s) with argument (%s)", optarg?argv[optind-2]:argv[optind-1], optarg?optarg:"(null)");
-	}
-    }
-
-    if (mode == MODE_INVALID) {
-	if (argc > 1) Usage(argc, argv, "Operation is not specified");
-	else Usage(argc, argv, NULL);
-    }
-
-    pcilib_set_error_handler(&Error, quiete?Silence:NULL);
-
-    handle = pcilib_open(fpga_device, model);
-    if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device);
-
-    model = pcilib_get_model(handle);
-    model_info = pcilib_get_model_description(handle);
-
-    switch (mode) {
-     case MODE_WRITE:
-        if (((argc - optind) == 1)&&(*argv[optind] == '*')) {
-    	    int vallen = strlen(argv[optind]);
-    	    if (vallen > 1) {
-		data = (char**)malloc(size * (vallen + sizeof(char*)));
-		if (!data) Error("Error allocating memory for data array");
-
-		for (i = 0; i < size; i++) {
-		    data[i] = ((char*)data) + size * sizeof(char*) + i * vallen;
-		    strcpy(data[i], argv[optind] + 1);
-		}
-	    } else {
-		data = (char**)malloc(size * (9 + sizeof(char*)));
-		if (!data) Error("Error allocating memory for data array");
-		
-		for (i = 0; i < size; i++) {
-		    data[i] = ((char*)data) + size * sizeof(char*) + i * 9;
-		    sprintf(data[i], "%x", i);
-		}
-	    }
-        } else if ((argc - optind) == size) data = argv + optind;
-        else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size);
-     case MODE_READ:
-        if (!addr) {
-	    if (model == PCILIB_MODEL_PCI) {
-		if ((amode != ACCESS_DMA)&&(amode != ACCESS_CONFIG)) 
-		    Usage(argc, argv, "The address is not specified");
-	    } else ++mode;
-	}
-     break;
-     case MODE_START_DMA:
-     case MODE_STOP_DMA:
-     case MODE_LIST_DMA_BUFFERS:
-     case MODE_READ_DMA_BUFFER:
-        if ((dma_channel)&&(*dma_channel)) {
-	    itmp = strlen(dma_channel) - 1;
-	    if (dma_channel[itmp] == 'r') dma_direction = PCILIB_DMA_FROM_DEVICE;
-	    else if (dma_channel[itmp] == 'w') dma_direction = PCILIB_DMA_TO_DEVICE;
-
-	    if (dma_direction != PCILIB_DMA_BIDIRECTIONAL) itmp--;
-	    
-	    if (strncmp(dma_channel, "dma", 3)) num_offset = dma_channel;
-	    else {
-		num_offset = dma_channel + 3;
-		itmp -= 3;
-	    }
-	    
-	    if (bank) {
-		if (strncmp(num_offset, bank, itmp)) Usage(argc, argv, "Conflicting DMA channels are specified in mode parameter (%s) and bank parameter (%s)", dma_channel, bank);
-	    }
-		 
-	    if (!isnumber_n(num_offset, itmp))
-		 Usage(argc, argv, "Invalid DMA channel (%s) is specified", dma_channel);
-
-	    dma = atoi(num_offset);
-	}
-     break;
-     default:
-        if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
-    }
-
-
-    if (addr) {
-	if ((!strncmp(addr, "dma", 3))&&((addr[3]==0)||isnumber(addr+3))) {
-	    if ((atype)&&(amode != ACCESS_DMA)) Usage(argc, argv, "Conflicting access modes, the DMA read is requested, but access type is (%s)", type);
-	    if (bank) {
-		if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting DMA channels are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank);
-	    } else {
-		if (addr[3] == 0) Usage(argc, argv, "The DMA channel is not specified");
-	    }
-	    dma = atoi(addr + 3);
-	    amode = ACCESS_DMA;
-	    addr = NULL;
-	} else if ((!strncmp(addr, "bar", 3))&&((addr[3]==0)||isnumber(addr+3))) {
-	    if ((atype)&&(amode != ACCESS_BAR)) Usage(argc, argv, "Conflicting access modes, the plain PCI read is requested, but access type is (%s)", type);
-	    if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting PCI bars are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank);
-	    bar = atoi(addr + 3);
-	    amode = ACCESS_BAR;
-	    addr = NULL;
-	} else if (!strcmp(addr, "config")) {
-	    if ((atype)&&(amode != ACCESS_CONFIG)) Usage(argc, argv, "Conflicting access modes, the read of PCI configurataion space is requested, but access type is (%s)", type);
-	    amode = ACCESS_CONFIG;
-	    addr = NULL;
-	} else if ((isxnumber(addr))&&(sscanf(addr, "%lx", &start) == 1)) {
-		// check if the address in the register range
-	    pcilib_register_range_t *ranges =  model_info->ranges;
-	    
-	    if (ranges) {
-		for (i = 0; ranges[i].start != ranges[i].end; i++) 
-		    if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break;
-	    		
-		    // register access in plain mode
-		if (ranges[i].start != ranges[i].end) {
-		    pcilib_register_bank_t regbank = pcilib_find_bank_by_addr(handle, ranges[i].bank);
-		    if (regbank == PCILIB_REGISTER_BANK_INVALID) Error("Configuration error: register bank specified in the address range is not found");
-		    
-		    bank = model_info->banks[regbank].name;
-		    start += ranges[i].addr_shift;
-		    addr_shift = ranges[i].addr_shift;
-		    ++mode;
-		}
-	    }
-	} else {
-	    if (pcilib_find_register(handle, bank, addr) == PCILIB_REGISTER_INVALID) {
-	        Usage(argc, argv, "Invalid address (%s) is specified", addr);
-	    } else {
-	        reg = addr;
-		++mode;
-	    }
-	} 
-    }
-	
-    if (mode == MODE_GRAB) {
-	if (output) {
-	    char fsname[128];
-	    if (!get_file_fs(output, 127, fsname)) {
-		if (!strcmp(fsname, "ext4")) partition = PARTITION_EXT4;
-		else if (!strcmp(fsname, "raw")) partition = PARTITION_RAW;
-	    }
-	} else {
-	    output = "/dev/null";
-	    partition = PARTITION_NULL;
-	}
-
-	if (!timeout_set) {
-	    if (run_time) timeout = PCILIB_TIMEOUT_INFINITE;
-	    else timeout = PCILIB_EVENT_TIMEOUT;
-	}
-	
-	if (!size_set) {
-	    if (run_time) size = 0;
-	}
-    }
-    
-    if (mode != MODE_GRAB) {
-	if (size == (size_t)-1)
-	    Usage(argc, argv, "Unlimited size is not supported in selected operation mode");
-    }
-    
-
-    if ((bank)&&(amode == ACCESS_DMA)) {
-	if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)) 
-	    Usage(argc, argv, "Invalid DMA channel (%s) is specified", bank);
-	else dma = itmp;
-    } else if (bank) {
-	switch (mode) {
-	    case MODE_BENCHMARK:
-	    case MODE_READ:
-	    case MODE_WRITE:
-		if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) 
-		    Usage(argc, argv, "Invalid data bank (%s) is specified", bank);
-		else bar = itmp;
-	    break;
-	    default:
-		if (pcilib_find_bank(handle, bank) == PCILIB_REGISTER_BANK_INVALID)
-		    Usage(argc, argv, "Invalid data bank (%s) is specified", bank);
-	}
-    }
-
-    signal(SIGINT, signal_exit_handler);
-
-    if ((mode != MODE_GRAB)&&(output)) {
-	ofile = fopen(output, "a+");
-	if (!ofile) {
-	    Error("Failed to open file \"%s\"", output);
-	}
-    }    
-
-    switch (mode) {
-     case MODE_INFO:
-        Info(handle, model_info);
-     break;
-     case MODE_LIST:
-        List(handle, model_info, bank, details);
-     break;
-     case MODE_BENCHMARK:
-        Benchmark(handle, amode, dma, bar, start, size_set?size:0, access, iterations);
-     break;
-     case MODE_READ:
-	if (amode == ACCESS_DMA) {
-	    ReadData(handle, amode, flags, dma, bar, start, size_set?size:0, access, endianess, timeout_set?timeout:(size_t)-1, ofile);
-	} else if (amode == ACCESS_CONFIG) {
-	    ReadData(handle, amode, flags, dma, bar, addr?start:0, (addr||size_set)?size:(256/abs(access)), access, endianess, (size_t)-1, ofile);
-	} else if (addr) {
-	    ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile);
-	} else {
-	    Error("Address to read is not specified");
-	}
-     break;
-     case MODE_READ_REGISTER:
-        if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg);
-	else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile);
-     break;
-     case MODE_WRITE:
-	WriteData(handle, amode, dma, bar, start, size, access, endianess, data, verify);
-     break;
-     case MODE_WRITE_REGISTER:
-        if (reg) WriteRegister(handle, model_info, bank, reg, data);
-	else WriteRegisterRange(handle, model_info, bank, start, addr_shift, size, data);
-     break;
-     case MODE_RESET:
-        pcilib_reset(handle);
-     break;
-     case MODE_GRAB:
-        TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, timeout, partition, format, buffer, threads, verbose, output);
-     break;
-     case MODE_LIST_DMA:
-        ListDMA(handle, fpga_device, model_info);
-     break;
-     case MODE_LIST_DMA_BUFFERS:
-        ListBuffers(handle, fpga_device, model_info, dma, dma_direction);
-     break;
-     case MODE_READ_DMA_BUFFER:
-        ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile);
-     break;
-     case MODE_START_DMA:
-        StartStopDMA(handle, model_info, dma, dma_direction, 1);
-     break;
-     case MODE_STOP_DMA:
-        StartStopDMA(handle, model_info, dma, dma_direction, 0);
-     break;
-     case MODE_ENABLE_IRQ:
-        EnableIRQ(handle, model_info, irq_type);
-     break;
-     case MODE_DISABLE_IRQ:
-        DisableIRQ(handle, model_info, irq_type);
-     break;
-     case MODE_ACK_IRQ:
-        AckIRQ(handle, model_info, irq_source);
-     break;
-     case MODE_WAIT_IRQ:
-        WaitIRQ(handle, model_info, irq_source, timeout);
-     break;
-     case MODE_LIST_KMEM:
-        if (use) DetailKMEM(handle, fpga_device, use, block);
-        else ListKMEM(handle, fpga_device);
-     break;
-     case MODE_READ_KMEM:
-        ReadKMEM(handle, fpga_device, useid, block, 0, ofile);
-     break;
-     case MODE_ALLOC_KMEM:
-        AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment);
-     break;
-     case MODE_FREE_KMEM:
-        FreeKMEM(handle, fpga_device, use, force);
-     break;
-     case MODE_INVALID:
-        break;
-    }
-
-    if (ofile) fclose(ofile);
-
-    pcilib_close(handle);
-    
-    if (data != argv + optind) free(data);
-}

+ 24 - 19
ipecamera/model.c → cmosis.c

@@ -4,9 +4,12 @@
 #include <unistd.h>
 #include <assert.h>
 
-#include "../tools.h"
-#include "../error.h"
-#include "model.h"
+#include <pcilib.h>
+#include <pcilib/tools.h>
+#include <pcilib/error.h>
+
+#include "cmosis.h"
+#include "private.h"
 
 #define ADDR_MASK 0x7F00
 #define WRITE_BIT 0x8000
@@ -23,11 +26,12 @@
 
 //static pcilib_register_value_t ipecamera_bit_mask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
 
-int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
+int ipecamera_cmosis_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
     uint32_t val, tmp[4];
     char *wr, *rd;
     struct timeval start;//, cur;
     int retries = RETRIES;
+    const pcilib_register_bank_description_t *bank = bank_ctx->bank;
 
     assert(addr < 128);
     
@@ -52,21 +56,21 @@ retry:
     ipecamera_datacpy(wr, &val, bank);
 
 #ifdef IPECAMERA_SIMPLIFIED_READOUT
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
 //    ipecamera_datacpy(tmp, rd, bank);
-//    usleep(PCILIB_REGISTER_TIMEOUT);
+//    usleep(IPECAMERA_REGISTER_TIMEOUT);
     ipecamera_datacpy(wr, &val, bank);
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
 //    ipecamera_datacpy(tmp, rd, bank);
-//    usleep(PCILIB_REGISTER_TIMEOUT);
+//    usleep(IPECAMERA_REGISTER_TIMEOUT);
     ipecamera_datacpy(wr, &val, bank);
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
 #endif /* IPECAMERA_SIMPLIFIED_READOUT */
     
     gettimeofday(&start, NULL);
 
 #ifdef IPECAMERA_MULTIREAD
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
     pcilib_datacpy(tmp, rd, 4, 4, bank->raw_endianess);
     val = tmp[0];
 #else /* IPECAMERA_MULTIREAD */
@@ -74,7 +78,7 @@ retry:
 
     while ((val & READ_READY_BIT) == 0) {
         gettimeofday(&cur, NULL);
-	if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
+	if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > IPECAMERA_REGISTER_TIMEOUT) break;
 	
 	ipecamera_datacpy(&val, rd, bank);
     }
@@ -113,11 +117,12 @@ retry:
     return 0;
 }
 
-int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) {
+int ipecamera_cmosis_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t value) {
     uint32_t val, tmp[4];
     char *wr, *rd;
     struct timeval start;//, cur;
     int retries = RETRIES;
+    const pcilib_register_bank_description_t *bank = bank_ctx->bank;
 
     assert(addr < 128);
     assert(value < 256);
@@ -142,28 +147,28 @@ retry:
     ipecamera_datacpy(wr, &val, bank);
 
 #ifdef IPECAMERA_SIMPLIFIED_READOUT
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
 //    ipecamera_datacpy(tmp, rd, bank);
-//    usleep(PCILIB_REGISTER_TIMEOUT);
+//    usleep(IPECAMERA_REGISTER_TIMEOUT);
     ipecamera_datacpy(wr, &val, bank);
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
 //    ipecamera_datacpy(tmp, rd, bank);
-//    usleep(PCILIB_REGISTER_TIMEOUT);
+//    usleep(IPECAMERA_REGISTER_TIMEOUT);
     ipecamera_datacpy(wr, &val, bank);
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
 #endif /* IPECAMERA_SIMPLIFIED_READOUT */
 
     gettimeofday(&start, NULL);
 
 #ifdef IPECAMERA_MULTIREAD
-    usleep(PCILIB_REGISTER_TIMEOUT);
+    usleep(IPECAMERA_REGISTER_TIMEOUT);
     pcilib_datacpy(tmp, rd, 4, 4, bank->raw_endianess);
     val = tmp[0];
 #else /* IPECAMERA_MULTIREAD */
     ipecamera_datacpy(&val, rd, bank);
     while ((val & READ_READY_BIT) == 0) {
         gettimeofday(&cur, NULL);
-	if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
+	if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > IPECAMERA_REGISTER_TIMEOUT) break;
 	
 	ipecamera_datacpy(&val, rd, bank);
     }

+ 9 - 0
cmosis.h

@@ -0,0 +1,9 @@
+#ifndef _IPECAMERA_CMOSIS_H
+#define _IPECAMERA_CMOSIS_H
+
+#include <pcilib/bank.h>
+
+int ipecamera_cmosis_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
+int ipecamera_cmosis_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
+
+#endif /* _IPECAMERA_CMOSIS_H */

+ 0 - 61
common.mk

@@ -1,61 +0,0 @@
-# Compiler and default flags
-CC ?= gcc
-CFLAGS ?= -O0
-
-
-# Defaults for directories
-ROOTDIR ?= $(shell pwd)
-
-INCDIR ?= $(ROOTDIR)
-BINDIR ?= $(ROOTDIR)
-LIBDIR ?= $(ROOTDIR)
-OBJDIR ?= $(ROOTDIR)
-DEPENDDIR ?= $(ROOTDIR)
-
-CXXFLAGS += $(addprefix -I ,$(INCDIR)) -fPIC
-CFLAGS += $(addprefix -I ,$(INCDIR)) -fPIC -std=c99
-
-# Source files in this directory
-SRC = $(wildcard *.cpp)
-SRCC = $(wildcard *.c)
-
-SRC += $(wildcard ipecamera/*.cpp)
-SRCC += $(wildcard ipecamera/*.c)
-
-SRC += $(wildcard dma/*.cpp)
-SRCC += $(wildcard dma/*.c)
-
-# Corresponding object files 
-OBJ = $(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
-OBJ += $(addprefix $(OBJDIR)/,$(SRCC:.c=.o))
-
-# Corresponding dependency files
-DEPEND = $(addprefix $(DEPENDDIR)/,$(SRC:.cpp=.d)) 
-DEPEND += $(addprefix $(DEPENDDIR)/,$(SRCC:.c=.d)) 
-
-# This makes Verbose easier. Just prefix $(Q) to any command
-ifdef VERBOSE
-	Q ?= 
-else
-	Q ?= @
-endif
-
-###############################################################
-# Target definitions
-
-# Target for automatic dependency generation
-depend: $(DEPEND) $(DEPENDC);
-
-# This rule generates a dependency makefile for each source
-$(DEPENDDIR)/%.d: %.c
-	@echo -e "DEPEND \t$<"
-	$(Q)$(CC) $(addprefix -I ,$(INCDIR)) -MM -MF $@ \
-		-MT $(OBJDIR)/$(<:.c=.o) -MT $@ $< 
-
-# This includes the automatically 
-# generated dependency files
--include $(DEPEND)
-
-$(OBJDIR)/%.o: %.c
-	@echo -e "CC \t$<"
-	$(Q)@$(CC) $(CFLAGS) -c -o $@ $<

+ 3 - 3
ipecamera/data.c → data.c

@@ -11,10 +11,10 @@
 
 #include <ufodecode.h>
 
-#include "../tools.h"
-#include "../error.h"
+#include <pcilib.h>
+#include <pcilib/tools.h>
+#include <pcilib/error.h>
 
-#include "pcilib.h"
 #include "private.h"
 #include "data.h"
 

+ 0 - 0
ipecamera/data.h → data.h


+ 0 - 34
default.c

@@ -1,34 +0,0 @@
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <assert.h>
-
-#include "tools.h"
-#include "default.h"
-#include "error.h"
-
-#define default_datacpy(dst, src, access, bank)   pcilib_datacpy(dst, src, access, 1, bank->raw_endianess)
-
-int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
-    char *ptr;
-    pcilib_register_value_t val = 0;
-    int access = bank->access / 8;
-
-    ptr =  pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr + addr);
-    default_datacpy(&val, ptr, access, bank);
-
-//    *value = val&BIT_MASK(bits);
-    *value = val;
-
-    return 0;
-}
-
-
-int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) {
-    char *ptr;
-    int access = bank->access / 8;
-
-    ptr =  pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr + addr);
-    default_datacpy(ptr, &value, access, bank);
-
-    return 0;
-}

+ 0 - 9
default.h

@@ -1,9 +0,0 @@
-#ifndef _PCILIB_DEFAULT_H
-#define _PCILIB_DEFAULT_H
-
-#include "pcilib.h"
-
-int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
-int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
-
-#endif /* _PCILIB_DEFAULT_H */

+ 0 - 327
dma.c

@@ -1,327 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "error.h"
-#include "pcilib.h"
-#include "pci.h"
-#include "dma.h"
-
-const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx) {
-    if (!ctx->dma_ctx) {
-        pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-	if ((ctx->event_ctx)&&(model_info->event_api->init_dma)) {
-	    pcilib_map_register_space(ctx);
-	    ctx->dma_ctx = model_info->event_api->init_dma(ctx->event_ctx);
-	} else if ((model_info->dma_api)&&(model_info->dma_api->init)) {
-	    pcilib_map_register_space(ctx);
-	    ctx->dma_ctx = model_info->dma_api->init(ctx, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
-	}
-	
-	if (!ctx->dma_ctx) return NULL;
-    }
-    
-    return &ctx->dma_info;
-}
-
-pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma) {
-    pcilib_dma_engine_t i;
-
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-    if (!info) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-    
-    for (i = 0; info->engines[i]; i++) {
-	if ((info->engines[i]->addr == dma)&&((info->engines[i]->direction&direction)==direction)) break;
-    }
-    
-    if (info->engines[i]) return i;
-    return PCILIB_DMA_ENGINE_INVALID;
-}
-
-int pcilib_set_dma_engine_description(pcilib_t *ctx, pcilib_dma_engine_t engine, pcilib_dma_engine_description_t *desc) {
-    ctx->dma_info.engines[engine] = desc;
-
-    return 0;
-}
-
-int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-    if (!info) {
-	pcilib_error("DMA is not supported by the device");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (!ctx->model_info.dma_api) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return PCILIB_ERROR_NOTAVAILABLE;
-    }
-    
-    if (!ctx->model_info.dma_api->start_dma) {
-	return 0;
-    }
-    
-    return ctx->model_info.dma_api->start_dma(ctx->dma_ctx, dma, flags);
-}
-
-int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-
-    if (!info) {
-	pcilib_error("DMA is not supported by the device");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (!ctx->model_info.dma_api) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return PCILIB_ERROR_NOTAVAILABLE;
-    }
-    
-    if (!ctx->model_info.dma_api->stop_dma) {
-	return 0;
-    }
-
-    return ctx->model_info.dma_api->stop_dma(ctx->dma_ctx, dma, flags);
-}
-
-int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-
-    if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->enable_irq)) return 0;
-
-    return ctx->model_info.dma_api->enable_irq(ctx->dma_ctx, irq_type, flags);
-}
-
-int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-
-    if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->disable_irq)) return 0;
-
-    return ctx->model_info.dma_api->disable_irq(ctx->dma_ctx, flags);
-}
-
-int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-
-    if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->acknowledge_irq)) return 0;
-
-    return ctx->model_info.dma_api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source);
-}
-
-typedef struct {
-    size_t size;
-    void *data;
-    size_t pos;
-    
-    pcilib_dma_flags_t flags;
-} pcilib_dma_read_callback_context_t;
-
-static int pcilib_dma_read_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
-    pcilib_dma_read_callback_context_t *ctx = (pcilib_dma_read_callback_context_t*)arg;
-    
-    if (ctx->pos + bufsize > ctx->size) {
-	if ((ctx->flags&PCILIB_DMA_FLAG_IGNORE_ERRORS) == 0)
-	    pcilib_error("Buffer size (%li) is not large enough for DMA packet, at least %li bytes is required", ctx->size, ctx->pos + bufsize); 
-	return -PCILIB_ERROR_TOOBIG;
-    }
-    
-    memcpy(ctx->data + ctx->pos, buf, bufsize);
-    ctx->pos += bufsize;
-
-    if (flags & PCILIB_DMA_FLAG_EOP) {
-	if ((ctx->pos < ctx->size)&&(ctx->flags&PCILIB_DMA_FLAG_MULTIPACKET)) {
-	    if (ctx->flags&PCILIB_DMA_FLAG_WAIT) return PCILIB_STREAMING_WAIT;
-	    else return PCILIB_STREAMING_CONTINUE;
-	}
-	return PCILIB_STREAMING_STOP;
-    }
-    
-    return PCILIB_STREAMING_REQ_FRAGMENT;
-}
-
-static int pcilib_dma_skip_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
-    struct timeval *tv = (struct timeval*)arg;
-    struct timeval cur;
-    
-    if (tv) {
-	gettimeofday(&cur, NULL);
-	if ((cur.tv_sec > tv->tv_sec)||((cur.tv_sec == tv->tv_sec)&&(cur.tv_usec > tv->tv_usec))) return PCILIB_STREAMING_STOP;
-    }
-    
-    return PCILIB_STREAMING_REQ_PACKET;
-}
-
-int pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-    if (!info) {
-	pcilib_error("DMA is not supported by the device");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (!ctx->model_info.dma_api) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return PCILIB_ERROR_NOTAVAILABLE;
-    }
-    
-    if (!ctx->model_info.dma_api->stream) {
-	pcilib_error("The DMA read is not supported by configured DMA engine");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-    
-    if (!info->engines[dma]) {
-	pcilib_error("The DMA engine (%i) is not supported by device", dma);
-	return PCILIB_ERROR_NOTAVAILABLE;
-    }
-
-    if ((info->engines[dma]->direction&PCILIB_DMA_FROM_DEVICE) == 0) {
-	pcilib_error("The selected engine (%i) is S2C-only and does not support reading", dma);
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    return ctx->model_info.dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
-}
-
-int pcilib_read_dma_custom(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *read_bytes) {
-    int err; 
-
-    pcilib_dma_read_callback_context_t opts = {
-	size, buf, 0, flags
-    };
-    
-    err = pcilib_stream_dma(ctx, dma, addr, size, flags, timeout, pcilib_dma_read_callback, &opts);
-    if (read_bytes) *read_bytes = opts.pos;
-    return err;
-}
-
-int pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *read_bytes) {
-    int err; 
-
-    pcilib_dma_read_callback_context_t opts = {
-	size, buf, 0, 0
-    };
-    
-    err = pcilib_stream_dma(ctx, dma, addr, size, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_read_callback, &opts);
-    if (read_bytes) *read_bytes = opts.pos;
-    return err;
-}
-
-
-int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma) {
-    int err;
-    struct timeval tv, cur;
-
-    gettimeofday(&tv, NULL);
-    tv.tv_usec += PCILIB_DMA_SKIP_TIMEOUT;
-    tv.tv_sec += tv.tv_usec / 1000000;
-    tv.tv_usec += tv.tv_usec % 1000000;
-    
-    do {
-	    // IMMEDIATE timeout is not working properly, so default is set
-	err = pcilib_stream_dma(ctx, dma, 0, 0, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_skip_callback, &tv);
-	gettimeofday(&cur, NULL);
-    } while ((!err)&&((cur.tv_sec < tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec < tv.tv_usec))));
-
-    if ((cur.tv_sec > tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec > tv.tv_usec))) return PCILIB_ERROR_TIMEOUT;
-    
-    return 0;
-}
-
-
-int pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-    if (!info) {
-	pcilib_error("DMA is not supported by the device");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (!ctx->model_info.dma_api) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return PCILIB_ERROR_NOTAVAILABLE;
-    }
-    
-    if (!ctx->model_info.dma_api->push) {
-	pcilib_error("The DMA write is not supported by configured DMA engine");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-    
-    if (!info->engines[dma]) {
-	pcilib_error("The DMA engine (%i) is not supported by device", dma);
-	return PCILIB_ERROR_NOTAVAILABLE;
-    }
-
-    if ((info->engines[dma]->direction&PCILIB_DMA_TO_DEVICE) == 0) {
-	pcilib_error("The selected engine (%i) is C2S-only and does not support writes", dma);
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-    
-    return ctx->model_info.dma_api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written);
-}
-
-
-int pcilib_write_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *written_bytes) {
-    return pcilib_push_dma(ctx, dma, addr, size, PCILIB_DMA_FLAG_EOP|PCILIB_DMA_FLAG_WAIT, PCILIB_DMA_TIMEOUT, buf, written_bytes);
-}
-
-double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-    if (!info) {
-	pcilib_error("DMA is not supported by the device");
-	return 0;
-    }
-
-    if (!ctx->model_info.dma_api) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return -1;
-    }
-    
-    if (!ctx->model_info.dma_api->benchmark) {
-	pcilib_error("The DMA benchmark is not supported by configured DMA engine");
-	return -1;
-   }
-    
-    if (!info->engines[dma]) {
-	pcilib_error("The DMA engine (%i) is not supported by device", dma);
-	return -1;
-    }
-
-    return ctx->model_info.dma_api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
-}
-
-int pcilib_get_dma_status(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) {
-    const pcilib_dma_info_t *info =  pcilib_get_dma_info(ctx);
-    if (!info) {
-	pcilib_error("DMA is not supported by the device");
-	return 0;
-    }
-
-    if (!ctx->model_info.dma_api) {
-	pcilib_error("DMA Engine is not configured in the current model");
-	return -1;
-    }
-    
-    if (!ctx->model_info.dma_api->status) {
-	memset(status, 0, sizeof(pcilib_dma_engine_status_t));
-	return -1;
-   }
-    
-    if (!info->engines[dma]) {
-	pcilib_error("The DMA engine (%i) is not supported by device", dma);
-	return -1;
-    }
-
-    return ctx->model_info.dma_api->status(ctx->dma_ctx, dma, status, n_buffers, buffers);
-}

+ 0 - 52
dma.h

@@ -1,52 +0,0 @@
-#ifndef _PCILIB_DMA_H
-#define _PCILIB_DMA_H
-
-#define PCILIB_DMA_BUFFER_INVALID ((size_t)-1)
-#define PCILIB_DMA_MODIFICATION_DEFAULT 0		/**< first 0x100 are reserved */
-
-typedef uint32_t pcilib_dma_modification_t;
-
-typedef struct {
-    int started;
-    size_t ring_size, buffer_size;
-    size_t ring_head, ring_tail;
-} pcilib_dma_engine_status_t;
-
-typedef struct {
-    int used;
-    int error;
-    int first;
-    int last;
-    size_t size;
-} pcilib_dma_buffer_status_t;
-
-struct pcilib_dma_api_description_s {
-    const char *title;
-
-    pcilib_dma_context_t *(*init)(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg);
-    void (*free)(pcilib_dma_context_t *ctx);
-    
-    int (*status)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers);
-
-    int (*enable_irq)(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags);
-    int (*disable_irq)(pcilib_dma_context_t *ctx, pcilib_dma_flags_t flags);
-    int (*acknowledge_irq)(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source);
-
-    int (*start_dma)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-    int (*stop_dma)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-
-    int (*push)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written);
-    int (*stream)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr);
-
-    double (*benchmark)(pcilib_dma_context_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction);
-};
-
-struct pcilib_dma_context_s {
-    int ignore_eop;
-};
-
-
-int pcilib_set_dma_engine_description(pcilib_t *ctx, pcilib_dma_engine_t engine, pcilib_dma_engine_description_t *desc);
-int pcilib_get_dma_status(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers);
-
-#endif /* _PCILIB_DMA_H */

+ 0 - 9
dma/CMakeLists.txt

@@ -1,9 +0,0 @@
-include_directories(
-    ${CMAKE_SOURCE_DIR}
-)
-
-
-set(HEADERS ${HEADERS} nwl.h nwl_private.h nwl_engine.h nwl_irq.h nwl_loopback.h nwl_register.h ipe.h ipe_private.h ipe_registers.h)
-
-add_library(dma STATIC nwl.c nwl_engine.c nwl_irq.c nwl_loopback.c nwl_register.c ipe.c)
-

+ 0 - 541
dma/ipe.c

@@ -1,541 +0,0 @@
-#define _PCILIB_DMA_IPE_C
-#define _BSD_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-
-#include "pci.h"
-#include "pcilib.h"
-#include "error.h"
-#include "tools.h"
-
-#include "ipe.h"
-#include "ipe_private.h"
-#include "ipe_registers.h"
-
-
-#define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; }
-#define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); }
-
-
-pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) {
-    int err = 0;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
-
-    ipe_dma_t *ctx = malloc(sizeof(ipe_dma_t));
-
-    if (ctx) {
-	memset(ctx, 0, sizeof(ipe_dma_t));
-	ctx->pcilib = pcilib;
-//	ctx->mode64 = 1;
-	
-	memset(ctx->engine, 0, 2 * sizeof(pcilib_dma_engine_description_t));
-	ctx->engine[0].addr = 0;
-	ctx->engine[0].type = PCILIB_DMA_TYPE_PACKET;
-	ctx->engine[0].direction = PCILIB_DMA_FROM_DEVICE;
-	ctx->engine[0].addr_bits = 32;
-	pcilib_set_dma_engine_description(pcilib, 0, &ctx->engine[0]);
-	pcilib_set_dma_engine_description(pcilib, 1, NULL);
-
-	pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
-	if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
-	    free(ctx);
-	    pcilib_error("DMA Register Bank could not be found");
-	    return NULL;
-	}
-
-	ctx->dma_bank = model_info->banks + dma_bank;
-	ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
-
-	err = pcilib_add_registers(ctx->pcilib, 0, ipe_dma_registers);
-	if (err) {
-	    free(ctx);
-	    pcilib_error("Error adding DMA registers");
-	    return NULL;
-	}
-    }
-
-    return (pcilib_dma_context_t*)ctx;
-}
-
-void  dma_ipe_free(pcilib_dma_context_t *vctx) {
-    ipe_dma_t *ctx = (ipe_dma_t*)vctx;
-
-    if (ctx) {
-	dma_ipe_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT);
-	free(ctx);
-    }
-}
-
-
-int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
-    size_t i;
-
-    ipe_dma_t *ctx = (ipe_dma_t*)vctx;
-
-    int preserve = 0;
-    pcilib_kmem_flags_t kflags;
-    pcilib_kmem_reuse_state_t reuse_desc, reuse_pages;
-
-    volatile void *desc_va;
-    volatile uint32_t *last_written_addr_ptr;
-
-    pcilib_register_value_t value;
-    
-    uint32_t address64;
-    
-
-    if (dma == PCILIB_DMA_ENGINE_INVALID) return 0;
-    else if (dma > 1) return PCILIB_ERROR_INVALID_BANK;
-
-    if (!ctx->started) ctx->started = 1;
-
-    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->preserve = 1;
-
-    if (ctx->pages) return 0;
-    
-    kflags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(ctx->preserve?PCILIB_KMEM_FLAG_PERSISTENT:0);
-    pcilib_kmem_handle_t *desc = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, IPEDMA_DESCRIPTOR_SIZE, IPEDMA_DESCRIPTOR_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x00), kflags);
-    pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, IPEDMA_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags);
-
-    if (!desc||!pages) {
-	if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0);
-	if (desc) pcilib_free_kernel_memory(ctx->pcilib, desc, 0);
-	return PCILIB_ERROR_MEMORY;
-    }
-    reuse_desc = pcilib_kmem_is_reused(ctx->pcilib, desc);
-    reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages);
-
-    if (reuse_desc == reuse_pages) {
-	if (reuse_desc & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing...");
-	else if (reuse_desc & PCILIB_KMEM_REUSE_REUSED) {
-	    if ((reuse_desc & PCILIB_KMEM_REUSE_PERSISTENT) == 0) pcilib_warning("Lost DMA buffers are found (non-persistent mode), reinitializing...");
-	    else if ((reuse_desc & PCILIB_KMEM_REUSE_HARDWARE) == 0) pcilib_warning("Lost DMA buffers are found (missing HW reference), reinitializing...");
-	    else {
-#ifndef IPEDMA_BUG_DMARD
-		RD(IPEDMA_REG_PAGE_COUNT, value);
-
-		if (value != IPEDMA_DMA_PAGES) pcilib_warning("Inconsistent DMA buffers are found (Number of allocated buffers (%lu) does not match current request (%lu)), reinitializing...", value + 1, IPEDMA_DMA_PAGES);
-		else
-#endif /* IPEDMA_BUG_DMARD */
-		    preserve = 1;
-	    }
-	}
-    } else pcilib_warning("Inconsistent DMA buffers (modes of ring and page buffers does not match), reinitializing....");
-
-    desc_va = pcilib_kmem_get_ua(ctx->pcilib, desc);
-    if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t);
-    else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t);
-
-    if (preserve) {
-	ctx->reused = 1;
-	ctx->preserve = 1;
-	
-
-//	usleep(100000);
-
-	    // Detect the current state of DMA engine
-#ifdef IPEDMA_BUG_DMARD
-	FILE *f = fopen("/tmp/pcitool_lastread", "r");
-	if (!f) pcilib_error("Can't read current status");
-	fread(&value, 1, sizeof(pcilib_register_value_t), f);
-	fclose(f);
-#else /* IPEDMA_BUG_DMARD */
-	RD(IPEDMA_REG_LAST_READ, value);
-	    // Numbered from 1 in FPGA
-	value--;
-#endif /* IPEDMA_BUG_DMARD */
-
-	ctx->last_read = value;
-    } else {
-	ctx->reused = 0;
-
-	    // Disable DMA
-	WR(IPEDMA_REG_CONTROL, 0x0);
-	usleep(100000);
-	
-	    // Reset DMA engine
-	WR(IPEDMA_REG_RESET, 0x1);
-	usleep(100000);
-	WR(IPEDMA_REG_RESET, 0x0);
-	usleep(100000);
-
-#ifndef IPEDMA_BUG_DMARD
-	    // Verify PCIe link status
-	RD(IPEDMA_REG_RESET, value);
-	if (value != 0x14031700) pcilib_warning("PCIe is not ready, code is %lx", value);
-#endif /* IPEDMA_BUG_DMARD */
-
-	    // Enable 64 bit addressing and configure TLP and PACKET sizes (40 bit mode can be used with big pre-allocated buffers later)
-	if (ctx->mode64) address64 = 0x8000 | (0<<24);
-	else address64 = 0;
-	
-        WR(IPEDMA_REG_TLP_SIZE,  address64 | IPEDMA_TLP_SIZE);
-        WR(IPEDMA_REG_TLP_COUNT, IPEDMA_PAGE_SIZE / (4 * IPEDMA_TLP_SIZE * IPEDMA_CORES));
-
-	    // Setting progress register threshold
-	WR(IPEDMA_REG_UPDATE_THRESHOLD, IPEDMA_DMA_PROGRESS_THRESHOLD);
-        
-	    // Reseting configured DMA pages
-        WR(IPEDMA_REG_PAGE_COUNT, 0);
-        
-	    // Setting current read position and configuring progress register
-	WR(IPEDMA_REG_LAST_READ, IPEDMA_DMA_PAGES);
-	WR(IPEDMA_REG_UPDATE_ADDR, pcilib_kmem_get_block_ba(ctx->pcilib, desc, 0));
-
-	    // Instructing DMA engine that writting should start from the first DMA page
-	*last_written_addr_ptr = 0;//htonl(pcilib_kmem_get_block_ba(ctx->pcilib, pages, IPEDMA_DMA_PAGES - 1));
-
-	
-	for (i = 0; i < IPEDMA_DMA_PAGES; i++) {
-	    uintptr_t bus_addr_check, bus_addr = pcilib_kmem_get_block_ba(ctx->pcilib, pages, i);
-	    WR(IPEDMA_REG_PAGE_ADDR, bus_addr);
-	    if (bus_addr%4096) printf("Bad address %lu: %lx\n", i, bus_addr);
-	    
-	    RD(IPEDMA_REG_PAGE_ADDR, bus_addr_check);
-	    if (bus_addr_check != bus_addr) {
-		pcilib_error("Written (%x) and read (%x) bus addresses does not match\n", bus_addr, bus_addr_check);
-	    }
-	    
-	    usleep(1000);
-	}
-	
-	    // Enable DMA
-	WR(IPEDMA_REG_CONTROL, 0x1);
-	
-	ctx->last_read = IPEDMA_DMA_PAGES - 1;
-
-#ifdef IPEDMA_BUG_DMARD
-	FILE *f = fopen("/tmp/pcitool_lastread", "w");
-	if (!f) pcilib_error("Can't write current status");
-	value = ctx->last_read;
-	fwrite(&value, 1, sizeof(pcilib_register_value_t), f);
-	fclose(f);
-#endif /* IPEDMA_BUG_DMARD */
-    }
-
-//    ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->pcilib, pages, ctx->last_read));
-    ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->pcilib, pages, ctx->last_read);
-
-
-    ctx->desc = desc;
-    ctx->pages = pages;
-    ctx->page_size = pcilib_kmem_get_block_size(ctx->pcilib, pages, 0);;
-    ctx->ring_size = IPEDMA_DMA_PAGES;
-
-    return 0;
-}
-
-int dma_ipe_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
-    pcilib_kmem_flags_t kflags;
-
-    ipe_dma_t *ctx = (ipe_dma_t*)vctx;
-
-    if (!ctx->started) return 0;
-
-    if ((dma != PCILIB_DMA_ENGINE_INVALID)&&(dma > 1)) return PCILIB_ERROR_INVALID_BANK;
-
-	    // ignoring previous setting if flag specified
-    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
-	ctx->preserve = 0;
-    }
-
-    if (ctx->preserve) {
-	kflags = PCILIB_KMEM_FLAG_REUSE;
-    } else {
-        kflags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT;
-
-	ctx->started  = 0;
-
-	    // Disable DMA
-	WR(IPEDMA_REG_CONTROL, 0);
-	usleep(100000);
-	
-	    // Reset DMA engine
-	WR(IPEDMA_REG_RESET, 0x1);
-	usleep(100000);
-	WR(IPEDMA_REG_RESET, 0x0);
-	usleep(100000);
-
-	    // Reseting configured DMA pages
-        WR(IPEDMA_REG_PAGE_COUNT, 0);
-	usleep(100000);
-    }
-
-	// Clean buffers
-    if (ctx->desc) {
-	pcilib_free_kernel_memory(ctx->pcilib, ctx->desc, kflags);
-	ctx->desc = NULL;
-    }
-
-    if (ctx->pages) {
-	pcilib_free_kernel_memory(ctx->pcilib, ctx->pages, kflags);
-	ctx->pages = NULL;
-    }
-
-    return 0;
-}
-
-
-int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) {
-    size_t i;
-    ipe_dma_t *ctx = (ipe_dma_t*)vctx;
-
-    void *desc_va = (void*)pcilib_kmem_get_ua(ctx->pcilib, ctx->desc);
-    uint32_t *last_written_addr_ptr;
-    uint32_t last_written_addr;
-
-    if (!status) return -1;
-
-    if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t);
-    else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t);
-
-    last_written_addr = *last_written_addr_ptr;
-
-    status->started = ctx->started;
-    status->ring_size = ctx->ring_size;
-    status->buffer_size = ctx->page_size;
-
-	// For simplicity, we keep last_read here, and fix in the end
-    status->ring_tail = ctx->last_read;
-
-	// Find where the ring head is actually are
-    for (i = 0; i < ctx->ring_size; i++) {
-	uintptr_t bus_addr = pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, i);
-
-	if (bus_addr == last_written_addr) {
-	    status->ring_head = i;
-	    break;
-	}
-    }
-
-    if (i == ctx->ring_size) {
-	if (last_written_addr) {
-	    pcilib_warning("DMA is in unknown state, last_written_addr does not correspond any of available buffers");
-	    return -1;
-	}
-	status->ring_head = 0;
-	status->ring_tail = 0;
-    }
-
-    if (n_buffers > ctx->ring_size) n_buffers = ctx->ring_size;
-
-    if (buffers) {
-	memset(buffers, 0, n_buffers * sizeof(pcilib_dma_buffer_status_t));
-	if (status->ring_head >= status->ring_tail) {
-	    for (i = status->ring_tail + 1; (i <= status->ring_head)&&(i < n_buffers); i++) {
-		buffers[i].used = 1;
-		buffers[i].size = ctx->page_size;
-		buffers[i].first = 1;
-		buffers[i].last = 1;
-	    }
-	} else {
-	    for (i = 0; (i <= status->ring_head)&&(i < n_buffers); i++) {
-		buffers[i].used = 1;
-		buffers[i].size = ctx->page_size;
-		buffers[i].first = 1;
-		buffers[i].last = 1;
-	    } 
-
-	    for (i = status->ring_tail + 1; (i < status->ring_size)&&(i < n_buffers); i++) {
-		buffers[i].used = 1;
-		buffers[i].size = ctx->page_size;
-		buffers[i].first = 1;
-		buffers[i].last = 1;
-	    }
-	}
-    }
-
-	// We actually keep last_read in the ring_tail, so need to increase
-    if (status->ring_tail != status->ring_head) {
-	status->ring_tail++;
-	if (status->ring_tail == status->ring_size) status->ring_tail = 0;
-    }
-
-    return 0;
-}
-
-int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) {
-    int err, ret = PCILIB_STREAMING_REQ_PACKET;
-
-
-    pcilib_timeout_t wait = 0;
-    struct timeval start, cur;
-
-    volatile void *desc_va;
-    volatile uint32_t *last_written_addr_ptr;
-    volatile uint32_t *empty_detected_ptr;
-
-    pcilib_dma_flags_t packet_flags = PCILIB_DMA_FLAG_EOP;
-
-#ifdef IPEDMA_BUG_DMARD
-    pcilib_register_value_t value;
-#endif /* IPEDMA_BUG_DMARD */
-
-    size_t cur_read;
-
-    ipe_dma_t *ctx = (ipe_dma_t*)vctx;
-
-    err = dma_ipe_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT);
-    if (err) return err;
-
-    desc_va = (void*)pcilib_kmem_get_ua(ctx->pcilib, ctx->desc);
-
-    if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t);
-    else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t);
-
-    empty_detected_ptr = last_written_addr_ptr - 2;
-
-    do {
-	switch (ret&PCILIB_STREAMING_TIMEOUT_MASK) {
-	    case PCILIB_STREAMING_CONTINUE: 
-		    // Hardware indicates that there is no more data pending and we can safely stop if there is no data in the kernel buffers already
-#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED
-		if (*empty_detected_ptr)
-		    wait = 0;
-		else
-#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */
-		    wait = IPEDMA_DMA_TIMEOUT; 
-	    break;
-	    case PCILIB_STREAMING_WAIT: 
-		wait = (timeout > IPEDMA_DMA_TIMEOUT)?timeout:IPEDMA_DMA_TIMEOUT;
-	    break;
-//	    case PCILIB_STREAMING_CHECK: wait = 0; break;
-	}
-
-#ifdef IPEDMA_DEBUG
-	printf("Waiting for data: %u (last read) 0x%x (last read addr) 0x%x (last_written)\n", ctx->last_read, ctx->last_read_addr, *last_written_addr_ptr);
-#endif /* IPEDMA_DEBUG */
-
-	gettimeofday(&start, NULL);
-	memcpy(&cur, &start, sizeof(struct timeval));
-	while (((*last_written_addr_ptr == 0)||(ctx->last_read_addr == (*last_written_addr_ptr)))&&((wait == PCILIB_TIMEOUT_INFINITE)||(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < wait))) {
-	    usleep(10);
-#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED
-	    if ((ret != PCILIB_STREAMING_REQ_PACKET)&&(*empty_detected_ptr)) break;
-#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */
-	    gettimeofday(&cur, NULL);
-	}
-	
-	    // Failing out if we exited on timeout
-	if ((ctx->last_read_addr == (*last_written_addr_ptr))||(*last_written_addr_ptr == 0)) {
-#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED
-# ifdef IPEDMA_DEBUG
-	    if ((wait)&&(*last_written_addr_ptr)&&(!*empty_detected_ptr))
-		pcilib_warning("The empty_detected flag is not set, but no data arrived within %lu us\n", wait);
-# endif /* IPEDMA_DEBUG */
-#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */
-	    return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0;
-	}
-
-	    // Getting next page to read
-	cur_read = ctx->last_read + 1;
-	if (cur_read == ctx->ring_size) cur_read = 0;
-
-#ifdef IPEDMA_DEBUG
-	printf("Reading: %u (last read) 0x%x (last read addr) 0x%x (last_written)\n", cur_read, ctx->last_read_addr, *last_written_addr_ptr);
-#endif /* IPEDMA_DEBUG */
-
-#ifdef IPEDMA_DETECT_PACKETS
-	if ((*empty_detected_ptr)&&(pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read) == (*last_written_addr_ptr))) packet_flags = PCILIB_DMA_FLAG_EOP;
-	else packet_flags = 0;
-#endif /* IPEDMA_DETECT_PACKETS */
-	
-	pcilib_kmem_sync_block(ctx->pcilib, ctx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, cur_read);
-        void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, ctx->pages, cur_read);
-	ret = cb(cbattr, packet_flags, ctx->page_size, buf);
-	if (ret < 0) return -ret;
-	
-//	DS: Fixme, it looks like we can avoid calling this for the sake of performance
-//	pcilib_kmem_sync_block(ctx->pcilib, ctx->pages, PCILIB_KMEM_SYNC_TODEVICE, cur_read);
-
-	    // Numbered from 1
-	WR(IPEDMA_REG_LAST_READ, cur_read + 1);
-
-	ctx->last_read = cur_read;
-//	ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read));
-	ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read);
-
-#ifdef IPEDMA_BUG_DMARD
-	FILE *f = fopen("/tmp/pcitool_lastread", "w");
-	if (!f) pcilib_error("Can't write current status");
-	value = cur_read;
-	fwrite(&value, 1, sizeof(pcilib_register_value_t), f);
-	fclose(f);
-#endif /* IPEDMA_BUG_DMARD */
-
-    } while (ret);
-
-    return 0;
-}
-
-double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) {
-    int err = 0;
-
-    ipe_dma_t *ctx = (ipe_dma_t*)vctx;
-
-    int iter;
-    size_t us = 0;
-    struct timeval start, cur;
-    
-    void *buf;
-    size_t bytes, rbytes;
-
-    if ((direction == PCILIB_DMA_TO_DEVICE)||(direction == PCILIB_DMA_BIDIRECTIONAL)) return -1.;
-
-    if ((dma != PCILIB_DMA_ENGINE_INVALID)&&(dma > 1)) return -1.;
-
-    err = dma_ipe_start(vctx, 0, PCILIB_DMA_FLAGS_DEFAULT);
-    if (err) return err;
-
-    WR(IPEDMA_REG_CONTROL, 0x0);
-
-    err = pcilib_skip_dma(ctx->pcilib, 0);
-    if (err) {
-	pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine");
-	return -1;
-    }
-
-    if (size%IPEDMA_PAGE_SIZE) size = (1 + size / IPEDMA_PAGE_SIZE) * IPEDMA_PAGE_SIZE;
-
-	// Allocate memory and prepare data
-    buf = malloc(size);
-    if (!buf) return -1;
-
-    for (iter = 0; iter < iterations; iter++) {
-	gettimeofday(&start, NULL);
-
-	    // Starting DMA
-	WR(IPEDMA_REG_CONTROL, 0x1);
-	
-	for (bytes = 0; bytes < size; bytes += rbytes) {
-	    err = pcilib_read_dma(ctx->pcilib, 0, addr, size - bytes, buf + bytes, &rbytes);
-	    if (err) {
-		pcilib_error("Can't read data from DMA, error %i", err);
-	        return -1;
-	    }
-	}
-
-	    // Stopping DMA
-	WR(IPEDMA_REG_CONTROL, 0x0);
-	if (err) break;
-	
-	gettimeofday(&cur, NULL);
-	us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));
-	    
-	err = pcilib_skip_dma(ctx->pcilib, 0);
-	if (err) {
-	    pcilib_error("Can't start iteration, devices continuously writes unexpected data using DMA engine");
-	    break;
-	}
-    }
-
-    free(buf);
-
-    return err?-1:((1. * size * iterations * 1000000) / (1024. * 1024. * us));
-}

+ 0 - 42
dma/ipe.h

@@ -1,42 +0,0 @@
-#ifndef _PCILIB_DMA_IPE_H
-#define _PCILIB_DMA_IPE_H
-
-#include <stdio.h>
-#include "../pcilib.h"
-
-//#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100
-
-pcilib_dma_context_t *dma_ipe_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg);
-void  dma_ipe_free(pcilib_dma_context_t *vctx);
-
-int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers);
-
-
-int dma_ipe_start(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-int dma_ipe_stop(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-
-int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr);
-double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction);
-
-
-#ifdef _PCILIB_DMA_IPE_C
-pcilib_dma_api_description_t ipe_dma_api = {
-    "ipe_dma",
-    dma_ipe_init,
-    dma_ipe_free,
-    dma_ipe_get_status,
-    NULL,
-    NULL,
-    NULL,
-    dma_ipe_start,
-    dma_ipe_stop,
-    NULL,
-    dma_ipe_stream_read,
-    dma_ipe_benchmark
-};
-#else
-extern pcilib_dma_api_description_t ipe_dma_api;
-#endif
-
-
-#endif /* _PCILIB_DMA_IPE_H */

+ 0 - 59
dma/ipe_private.h

@@ -1,59 +0,0 @@
-#ifndef _PCILIB_DMA_IPE_PRIVATE_H
-#define _PCILIB_DMA_IPE_PRIVATE_H
-
-#define IPEDMA_CORES			1
-#define IPEDMA_TLP_SIZE			32
-#define IPEDMA_PAGE_SIZE		4096
-#define IPEDMA_DMA_PAGES		16		/**< number of DMA pages in the ring buffer to allocate */
-#define IPEDMA_DMA_PROGRESS_THRESHOLD	1		/**< how many pages the DMA engine should fill before reporting progress */
-#define IPEDMA_DESCRIPTOR_SIZE		128
-#define IPEDMA_DESCRIPTOR_ALIGNMENT	64
-
-//#define IPEDMA_DEBUG
-//#define IPEDMA_BUG_DMARD				/**< No register read during DMA transfer */
-//#define IPEDMA_DETECT_PACKETS				/**< Using empty_deceted flag */
-#define  IPEDMA_SUPPORT_EMPTY_DETECTED			/**< Avoid waiting for data when empty_detected flag is set in hardware */
-#define IPEDMA_DMA_TIMEOUT 100000			/**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */
-
-#define IPEDMA_REG_RESET		0x00
-#define IPEDMA_REG_CONTROL		0x04
-#define IPEDMA_REG_TLP_SIZE		0x0C
-#define IPEDMA_REG_TLP_COUNT		0x10
-#define IPEDMA_REG_PAGE_ADDR		0x50
-#define IPEDMA_REG_UPDATE_ADDR		0x54
-#define IPEDMA_REG_LAST_READ		0x58
-#define IPEDMA_REG_PAGE_COUNT		0x5C
-#define IPEDMA_REG_UPDATE_THRESHOLD	0x60
-
-
-
-typedef struct ipe_dma_s ipe_dma_t;
-
-struct ipe_dma_s {
-    struct pcilib_dma_context_s dmactx;
-    pcilib_dma_engine_description_t engine[2];
-
-    pcilib_t *pcilib;
-    
-    pcilib_register_bank_description_t *dma_bank;
-    char *base_addr;
-
-    pcilib_irq_type_t irq_enabled;	/**< indicates that IRQs are enabled */
-    pcilib_irq_type_t irq_preserve;	/**< indicates that IRQs should not be disabled during clean-up */
-    int irq_started;			/**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */    
-
-    int started;			/**< indicates that DMA buffers are initialized and reading is allowed */
-    int writting;			/**< indicates that we are in middle of writting packet */
-    int reused;				/**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */
-    int preserve;			/**< indicates that DMA should not be stopped during clean-up */
-    int mode64;				/**< indicates 64-bit operation mode */
-
-    pcilib_kmem_handle_t *desc;		/**< in-memory status descriptor written by DMA engine upon operation progess */
-    pcilib_kmem_handle_t *pages;	/**< collection of memory-locked pages for DMA operation */
-
-    size_t ring_size, page_size;
-    size_t last_read, last_read_addr, last_written;
-
-};
-
-#endif /* _PCILIB_DMA_IPE_PRIVATE_H */

+ 0 - 44
dma/ipe_registers.h

@@ -1,44 +0,0 @@
-#ifndef _PCILIB_DMA_IPE_REGISTERS_H
-#define _PCILIB_DMA_IPE_REGISTERS_H 
-
-#ifdef _PCILIB_DMA_IPE_C 
-static pcilib_register_description_t ipe_dma_registers[] = {
-    {0x0000, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dcr",  			"Device Control Status Register"},
-    {0x0000, 	0, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "reset_dma",  			""},
-    {0x0000, 	16, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "datapath_width",			""},
-    {0x0000, 	24, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "fpga_family",			""},
-    {0x0004, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "ddmacr",  			"Device DMA Control Status Register"},
-    {0x0004, 	0, 	1, 	0, 	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_start",  			"Start writting memory"},
-    {0x0004, 	5, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_relxed_order",  		""},
-    {0x0004, 	6, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_nosnoop",  			""},
-    {0x0004, 	7, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_int_dis",  			""},
-    {0x0004, 	16, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_start",  			""},
-    {0x0004, 	21, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_relaxed_order",  		""},
-    {0x0004, 	22, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_nosnoop",  			""},
-    {0x0004, 	23, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_int_dis",  			""},
-    {0x000C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_size",  			"DMA TLP size"},
-    {0x000C, 	0, 	16, 	0x20, 	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_len",  			"Max TLP size"},
-    {0x000C, 	16, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_tlp_tc",  			"TC for TLP packets"},
-    {0x000C, 	19, 	1, 	0, 	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_64b_en",  			"Enable 64 bit memory addressing"},
-    {0x000C, 	20, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_phant_func_dis",		"Disable MWR phantom function"},
-    {0x000C, 	24, 	8, 	0, 	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_up_addr",  			"Upper address for 64 bit memory addressing"},
-    {0x0010, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_count",  		"Write DMA TLP Count"},
-    {0x0014, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_pattern",  		"DMA generator data pattern"},
-    {0x0028, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_perf",			"MWR Performance"},
-    {0x003C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_lnk_width",		"Negotiated and max width of PCIe Link"},
-    {0x003C, 	0, 	6, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_lnk_width", 		"Max link width"},
-    {0x003C, 	8, 	6, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_lnk_width", 		"Negotiated link width"},
-    {0x0040, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_payload_size",  		""},
-    {0x0040, 	0, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_payload_size",	"Max payload size"},
-    {0x0040, 	8, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_payload_size",	"Prog max payload size"},
-    {0x0040, 	16, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_max_rd_req_size",		"Max read request size"},
-    {0x0050, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din",  		"Descriptor memory"},
-    {0x0054, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr",  		"Address of progress register"},
-    {0x0058, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "last_descriptor_read",	"Last descriptor read by the host"},
-    {0x005C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", 		"Number of descriptors configured"},
-    {0x0060, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_thresh",  		"Update threshold of progress register"},
-    {0,		0,	0,	0,	0x00000000,	0,                                           0,                        0, NULL, 			NULL}
-};
-#endif /* _PCILIB_DMA_IPE_C */
-
-#endif /* _PCILIB_DMA_IPE_REGISTERS_H */

+ 0 - 139
dma/nwl.c

@@ -1,139 +0,0 @@
-#define _PCILIB_DMA_NWL_C
-#define _BSD_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "pci.h"
-#include "pcilib.h"
-#include "error.h"
-#include "tools.h"
-#include "nwl_private.h"
-
-#include "nwl_defines.h"
-
-int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
-    int err;
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-
-    if (!ctx->started) {
-	// global initialization, should we do anything?
-	ctx->started = 1;
-    }
-
-    if (dma == PCILIB_DMA_ENGINE_INVALID) return 0;
-    else if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK;
-
-    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->engines[dma].preserve = 1;
-
-    err = dma_nwl_start_engine(ctx, dma);
-    
-    return err;
-}
-
-int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
-    int err;
-    int preserving = 0;
-
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-    
-    if (!ctx->started) return 0;
-    
-	// stop everything
-    if (dma == PCILIB_DMA_ENGINE_INVALID) {
-        for (dma = 0; dma < ctx->n_engines; dma++) {
-	    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
-		ctx->engines[dma].preserve = 0;
-	    }
-	
-	    if (ctx->engines[dma].preserve) preserving = 1;
-	    
-	    err = dma_nwl_stop_engine(ctx, dma);
-	    if (err) return err;
-	}
-	    
-	    // global cleanup, should we do anything?
-	if (!preserving) {
-	    ctx->started = 0;
-	}
-	
-	return 0;
-    }
-    
-    if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK;
-    
-	    // ignorign previous setting if flag specified
-    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
-	ctx->engines[dma].preserve = 0;
-    }
-    
-    return dma_nwl_stop_engine(ctx, dma);
-}
-
-
-pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) {
-    int i;
-    int err;
-    pcilib_dma_engine_t n_engines;
-
-    pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
-    
-    nwl_dma_t *ctx = malloc(sizeof(nwl_dma_t));
-    if (ctx) {
-	memset(ctx, 0, sizeof(nwl_dma_t));
-	ctx->pcilib = pcilib;
-	ctx->type = type;
-
-	if (type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
-	    ctx->dmactx.ignore_eop = 1;
-	}
-
-	pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
-	if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
-	    free(ctx);
-	    pcilib_error("DMA Register Bank could not be found");
-	    return NULL;
-	}
-	
-	ctx->dma_bank = model_info->banks + dma_bank;
-	ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
-
-	for (i = 0, n_engines = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) {
-	    char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE;
-
-	    memset(ctx->engines + n_engines, 0, sizeof(pcilib_nwl_engine_description_t));
-
-	    err = dma_nwl_read_engine_config(ctx, ctx->engines + n_engines, addr);
-	    if (err) continue;
-	    
-	    pcilib_set_dma_engine_description(pcilib, n_engines, (pcilib_dma_engine_description_t*)(ctx->engines + n_engines));
-	    ++n_engines;
-	}
-	pcilib_set_dma_engine_description(pcilib, n_engines, NULL);
-	
-	ctx->n_engines = n_engines;
-	
-	err = nwl_add_registers(ctx);
-	if (err) {
-	    free(ctx);
-	    pcilib_error("Failed to add DMA registers");
-	    return NULL;
-	}
-    }
-    return (pcilib_dma_context_t*)ctx;
-}
-
-void  dma_nwl_free(pcilib_dma_context_t *vctx) {
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-
-    if (ctx) {
-	if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
-	dma_nwl_free_irq(ctx);
-	dma_nwl_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT);
-	    
-	free(ctx);
-    }
-}

+ 0 - 46
dma/nwl.h

@@ -1,46 +0,0 @@
-#ifndef _PCILIB_DMA_NWL_H
-#define _PCILIB_DMA_NWL_H
-
-#include <stdio.h>
-#include "../pcilib.h"
-
-#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100
-
-pcilib_dma_context_t *dma_nwl_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg);
-void  dma_nwl_free(pcilib_dma_context_t *vctx);
-
-int dma_nwl_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers);
-
-int dma_nwl_enable_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t type, pcilib_dma_flags_t flags);
-int dma_nwl_disable_irq(pcilib_dma_context_t *vctx, pcilib_dma_flags_t flags);
-int dma_nwl_acknowledge_irq(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source);
-
-int dma_nwl_start(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-int dma_nwl_stop(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-
-int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *data, size_t *written);
-int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr);
-double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction);
-
-
-#ifdef _PCILIB_DMA_NWL_C
-pcilib_dma_api_description_t nwl_dma_api = {
-    "nwl_dma",
-    dma_nwl_init,
-    dma_nwl_free,
-    dma_nwl_get_status,
-    dma_nwl_enable_irq,
-    dma_nwl_disable_irq,
-    dma_nwl_acknowledge_irq,
-    dma_nwl_start,
-    dma_nwl_stop,
-    dma_nwl_write_fragment,
-    dma_nwl_stream_read,
-    dma_nwl_benchmark
-};
-#else
-extern pcilib_dma_api_description_t nwl_dma_api;
-#endif
-
-
-#endif /* _PCILIB_DMA_NWL_H */

+ 0 - 145
dma/nwl_defines.h

@@ -1,145 +0,0 @@
-/** @name Buffer Descriptor offsets
- *  USR fields are defined by higher level IP. For example, checksum offload
- *  setup for EMAC type devices. The 1st 8 words are utilized by hardware. Any
- *  words after the 8th are for software use only.
- *  @{
- */
-#define DMA_BD_BUFL_STATUS_OFFSET   0x00 /**< Buffer length + status */
-#define DMA_BD_USRL_OFFSET          0x04 /**< User logic specific - LSBytes */
-#define DMA_BD_USRH_OFFSET          0x08 /**< User logic specific - MSBytes */
-#define DMA_BD_CARDA_OFFSET         0x0C /**< Card address */
-#define DMA_BD_BUFL_CTRL_OFFSET     0x10 /**< Buffer length + control */
-#define DMA_BD_BUFAL_OFFSET         0x14 /**< Buffer address LSBytes */
-#define DMA_BD_BUFAH_OFFSET         0x18 /**< Buffer address MSBytes */
-#define DMA_BD_NDESC_OFFSET         0x1C /**< Next descriptor pointer */
-
-/* Bit masks for some BD fields */
-#define DMA_BD_BUFL_MASK            0x000FFFFF /**< Byte count */
-#define DMA_BD_STATUS_MASK          0xFF000000 /**< Status Flags */
-#define DMA_BD_CTRL_MASK            0xFF000000 /**< Control Flags */
-
-/* Bit masks for BD control field */
-#define DMA_BD_INT_ERROR_MASK       0x02000000 /**< Intr on error */
-#define DMA_BD_INT_COMP_MASK        0x01000000 /**< Intr on BD completion */
-
-/* Bit masks for BD status field */
-#define DMA_BD_SOP_MASK             0x80000000 /**< Start of packet */
-#define DMA_BD_EOP_MASK             0x40000000 /**< End of packet */
-#define DMA_BD_ERROR_MASK           0x10000000 /**< BD had error */
-#define DMA_BD_USER_HIGH_ZERO_MASK  0x08000000 /**< User High Status zero */
-#define DMA_BD_USER_LOW_ZERO_MASK   0x04000000 /**< User Low Status zero */
-#define DMA_BD_SHORT_MASK           0x02000000 /**< BD not fully used */
-#define DMA_BD_COMP_MASK            0x01000000 /**< BD completed */
-
-
-
-#define DMA_BD_MINIMUM_ALIGNMENT    0x40  /**< Minimum byte alignment */
-
-/* Common DMA registers */
-#define REG_DMA_CTRL_STATUS     0x4000      /**< DMA Common Ctrl & Status */
-
-/* These engine registers are applicable to both S2C and C2S channels. 
- * Register field mask and shift definitions are later in this file.
- */
-
-#define REG_DMA_ENG_CAP         0x00000000  /**< DMA Engine Capabilities */
-#define REG_DMA_ENG_CTRL_STATUS 0x00000004  /**< DMA Engine Control */
-#define REG_DMA_ENG_NEXT_BD     0x00000008  /**< HW Next desc pointer */
-#define REG_SW_NEXT_BD          0x0000000C  /**< SW Next desc pointer */
-#define REG_DMA_ENG_LAST_BD     0x00000010  /**< HW Last completed pointer */
-#define REG_DMA_ENG_ACTIVE_TIME 0x00000014  /**< DMA Engine Active Time */
-#define REG_DMA_ENG_WAIT_TIME   0x00000018  /**< DMA Engine Wait Time */
-#define REG_DMA_ENG_COMP_BYTES  0x0000001C  /**< DMA Engine Completed Bytes */
-
-/* Register masks. The following constants define bit locations of various
- * control bits in the registers. For further information on the meaning of 
- * the various bit masks, refer to the hardware spec.
- *
- * Masks have been written assuming HW bits 0-31 correspond to SW bits 0-31 
- */
-
-/** @name Bitmasks of REG_DMA_CTRL_STATUS register.
- * @{
- */
-#define DMA_INT_ENABLE              0x00000001  /**< Enable global interrupts */
-#define DMA_INT_DISABLE             0x00000000  /**< Disable interrupts */
-#define DMA_INT_ACTIVE_MASK         0x00000002  /**< Interrupt active? */
-#define DMA_INT_PENDING_MASK        0x00000004  /**< Engine interrupt pending */
-#define DMA_INT_MSI_MODE            0x00000008  /**< MSI or Legacy mode? */
-#define DMA_USER_INT_ENABLE         0x00000010  /**< Enable user interrupts */
-#define DMA_USER_INT_ACTIVE_MASK    0x00000020  /**< Int - user interrupt */
-#define DMA_USER_INT_ACK            0x00000020  /**< Acknowledge */
-#define DMA_MPS_USED                0x00000700  /**< MPS Used */
-#define DMA_MRRS_USED               0x00007000  /**< MRRS Used */
-#define DMA_S2C_ENG_INT_VAL         0x00FF0000  /**< IRQ value of 1st 8 S2Cs */
-#define DMA_C2S_ENG_INT_VAL         0xFF000000  /**< IRQ value of 1st 8 C2Ss */
-
-/** @name Bitmasks of REG_DMA_ENG_CAP register.
- * @{
- */
-/* DMA engine characteristics */
-#define DMA_ENG_PRESENT_MASK    0x00000001  /**< DMA engine present? */
-#define DMA_ENG_DIRECTION_MASK  0x00000002  /**< DMA engine direction */
-#define DMA_ENG_C2S             0x00000002  /**< DMA engine - C2S */
-#define DMA_ENG_S2C             0x00000000  /**< DMA engine - S2C */
-#define DMA_ENG_TYPE_MASK       0x00000030  /**< DMA engine type */
-#define DMA_ENG_BLOCK           0x00000000  /**< DMA engine - Block type */
-#define DMA_ENG_PACKET          0x00000010  /**< DMA engine - Packet type */
-#define DMA_ENG_NUMBER          0x0000FF00  /**< DMA engine number */
-#define DMA_ENG_BD_MAX_BC       0x3F000000  /**< DMA engine max buffer size */
-
-
-/* Shift constants for selected masks */
-#define DMA_ENG_NUMBER_SHIFT        8
-#define DMA_ENG_BD_MAX_BC_SHIFT     24
-
-/** @name Bitmasks of REG_DMA_ENG_CTRL_STATUS register.
- * @{
- */
-/* Interrupt activity and acknowledgement bits */
-#define DMA_ENG_INT_ENABLE          0x00000001  /**< Enable interrupts */
-#define DMA_ENG_INT_DISABLE         0x00000000  /**< Disable interrupts */
-#define DMA_ENG_INT_ACTIVE_MASK     0x00000002  /**< Interrupt active? */
-#define DMA_ENG_INT_ACK             0x00000002  /**< Interrupt ack */
-#define DMA_ENG_INT_BDCOMP          0x00000004  /**< Int - BD completion */
-#define DMA_ENG_INT_BDCOMP_ACK      0x00000004  /**< Acknowledge */
-#define DMA_ENG_INT_ALERR           0x00000008  /**< Int - BD align error */
-#define DMA_ENG_INT_ALERR_ACK       0x00000008  /**< Acknowledge */
-#define DMA_ENG_INT_FETERR          0x00000010  /**< Int - BD fetch error */
-#define DMA_ENG_INT_FETERR_ACK      0x00000010  /**< Acknowledge */
-#define DMA_ENG_INT_ABORTERR        0x00000020  /**< Int - DMA abort error */
-#define DMA_ENG_INT_ABORTERR_ACK    0x00000020  /**< Acknowledge */
-#define DMA_ENG_INT_CHAINEND        0x00000080  /**< Int - BD chain ended */
-#define DMA_ENG_INT_CHAINEND_ACK    0x00000080  /**< Acknowledge */
-
-/* DMA engine control */
-#define DMA_ENG_ENABLE_MASK         0x00000100  /**< DMA enabled? */
-#define DMA_ENG_ENABLE              0x00000100  /**< Enable DMA */
-#define DMA_ENG_DISABLE             0x00000000  /**< Disable DMA */
-#define DMA_ENG_STATE_MASK          0x00000C00  /**< Current DMA state? */
-#define DMA_ENG_RUNNING             0x00000400  /**< DMA running */
-#define DMA_ENG_IDLE                0x00000000  /**< DMA idle */
-#define DMA_ENG_WAITING             0x00000800  /**< DMA waiting */
-#define DMA_ENG_STATE_WAITED        0x00001000  /**< DMA waited earlier */
-#define DMA_ENG_WAITED_ACK          0x00001000  /**< Acknowledge */
-#define DMA_ENG_USER_RESET          0x00004000  /**< Reset only user logic */
-#define DMA_ENG_RESET               0x00008000  /**< Reset DMA engine + user */
-
-#define DMA_ENG_ALLINT_MASK         0x000000BE  /**< To get only int events */
-
-#define DMA_ENGINE_PER_SIZE     0x100   /**< Separation between engine regs */
-#define DMA_OFFSET              0       /**< Starting register offset */
-                                        /**< Size of DMA engine reg space */
-#define DMA_SIZE                (MAX_DMA_ENGINES * DMA_ENGINE_PER_SIZE)
-
-
-#define TX_CONFIG_ADDRESS   0x9108  /* Reg for controlling TX data */
-#define RX_CONFIG_ADDRESS   0x9100  /* Reg for controlling RX pkt generator */
-#define PKT_SIZE_ADDRESS    0x9104  /* Reg for programming packet size */
-#define STATUS_ADDRESS      0x910C  /* Reg for checking TX pkt checker status */
-
-/* Test start / stop conditions */
-#define PKTCHKR             0x00000001  /* Enable TX packet checker */
-#define PKTGENR             0x00000001  /* Enable RX packet generator */
-#define CHKR_MISMATCH       0x00000001  /* TX checker reported data mismatch */
-#define LOOPBACK            0x00000002  /* Enable TX data loopback onto RX */

+ 0 - 318
dma/nwl_engine.c

@@ -1,318 +0,0 @@
-#define _BSD_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "pci.h"
-#include "pcilib.h"
-#include "error.h"
-#include "tools.h"
-#include "nwl_private.h"
-
-#include "nwl_defines.h"
-
-#include "nwl_engine_buffers.h"
-
-int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base) {
-    uint32_t val;
-    
-    info->base_addr = base;
-    
-    nwl_read_register(val, ctx, base, REG_DMA_ENG_CAP);
-
-    if ((val & DMA_ENG_PRESENT_MASK) == 0) return PCILIB_ERROR_NOTAVAILABLE;
-    
-    info->desc.addr = (val & DMA_ENG_NUMBER) >> DMA_ENG_NUMBER_SHIFT;
-    if ((info->desc.addr > PCILIB_MAX_DMA_ENGINES)||(info->desc.addr < 0)) return PCILIB_ERROR_INVALID_DATA;
-    
-    switch (val & DMA_ENG_DIRECTION_MASK) {
-	case  DMA_ENG_C2S:
-	    info->desc.direction = PCILIB_DMA_FROM_DEVICE;
-	break;
-	default:
-	    info->desc.direction = PCILIB_DMA_TO_DEVICE;
-    }
-    
-    switch (val & DMA_ENG_TYPE_MASK) {
-	case DMA_ENG_BLOCK:
-	    info->desc.type = PCILIB_DMA_TYPE_BLOCK;
-	break;
-	case DMA_ENG_PACKET:
-	    info->desc.type = PCILIB_DMA_TYPE_PACKET;
-	break;
-	default:
-	    info->desc.type = PCILIB_DMA_TYPE_UNKNOWN;
-    }
-    
-    info->desc.addr_bits = (val & DMA_ENG_BD_MAX_BC) >> DMA_ENG_BD_MAX_BC_SHIFT;
-
-    info->base_addr = base;
-    
-    return 0;
-}
-
-int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
-    int err;
-    uint32_t val;
-    uint32_t ring_pa;
-    struct timeval start, cur;
-
-    pcilib_nwl_engine_description_t *info = ctx->engines + dma;
-    char *base = ctx->engines[dma].base_addr;
-    
-    if (info->started) return 0;
-
-
-	// This will only successed if there are no parallel access to DMA engine
-    err = dma_nwl_allocate_engine_buffers(ctx, info);
-    if (err) {
-	info->started = 1;
-	dma_nwl_stop_engine(ctx, dma);
-	return err;
-    }
-    
-    if (info->reused) {
-    	info->preserve = 1;
-
-	dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma);
-
-#ifdef NWL_GENERATE_DMA_IRQ
-	dma_nwl_enable_engine_irq(ctx, dma);
-#endif /* NWL_GENERATE_DMA_IRQ */
-    } else {
-	// Disable IRQs
-	err = dma_nwl_disable_engine_irq(ctx, dma);
-	if (err) {
-	    info->started = 1;
-	    dma_nwl_stop_engine(ctx, dma);
-	    return err;
-	}
-
-	// Disable Engine & Reseting 
-	val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET;
-	nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
-
-	gettimeofday(&start, NULL);
-	do {
-	    nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
-    	    gettimeofday(&cur, NULL);
-	} while ((val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT));
-    
-	if (val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET)) {
-	    pcilib_error("Timeout during reset of DMA engine %i", info->desc.addr);
-
-	    info->started = 1;
-	    dma_nwl_stop_engine(ctx, dma);
-	    return PCILIB_ERROR_TIMEOUT;
-	}
-
-	val = DMA_ENG_RESET; 
-	nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
-    
-	gettimeofday(&start, NULL);
-	do {
-	    nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
-    	    gettimeofday(&cur, NULL);
-	} while ((val & DMA_ENG_RESET)&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT));
-    
-	if (val & DMA_ENG_RESET) {
-	    pcilib_error("Timeout during reset of DMA engine %i", info->desc.addr);
-
-	    info->started = 1;
-	    dma_nwl_stop_engine(ctx, dma);
-	    return PCILIB_ERROR_TIMEOUT;
-	}
-    
-    	dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma);
-
-	ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
-	nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
-	nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
-
-	__sync_synchronize();
-
-	nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
-	val |= (DMA_ENG_ENABLE);
-	nwl_write_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
-
-	__sync_synchronize();
-
-#ifdef NWL_GENERATE_DMA_IRQ
-	dma_nwl_enable_engine_irq(ctx, dma);
-#endif /* NWL_GENERATE_DMA_IRQ */
-
-	if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) {
-	    ring_pa += (info->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    	    nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
-
-	    info->tail = 0;
-	    info->head = (info->ring_size - 1);
-	} else {
-	    info->tail = 0;
-	    info->head = 0;
-	}
-    }
-    
-    info->started = 1;
-    
-    return 0;
-}
-
-
-int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
-    int err;
-    uint32_t val;
-    uint32_t ring_pa;
-    struct timeval start, cur;
-    pcilib_kmem_flags_t flags;
-    
-    
-    pcilib_nwl_engine_description_t *info = ctx->engines + dma;
-    char *base = ctx->engines[dma].base_addr;
-
-    if (!info->started) return 0;
-    
-    info->started = 0;
-
-    err = dma_nwl_disable_engine_irq(ctx, dma);
-    if (err) return err;
-
-    if (!info->preserve) {
-	    // Stopping DMA is not enough reset is required
-	val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET|DMA_ENG_RESET;
-	nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
-
-	gettimeofday(&start, NULL);
-	do {
-	    nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
-    	    gettimeofday(&cur, NULL);
-	} while ((val & (DMA_ENG_RUNNING))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT));
-
-	if (info->ring) {
-	    ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
-	    nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
-	    nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
-	}
-    }
-    
-    dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma);
-
-    if (info->preserve) {
-	flags = PCILIB_KMEM_FLAG_REUSE;
-    } else {
-        flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT;
-    }
-    
-	// Clean buffers
-    if (info->ring) {
-	pcilib_free_kernel_memory(ctx->pcilib, info->ring, flags);
-	info->ring = NULL;
-    }
-
-    if (info->pages) {
-	pcilib_free_kernel_memory(ctx->pcilib, info->pages, flags);
-	info->pages = NULL;
-    }
-
-    return 0;
-}
-
-int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *data, size_t *written) {
-    int err;
-    size_t pos;
-    size_t bufnum;
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-
-    pcilib_nwl_engine_description_t *info = ctx->engines + dma;
-
-    err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT);
-    if (err) return err;
-
-    if (data) {
-	for (pos = 0; pos < size; pos += info->page_size) {
-	    int block_size = min2(size - pos, info->page_size);
-	    
-    	    bufnum = dma_nwl_get_next_buffer(ctx, info, 1, timeout);
-	    if (bufnum == PCILIB_DMA_BUFFER_INVALID) {
-		if (written) *written = pos;
-		return PCILIB_ERROR_TIMEOUT;
-	    }
-	
-    	    void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, info->pages, bufnum);
-
-	    pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum);
-	    memcpy(buf, data, block_size);
-	    pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum);
-
-	    err = dma_nwl_push_buffer(ctx, info, block_size, (flags&PCILIB_DMA_FLAG_EOP)&&((pos + block_size) == size), timeout);
-	    if (err) {
-		if (written) *written = pos;
-		return err;
-	    }
-	}    
-    }
-    
-    if (written) *written = size;
-    
-    if (flags&PCILIB_DMA_FLAG_WAIT) {
-	bufnum =  dma_nwl_get_next_buffer(ctx, info, PCILIB_NWL_DMA_PAGES - 1, timeout);
-	if (bufnum == PCILIB_DMA_BUFFER_INVALID) return PCILIB_ERROR_TIMEOUT;
-    }
-    
-    return 0;
-}
-
-int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) {
-    int err, ret = PCILIB_STREAMING_REQ_PACKET;
-    pcilib_timeout_t wait = 0;
-    size_t res = 0;
-    size_t bufnum;
-    size_t bufsize;
-    
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-
-    int eop;
-
-    pcilib_nwl_engine_description_t *info = ctx->engines + dma;
-
-    err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT);
-    if (err) return err;
-    
-    do {
-	switch (ret&PCILIB_STREAMING_TIMEOUT_MASK) {
-	    case PCILIB_STREAMING_CONTINUE: wait = PCILIB_DMA_TIMEOUT; break;
-	    case PCILIB_STREAMING_WAIT: wait = timeout; break;
-//	    case PCILIB_STREAMING_CHECK: wait = 0; break;
-	}
-    
-        bufnum = dma_nwl_wait_buffer(ctx, info, &bufsize, &eop, wait);
-        if (bufnum == PCILIB_DMA_BUFFER_INVALID) {
-	    return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0;
-	}
-
-	    // EOP is not respected in IPE Camera
-	if (ctx->dmactx.ignore_eop) eop = 1;
-	
-	pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum);
-        void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, info->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
-//	pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum);
-	dma_nwl_return_buffer(ctx, info);
-	
-	res += bufsize;
-
-    } while (ret);
-    
-    return 0;
-}
-
-int dma_nwl_wait_completion(nwl_dma_t * ctx, pcilib_dma_engine_t dma, pcilib_timeout_t timeout) {
-    if (dma_nwl_get_next_buffer(ctx, ctx->engines + dma, PCILIB_NWL_DMA_PAGES - 1, PCILIB_DMA_TIMEOUT) == (PCILIB_NWL_DMA_PAGES - 1)) return 0;
-    else return PCILIB_ERROR_TIMEOUT;
-}
-

+ 0 - 12
dma/nwl_engine.h

@@ -1,12 +0,0 @@
-#ifndef _PCILIB_DMA_NWL_ENGINE_H
-#define _PCILIB_DMA_NWL_ENGINE_H
-
-int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base);
-int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma);
-int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma);
-
-int dma_nwl_wait_completion(nwl_dma_t * ctx, pcilib_dma_engine_t dma, pcilib_timeout_t timeout);
-
-
-#endif /* _PCILIB_DMA_NWL_ENGINE_H */
-

+ 0 - 412
dma/nwl_engine_buffers.h

@@ -1,412 +0,0 @@
-#define NWL_RING_GET(data, offset)  *(uint32_t*)(((char*)(data)) + (offset))
-#define NWL_RING_SET(data, offset, val)  *(uint32_t*)(((char*)(data)) + (offset)) = (val)
-#define NWL_RING_UPDATE(data, offset, mask, val) *(uint32_t*)(((char*)(data)) + (offset)) = ((*(uint32_t*)(((char*)(data)) + (offset)))&(mask))|(val)
-
-static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, unsigned char *ring, uint32_t ring_pa) {
-    uint32_t val;
-
-    char *base = info->base_addr;
-    
-    nwl_read_register(val, ctx, base, REG_SW_NEXT_BD);
-    if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) {
-	if (val < ring_pa) pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%lx) is below start of ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	else pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-
-    info->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    if (info->head >= PCILIB_NWL_DMA_PAGES) {
-	pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", info->head);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-
-    nwl_read_register(val, ctx, base, REG_DMA_ENG_NEXT_BD);
-    if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) {
-	if (val < ring_pa) pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%lx) is below start of ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	else pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-
-    info->tail = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    if (info->tail >= PCILIB_NWL_DMA_PAGES) {
-	pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu) out of range)", info->tail);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-
-#ifdef DEBUG_NWL    
-    printf("S2C: %lu %lu\n", info->tail, info->head);
-#endif /* DEBUG_NWL */
-
-    return 0;
-}
-
-static int dma_nwl_compute_read_c2s_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, unsigned char *ring, uint32_t ring_pa) {
-    uint32_t val;
-
-    char *base = info->base_addr;
-
-    nwl_read_register(val, ctx, base, REG_SW_NEXT_BD);
-    if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) {
-	if (val < ring_pa) pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%lx) is below start of the ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	else pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-
-    info->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    if (info->head >= PCILIB_NWL_DMA_PAGES) {
-	pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", info->head);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-    
-    info->tail = info->head + 1;
-    if (info->tail == PCILIB_NWL_DMA_PAGES) info->tail = 0;
-
-#ifdef DEBUG_NWL    
-    printf("C2S: %lu %lu\n", info->tail, info->head);
-#endif /* DEBUG_NWL */
-
-    return 0;
-}
-
-
-static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) {
-    int err = 0;
-
-    int i;
-    int preserve = 0;
-    uint16_t sub_use;
-    uint32_t val;
-    uint32_t buf_sz;
-    uint64_t buf_pa;
-    pcilib_kmem_reuse_state_t reuse_ring, reuse_pages;
-    pcilib_kmem_flags_t flags;
-    pcilib_kmem_type_t type;
-
-    char *base = info->base_addr;
-    
-    if (info->pages) return 0;
-    
-	// Or bidirectional specified by 0x0|addr, or read 0x0|addr and write 0x80|addr
-    type = (info->desc.direction == PCILIB_DMA_TO_DEVICE)?PCILIB_KMEM_TYPE_DMA_S2C_PAGE:PCILIB_KMEM_TYPE_DMA_C2S_PAGE;
-    sub_use = info->desc.addr|((info->desc.direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00);
-    flags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(info->preserve?PCILIB_KMEM_FLAG_PERSISTENT:0);
-    
-    pcilib_kmem_handle_t *ring = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, PCILIB_NWL_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, sub_use), flags);
-    pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, type, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, sub_use), flags);
-
-    if (!ring||!pages) {
-	if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0);
-	if (ring) pcilib_free_kernel_memory(ctx->pcilib, ring, 0);
-	return PCILIB_ERROR_MEMORY;
-    }
-
-    reuse_ring = pcilib_kmem_is_reused(ctx->pcilib, ring);
-    reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages);
-
-//	I guess idea here was that we not need to check all that stuff during the second iteration
-//	which is basicaly true (shall we expect any driver-triggered changes or parallel accesses?)
-//	but still we need to set preserve flag (and that if we enforcing preservation --start-dma). 
-//	Probably having checks anyway is not harming...
-//    if (!info->preserve) {
-	if (reuse_ring == reuse_pages) {
-	    if (reuse_ring & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing...");
-	    else if (reuse_ring & PCILIB_KMEM_REUSE_REUSED) {
-		if ((reuse_ring & PCILIB_KMEM_REUSE_PERSISTENT) == 0) pcilib_warning("Lost DMA buffers are found (non-persistent mode), reinitializing...");
-		else if ((reuse_ring & PCILIB_KMEM_REUSE_HARDWARE) == 0) pcilib_warning("Lost DMA buffers are found (missing HW reference), reinitializing...");
-		else {
-		    nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
-
-		    if ((val&DMA_ENG_RUNNING) == 0) pcilib_warning("Lost DMA buffers are found (DMA engine is stopped), reinitializing...");
-		    else preserve = 1;
-		}
-	    } 	
-	} else pcilib_warning("Inconsistent DMA buffers (modes of ring and page buffers does not match), reinitializing....");
-//    }
-
-    
-    unsigned char *data = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, ring);
-    uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, ring);
-
-    if (preserve) {
-	if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) err = dma_nwl_compute_read_c2s_pointers(ctx, info, data, ring_pa);
-	else err = dma_nwl_compute_read_s2c_pointers(ctx, info, data, ring_pa);
-
-	if (err) preserve = 0;
-    }
-    
-    if (preserve) {
-	info->reused = 1;
-        buf_sz = pcilib_kmem_get_block_size(ctx->pcilib, pages, 0);
-    } else {
-	info->reused = 0;
-	
-	memset(data, 0, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-
-	for (i = 0; i < PCILIB_NWL_DMA_PAGES; i++, data += PCILIB_NWL_DMA_DESCRIPTOR_SIZE) {
-	    buf_pa = pcilib_kmem_get_block_pa(ctx->pcilib, pages, i);
-	    buf_sz = pcilib_kmem_get_block_size(ctx->pcilib, pages, i);
-
-	    NWL_RING_SET(data, DMA_BD_NDESC_OFFSET, ring_pa + ((i + 1) % PCILIB_NWL_DMA_PAGES) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	    NWL_RING_SET(data, DMA_BD_BUFAL_OFFSET, buf_pa&0xFFFFFFFF);
-	    NWL_RING_SET(data, DMA_BD_BUFAH_OFFSET, buf_pa>>32);
-#ifdef NWL_GENERATE_DMA_IRQ
-    	    NWL_RING_SET(data, DMA_BD_BUFL_CTRL_OFFSET, buf_sz | DMA_BD_INT_ERROR_MASK | DMA_BD_INT_COMP_MASK);
-#else /* NWL_GENERATE_DMA_IRQ */
-    	    NWL_RING_SET(data, DMA_BD_BUFL_CTRL_OFFSET, buf_sz);
-#endif /* NWL_GENERATE_DMA_IRQ */
-	}
-
-	val = ring_pa;
-	nwl_write_register(val, ctx, base, REG_DMA_ENG_NEXT_BD);
-	nwl_write_register(val, ctx, base, REG_SW_NEXT_BD);
-
-        info->head = 0;
-	info->tail = 0;
-    }
-    
-    info->ring = ring;
-    info->pages = pages;
-    info->page_size = buf_sz;
-    info->ring_size = PCILIB_NWL_DMA_PAGES;
-    
-    return 0;
-}
-
-
-static size_t dma_nwl_clean_buffers(nwl_dma_t * ctx, pcilib_nwl_engine_description_t *info) {
-    size_t res = 0;
-    uint32_t status;
-
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring);
-    ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-
-next_buffer:
-    status = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_STATUS_MASK;
-//  control = NWL_RING_GET(ring, DMA_BD_BUFL_CTRL_OFFSET)&DMA_BD_CTRL_MASK;
-    
-    if (status & DMA_BD_ERROR_MASK) {
-        pcilib_error("NWL DMA Engine reported error in ring descriptor");
-        return (size_t)-1;
-    }
-	
-    if (status & DMA_BD_SHORT_MASK) {
-        pcilib_error("NWL DMA Engine reported short error");
-        return (size_t)-1;
-    }
-	
-    if (status & DMA_BD_COMP_MASK) {
-	info->tail++;
-	if (info->tail == info->ring_size) {
-	    ring -= (info->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-	    info->tail = 0;
-	} else {
-	    ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-	}
-	
-	res++;
-
-	if (info->tail != info->head) goto next_buffer;
-    }
-    
-//    printf("====> Cleaned: %i\n", res);
-    return res;
-}
-
-
-static size_t dma_nwl_get_next_buffer(nwl_dma_t * ctx, pcilib_nwl_engine_description_t *info, size_t n_buffers, pcilib_timeout_t timeout) {
-    struct timeval start, cur;
-
-    size_t res, n = 0;
-    size_t head;
-
-    for (head = info->head; (((head + 1)%info->ring_size) != info->tail)&&(n < n_buffers); head++, n++);
-    if (n == n_buffers) return info->head;
-
-    gettimeofday(&start, NULL);
-
-    res = dma_nwl_clean_buffers(ctx, info);
-    if (res == (size_t)-1) return PCILIB_DMA_BUFFER_INVALID;
-    else n += res;
-
-    
-    while (n < n_buffers) {
-	if (timeout != PCILIB_TIMEOUT_INFINITE) {
-	    gettimeofday(&cur, NULL);
-	    if  (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > timeout) break;
-	}
-	
-	usleep (10);	
-
-        res = dma_nwl_clean_buffers(ctx, info);
-        if (res == (size_t)-1) return PCILIB_DMA_BUFFER_INVALID;
-	else if (res > 0) {
-	    gettimeofday(&start, NULL);
-	    n += res;
-	}
-    }
-
-    if (n < n_buffers) return PCILIB_DMA_BUFFER_INVALID;
-    
-    return info->head;
-}
-
-static int dma_nwl_push_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, size_t size, int eop, pcilib_timeout_t timeout) {
-    int flags = 0;
-    
-    uint32_t val;
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring);
-    uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
-
-    ring += info->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-
-    
-    if (!info->writting) {
-	flags |= DMA_BD_SOP_MASK;
-	info->writting = 1;
-    }
-    if (eop) {
-	flags |= DMA_BD_EOP_MASK;
-	info->writting = 0;
-    }
-    
-    NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, size|flags);
-    NWL_RING_SET(ring, DMA_BD_BUFL_STATUS_OFFSET, size);
-
-    info->head++;
-    if (info->head == info->ring_size) info->head = 0;
-    
-    val = ring_pa + info->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    nwl_write_register(val, ctx, info->base_addr, REG_SW_NEXT_BD);
-    
-    return 0;
-}
-
-
-static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, size_t *size, int *eop, pcilib_timeout_t timeout) {
-    struct timeval start, cur;
-    uint32_t status_size, status;
-
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring);
-    
-    ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-
-    gettimeofday(&start, NULL);
-    
-    do {
-	status_size = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET);
-	status = status_size & DMA_BD_STATUS_MASK;
-	
-	if (status & DMA_BD_ERROR_MASK) {
-    	    pcilib_error("NWL DMA Engine reported error in ring descriptor");
-    	    return (size_t)-1;
-	}	
-	
-	if (status & DMA_BD_COMP_MASK) {
-	    if (status & DMA_BD_EOP_MASK) *eop = 1;
-	    else *eop = 0;
-	            
-	    *size = status_size & DMA_BD_BUFL_MASK;
-
-/*	    
-	    if (mrd) {
-		if ((info->tail + 1) == info->ring_size) ring -= info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-		else ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-		*mrd = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_COMP_MASK;
-	    }
-*/
-	
-	    return info->tail;
-	}
-	
-	usleep(10);
-        gettimeofday(&cur, NULL);
-    } while ((timeout == PCILIB_TIMEOUT_INFINITE)||(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < timeout));
-
-    return (size_t)-1;
-}
-
-/*
-    // This function is not used now, but we may need it in the future
-static int dma_nwl_is_overflown(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) {
-    uint32_t status;
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring);
-    if (info->tail > 0) ring += (info->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    else ring += (info->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-
-    status = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET);
-    return status&DMA_BD_COMP_MASK?1:0;
-}
-*/
-
-static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) {
-    uint32_t val;
-
-    unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring);
-    uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
-    size_t bufsz = pcilib_kmem_get_block_size(ctx->pcilib, info->pages, info->tail);
-
-    ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-
-#ifdef NWL_GENERATE_DMA_IRQ    
-    NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, bufsz | DMA_BD_INT_ERROR_MASK | DMA_BD_INT_COMP_MASK);
-#else /* NWL_GENERATE_DMA_IRQ */
-    NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, bufsz);
-#endif /* NWL_GENERATE_DMA_IRQ */
-
-    NWL_RING_SET(ring, DMA_BD_BUFL_STATUS_OFFSET, 0);
-
-    val = ring_pa + info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    nwl_write_register(val, ctx, info->base_addr, REG_SW_NEXT_BD);
-    
-    info->tail++;
-    if (info->tail == info->ring_size) info->tail = 0;
-    
-    return 0;
-}
-
-int dma_nwl_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) {
-    size_t i;
-    uint32_t bstatus;
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-    pcilib_nwl_engine_description_t *info = ctx->engines + dma;
-    unsigned char *ring = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, info->ring);
-
-
-    if (!status) return -1;
-    
-    status->started = info->started;
-    status->ring_size = info->ring_size;
-    status->buffer_size = info->page_size;
-    status->ring_tail = info->tail;
-    
-    if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) {
-	size_t pos = 0;
-	for (i = 0; i < info->ring_size; i++) {
-	    pos = status->ring_tail + i;
-	    if (pos >= info->ring_size) pos -= info->ring_size;
-
-	    bstatus = NWL_RING_GET(ring + pos * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, DMA_BD_BUFL_STATUS_OFFSET);
-	    if ((bstatus&(DMA_BD_ERROR_MASK|DMA_BD_COMP_MASK)) == 0) break;
-	}
-        status->ring_head = pos;
-    } else {
-        status->ring_head = info->head;
-    }
-
-
-    if (buffers) {	
-	for (i = 0; (i < info->ring_size)&&(i < n_buffers); i++) {
-	    bstatus = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET);
-
-	    buffers[i].error = bstatus & (DMA_BD_ERROR_MASK/*|DMA_BD_SHORT_MASK*/);
-	    buffers[i].used = bstatus & DMA_BD_COMP_MASK;
-	    buffers[i].size = bstatus & DMA_BD_BUFL_MASK;
-	    buffers[i].first = bstatus & DMA_BD_SOP_MASK;
-	    buffers[i].last = bstatus & DMA_BD_EOP_MASK;
-
-	    ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-	}
-    }
-    
-    return 0;
-}

+ 0 - 119
dma/nwl_irq.c

@@ -1,119 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "pcilib.h"
-
-#include "pci.h"
-#include "error.h"
-#include "tools.h"
-
-#include "nwl_private.h"
-#include "nwl_defines.h"
-
-int dma_nwl_init_irq(nwl_dma_t *ctx, uint32_t val) {
-    if (val&(DMA_INT_ENABLE|DMA_USER_INT_ENABLE)) {
-	if (val&DMA_INT_ENABLE) ctx->irq_preserve |= PCILIB_DMA_IRQ;
-	if (val&DMA_USER_INT_ENABLE) ctx->irq_preserve |= PCILIB_EVENT_IRQ;
-    }
-    
-    ctx->irq_started = 1;
-    return 0;
-}
-
-int dma_nwl_free_irq(nwl_dma_t *ctx) {
-    if (ctx->irq_started) {
-	dma_nwl_disable_irq((pcilib_dma_context_t*)ctx, 0);
-	if (ctx->irq_preserve) dma_nwl_enable_irq((pcilib_dma_context_t*)ctx, ctx->irq_preserve, 0);
-	ctx->irq_enabled = 0;
-	ctx->irq_started = 0;
-    }
-    return 0;
-}
-
-int dma_nwl_enable_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t type, pcilib_dma_flags_t flags) {
-    uint32_t val;
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-    
-    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->irq_preserve |= type;
-
-    if ((ctx->irq_enabled&type) == type) return 0;
-    
-    type |= ctx->irq_enabled;
-    
-    nwl_read_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS);
-    if (!ctx->irq_started) dma_nwl_init_irq(ctx, val);
-
-    val &= ~(DMA_INT_ENABLE|DMA_USER_INT_ENABLE);
-    nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS);
-    
-    pcilib_clear_irq(ctx->pcilib, NWL_DMA_IRQ_SOURCE);
-
-    if (type & PCILIB_DMA_IRQ) val |= DMA_INT_ENABLE;
-    if (type & PCILIB_EVENT_IRQ) val |= DMA_USER_INT_ENABLE;
-    nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS);
-    
-    ctx->irq_enabled = type;
-
-    return 0;
-}
-
-
-int dma_nwl_disable_irq(pcilib_dma_context_t *vctx, pcilib_dma_flags_t flags) {
-    uint32_t val;
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-    
-    ctx->irq_enabled = 0;
-    
-    nwl_read_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS);
-    if (!ctx->irq_started) dma_nwl_init_irq(ctx, val);
-    val &= ~(DMA_INT_ENABLE|DMA_USER_INT_ENABLE);
-    nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS);
-    
-    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->irq_preserve = 0;
-
-    return 0;
-}
-
-
-int dma_nwl_enable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
-    uint32_t val;
-    
-    dma_nwl_enable_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, 0);
-
-    nwl_read_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS);
-    val |= (DMA_ENG_INT_ENABLE);
-    nwl_write_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS);
-    
-    return 0;
-}
-
-int dma_nwl_disable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
-    uint32_t val;
-
-    nwl_read_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS);
-    val &= ~(DMA_ENG_INT_ENABLE);
-    nwl_write_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS);
-
-    return 0;
-}
-
-int dma_nwl_acknowledge_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) {
-    uint32_t val;
-    
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-    pcilib_nwl_engine_description_t *info = ctx->engines + irq_source;
-
-    if (irq_type != PCILIB_DMA_IRQ) return PCILIB_ERROR_NOTSUPPORTED;
-    if (irq_source >= ctx->n_engines) return PCILIB_ERROR_NOTAVAILABLE;
-
-    nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
-    if (val & DMA_ENG_INT_ACTIVE_MASK) {
-	val |= DMA_ENG_ALLINT_MASK;
-	nwl_write_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
-    }
-    
-    return 0;
-}

+ 0 - 10
dma/nwl_irq.h

@@ -1,10 +0,0 @@
-#ifndef _PCILIB_NWL_IRQ_H
-#define _PCILIB_NWL_IRQ_H
-
-int dma_nwl_init_irq(nwl_dma_t *ctx, uint32_t val);
-int dma_nwl_free_irq(nwl_dma_t *ctx);
-
-int dma_nwl_enable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma);
-int dma_nwl_disable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma);
-
-#endif /* _PCILIB_NWL_IRQ_H */

+ 0 - 255
dma/nwl_loopback.c

@@ -1,255 +0,0 @@
-#define _BSD_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "pci.h"
-#include "pcilib.h"
-#include "error.h"
-#include "tools.h"
-#include "nwl_private.h"
-
-#include "nwl_defines.h"
-
-#define NWL_BUG_EXTRA_DATA
-
-
-int dma_nwl_start_loopback(nwl_dma_t *ctx,  pcilib_dma_direction_t direction, size_t packet_size) {
-    uint32_t val;
-
-    ctx->loopback_started = 1;
-    dma_nwl_stop_loopback(ctx);
-    
-    val = packet_size;
-    nwl_write_register(val, ctx, ctx->base_addr, PKT_SIZE_ADDRESS);
-
-    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
-	switch (direction) {
-          case PCILIB_DMA_BIDIRECTIONAL:
-	    val = LOOPBACK;
-	    nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
-	    break;
-          case PCILIB_DMA_TO_DEVICE:
-	    return -1;
-	  case PCILIB_DMA_FROM_DEVICE:
-    	    val = PKTGENR;
-	    nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS);
-	    break;
-	}
-    }
-
-    ctx->loopback_started = 1;
-        
-    return 0;
-}
-
-int dma_nwl_stop_loopback(nwl_dma_t *ctx) {
-    uint32_t val = 0;
-    
-    if (!ctx->loopback_started) return 0;
-
-	/* Stop in any case, otherwise we can have problems in benchmark due to
-	engine initialized in previous run, and benchmark is only actual usage.
-	Otherwise, we should detect current loopback status during initialization */
-
-    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
-	nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
-	nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS);
-    }
-    
-    ctx->loopback_started = 0;
-    
-    return 0;
-}
-
-double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) {
-    int iter, i;
-    int err;
-    size_t bytes, rbytes;
-    uint32_t *buf, *cmp;
-    const char *error = NULL;
-    size_t packet_size, blocks;    
-
-    size_t us = 0;
-    struct timeval start, cur;
-
-    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-
-    pcilib_dma_engine_t readid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_FROM_DEVICE, dma);
-    pcilib_dma_engine_t writeid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_TO_DEVICE, dma);
-
-    if (size%sizeof(uint32_t)) size = 1 + size / sizeof(uint32_t);
-    else size /= sizeof(uint32_t);
-
-	// Not supported
-    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
-	if (direction == PCILIB_DMA_TO_DEVICE) return -1.;
-    }
-//    else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.;
-
-	// Stop Generators and drain old data
-    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
-//    dma_nwl_stop_engine(ctx, readid); // DS: replace with something better
-
-    __sync_synchronize();
-
-    err = pcilib_skip_dma(ctx->pcilib, readid);
-    if (err) {
-	pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine");
-	return -1;
-    }
-
-#ifdef NWL_GENERATE_DMA_IRQ
-    dma_nwl_enable_engine_irq(ctx, readid);
-    dma_nwl_enable_engine_irq(ctx, writeid);
-#endif /* NWL_GENERATE_DMA_IRQ */
-
-    if (size * sizeof(uint32_t) > NWL_MAX_PACKET_SIZE) {
-	packet_size = NWL_MAX_PACKET_SIZE;
-	blocks = (size * sizeof(uint32_t)) / packet_size + (((size*sizeof(uint32_t))%packet_size)?1:0);
-    } else {
-	packet_size = size * sizeof(uint32_t);
-	blocks = 1;
-    }
-
-    dma_nwl_start_loopback(ctx, direction, packet_size);
-
-	// Allocate memory and prepare data
-    buf = malloc(blocks * packet_size * sizeof(uint32_t));
-    cmp = malloc(blocks * packet_size * sizeof(uint32_t));
-    if ((!buf)||(!cmp)) {
-	if (buf) free(buf);
-	if (cmp) free(cmp);
-	return -1;
-    }
-
-    if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
-	pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e5);
-	usleep(100000);
-	pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
-
-	    // This way causes more problems with garbage
-	//pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
-    }
-
-	// Benchmark
-    for (iter = 0; iter < iterations; iter++) {
-        memset(cmp, 0x13 + iter, size * sizeof(uint32_t));
-
-	if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
-	    pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
-	}
-
-	if ((direction&PCILIB_DMA_TO_DEVICE)||(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) {
-	    memcpy(buf, cmp, size * sizeof(uint32_t));
-
-    	    if (direction&PCILIB_DMA_TO_DEVICE) {
-		gettimeofday(&start, NULL);
-	    }
-	    
-	    err = pcilib_write_dma(ctx->pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes);
-	    if ((err)||(bytes != size * sizeof(uint32_t))) {
-		error = "Write failed";
-	    	break;
-	    }
-	    
-    	    if (direction&PCILIB_DMA_TO_DEVICE) {
-		// wait written
-		if (direction == PCILIB_DMA_TO_DEVICE) {
-		    dma_nwl_wait_completion(ctx, writeid, PCILIB_DMA_TIMEOUT);
-		}
-		gettimeofday(&cur, NULL);
-	        us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));    
-	    }
-	}
-
-	if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
-	    pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
-	}
-
-	memset(buf, 0, size * sizeof(uint32_t));
-
-        if (direction&PCILIB_DMA_FROM_DEVICE) {
-	    gettimeofday(&start, NULL);
-	}
-
-	for (i = 0, bytes = 0; i < blocks; i++) {
-#ifdef NWL_BUG_EXTRA_DATA
-	    retry:
-#endif
-    
-	    err = pcilib_read_dma(ctx->pcilib, readid, addr, packet_size * sizeof(uint32_t), buf + (bytes>>2), &rbytes);
-	    if ((err)||(rbytes%sizeof(uint32_t))) {
-		break;
-	    } 
-#ifdef NWL_BUG_EXTRA_DATA
-	    else if (rbytes == 8) {
-		goto retry;	
-	    }
-#endif
-	    bytes += rbytes;
-	}
-
-        if (direction&PCILIB_DMA_FROM_DEVICE) {
-	    gettimeofday(&cur, NULL);
-	    us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));
-	}
-#ifdef NWL_BUG_EXTRA_DATA
-	if ((err)||((bytes != size * sizeof(uint32_t))&&((bytes - 8) != size * sizeof(uint32_t)))) {
-#else
-	if ((err)||(bytes != size * sizeof(uint32_t))) {
-#endif
-	    printf("Expected: %zu bytes, but %zu read, error: %i\n", size * sizeof(uint32_t), bytes, err);
-	    error = "Read failed";
-	    break;
-	}
-	
-#ifndef NWL_BUG_EXTRA_DATA
-	if (direction == PCILIB_DMA_BIDIRECTIONAL) {
-	    if (memcmp(buf, cmp, size * sizeof(uint32_t))) {
-		for (i = 0; i < size; i++)
-		    if (buf[i] != cmp[i]) break;
-		
-		bytes = i;
-		printf("Expected: *0x%lx, Written at dword %lu:", 0x13 + iter, bytes);
-		for (; (i < size)&&(i < (bytes + 16)); i++) {
-		    if (((i - bytes)%8)==0) printf("\n");
-		    printf("% 10lx", buf[i]);
-		}
-		printf("\n");
-		
-		error = "Written and read values does not match";
-		break;
-	    }
-	}
-#endif
-    }
-
-    if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
-	pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
-    }
-
-    if (error) {
-	pcilib_warning("%s at iteration %i, error: %i, bytes: %zu", error, iter, err, bytes);
-    }
-    
-#ifdef NWL_GENERATE_DMA_IRQ
-    dma_nwl_disable_engine_irq(ctx, writeid);
-    dma_nwl_disable_engine_irq(ctx, readid);
-#endif /* NWL_GENERATE_DMA_IRQ */
-
-    dma_nwl_stop_loopback(ctx);
-
-    __sync_synchronize();
-    
-    if (direction == PCILIB_DMA_FROM_DEVICE) {
-	pcilib_skip_dma(ctx->pcilib, readid);
-    }
-    
-    free(cmp);
-    free(buf);
-
-    return /*error?-1:*/(1. * size * sizeof(uint32_t) * iterations * 1000000) / (1024. * 1024. * us);
-}

+ 0 - 7
dma/nwl_loopback.h

@@ -1,7 +0,0 @@
-#ifndef _PCILIB_NWL_LOOPBACK_H
-#define _PCILIB_NWL_LOOPBACK_H
-
-int dma_nwl_start_loopback(nwl_dma_t *ctx,  pcilib_dma_direction_t direction, size_t packet_size);
-int dma_nwl_stop_loopback(nwl_dma_t *ctx);
-
-#endif /* _PCILIB_NWL_LOOPBACK_H */

+ 0 - 67
dma/nwl_private.h

@@ -1,67 +0,0 @@
-#ifndef _PCILIB_DMA_NWL_PRIVATE_H
-#define _PCILIB_DMA_NWL_PRIVATE_H
-
-typedef struct nwl_dma_s nwl_dma_t;
-typedef struct pcilib_nwl_engine_description_s pcilib_nwl_engine_description_t;
-
-#define NWL_DMA_IRQ_SOURCE 0
-
-#define NWL_XAUI_ENGINE 0
-#define NWL_XRAWDATA_ENGINE 1
-#define NWL_MAX_PACKET_SIZE 4096 //16384
-//#define NWL_GENERATE_DMA_IRQ
-
-#define PCILIB_NWL_ALIGNMENT 			64  // in bytes
-#define PCILIB_NWL_DMA_DESCRIPTOR_SIZE		64  // in bytes
-#define PCILIB_NWL_DMA_PAGES			256 // 1024
-
-//#define DEBUG_HARDWARE
-//#define DEBUG_NWL
-
-#include "nwl.h"
-#include "nwl_irq.h"
-#include "nwl_register.h"
-#include "nwl_engine.h"
-#include "nwl_loopback.h"
-
-#define nwl_read_register(var, ctx, base, reg) pcilib_datacpy(&var, base + reg, 4, 1, ctx->dma_bank->raw_endianess)
-#define nwl_write_register(var, ctx, base, reg) pcilib_datacpy(base + reg, &var, 4, 1, ctx->dma_bank->raw_endianess)
-
-struct pcilib_nwl_engine_description_s {
-    pcilib_dma_engine_description_t desc;
-    char *base_addr;
-    
-    size_t ring_size, page_size;
-    size_t head, tail;
-    pcilib_kmem_handle_t *ring;
-    pcilib_kmem_handle_t *pages;
-    
-    int started;			/**< indicates that DMA buffers are initialized and reading is allowed */
-    int writting;			/**< indicates that we are in middle of writting packet */
-    int reused;				/**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */
-    int preserve;			/**< indicates that DMA should not be stopped during clean-up */
-};
-
-
-struct nwl_dma_s {
-    struct pcilib_dma_context_s dmactx;
-    
-    pcilib_t *pcilib;
-    
-    pcilib_dma_modification_t type;
-    
-    pcilib_register_bank_description_t *dma_bank;
-    char *base_addr;
-
-    pcilib_irq_type_t irq_enabled;	/**< indicates that IRQs are enabled */
-    pcilib_irq_type_t irq_preserve;	/**< indicates that IRQs should not be disabled during clean-up */
-    int started;			/**< indicates that DMA subsystem is initialized and DMA engine can start */
-    int irq_started;			/**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */    
-    int loopback_started;		/**< indicates that benchmarking subsystem is initialized */
-
-    pcilib_dma_engine_t n_engines;
-    pcilib_nwl_engine_description_t engines[PCILIB_MAX_DMA_ENGINES + 1];
-};
-
-
-#endif /* _PCILIB_DMA_NWL_PRIVATE_H */

+ 0 - 77
dma/nwl_register.c

@@ -1,77 +0,0 @@
-#define _PCILIB_NWL_REGISTER_C 
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "pcilib.h"
-
-#include "pci.h"
-#include "error.h"
-#include "tools.h"
-
-#include "nwl_private.h"
-#include "nwl_register.h"
-
-int nwl_add_registers(nwl_dma_t *ctx) {
-    int err;
-    size_t n, i, j;
-    int length;
-    const char *names[NWL_MAX_DMA_ENGINE_REGISTERS];
-    uintptr_t addr[NWL_MAX_DMA_ENGINE_REGISTERS];
-    
-	// We don't want DMA registers
-    if (pcilib_find_bank_by_addr(ctx->pcilib, PCILIB_REGISTER_BANK_DMA) == PCILIB_REGISTER_BANK_INVALID) return 0;
-    
-    err = pcilib_add_registers(ctx->pcilib, 0, nwl_dma_registers);
-    if (err) return err;
-
-    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
-	err = pcilib_add_registers(ctx->pcilib, 0, nwl_xrawdata_registers);
-	if (err) return err;
-    }
-
-    
-    for (n = 0; nwl_dma_engine_registers[n].bits; n++) {
-	names[n] = nwl_dma_engine_registers[n].name;
-	addr[n] = nwl_dma_engine_registers[n].addr;
-    }
-
-    if (ctx->n_engines > 9) length = 2;
-    else length = 1;
-
-    
-    for (i = 0; i < ctx->n_engines; i++) {
-	for (j = 0; nwl_dma_engine_registers[j].bits; j++) {
-	    const char *direction;
-	    nwl_dma_engine_registers[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j];
-	    nwl_dma_engine_registers[j].addr = addr[j] + (ctx->engines[i].base_addr - ctx->base_addr);
-//	    printf("%lx %lx\n", (ctx->engines[i].base_addr - ctx->base_addr), nwl_dma_engine_registers[j].addr);
-	    
-	    switch (ctx->engines[i].desc.direction) {
-		case PCILIB_DMA_FROM_DEVICE:
-		    direction =  "r";
-		break;
-		case PCILIB_DMA_TO_DEVICE:
-		    direction = "w";
-		break;
-		default:
-		    direction = "";
-	    }
-	    
-	    sprintf((char*)nwl_dma_engine_registers[j].name, names[j], length, ctx->engines[i].desc.addr, direction);
-	}
-	
-        err = pcilib_add_registers(ctx->pcilib, n, nwl_dma_engine_registers);
-	if (err) return err;
-    }
-    
-    for (n = 0; nwl_dma_engine_registers[n].bits; n++) {
-	nwl_dma_engine_registers[n].name = names[n];
-	nwl_dma_engine_registers[n].addr = addr[n];
-    }
-    
-    return 0;
-}

+ 0 - 97
dma/nwl_register.h

@@ -1,97 +0,0 @@
-#ifndef _PCILIB_NWL_REGISTERS_H
-#define _PCILIB_NWL_REGISTERS_H 
-
-#ifdef _PCILIB_NWL_REGISTER_C 
-  // DMA
-static pcilib_register_description_t nwl_dma_registers[] = {
-    {0x4000, 	0, 	32, 	0, 	0x00000011,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_control_and_status",  ""},
-    {0x4000, 	0, 	1, 	0, 	0x00000011,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_enable",  ""},
-    {0x4000, 	1, 	1, 	0, 	0x00000011,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_active",  ""},
-    {0x4000, 	2, 	1, 	0, 	0x00000011,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_pending",  ""},
-    {0x4000, 	3, 	1, 	0, 	0x00000011,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_mode",  ""},
-    {0x4000, 	4, 	1, 	0, 	0x00000011,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_enable",  ""},
-    {0x4000, 	5, 	1, 	0, 	0x00000011,	PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_active",  ""},
-    {0x4000, 	16, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_s2c_interrupt_status",  ""},
-    {0x4000, 	24, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_c2s_interrupt_status",  ""},
-    {0x8000, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_design_version",  ""},
-    {0x8000, 	0, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_subversion_number",  ""},
-    {0x8000, 	4, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_version_number",  ""},
-    {0x8000, 	28, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_targeted_device",  ""},
-    {0x8200, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_transmit_utilization",  ""},
-    {0x8200, 	0, 	2, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_sample_count",  ""},
-    {0x8200, 	2, 	30, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_dword_count",  ""},
-    {0x8204, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_receive_utilization",  ""},
-    {0x8004, 	0, 	2, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_sample_count",  ""},
-    {0x8004, 	2, 	30, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_dword_count",  ""},
-    {0x8208, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_mwr",  ""},
-    {0x8008, 	0, 	2, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_sample_count",  ""},
-    {0x8008, 	2, 	30, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_dword_count",  ""},
-    {0x820C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_cpld",  ""},
-    {0x820C, 	0, 	2, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_sample_count",  ""},
-    {0x820C, 	2, 	30, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_dword_count",  ""},
-    {0x8210, 	0, 	12, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cpld",  ""},
-    {0x8214, 	0, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cplh",  ""},
-    {0x8218, 	0, 	12, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_npd",  ""},
-    {0x821C, 	0, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_nph",  ""},
-    {0x8220, 	0, 	12, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_pd",  ""},
-    {0x8224, 	0, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_ph",  ""},
-    {0,		0,	0,	0,	0x00000000,	0,                                           0,                        0, NULL, NULL}
-};
-
- // DMA Engine Registers
-#define NWL_MAX_DMA_ENGINE_REGISTERS 64
-#define NWL_MAX_REGISTER_NAME 128
-static char nwl_dma_engine_register_names[PCILIB_MAX_DMA_ENGINES * NWL_MAX_DMA_ENGINE_REGISTERS][NWL_MAX_REGISTER_NAME];
-static pcilib_register_description_t nwl_dma_engine_registers[] = {
-    {0x0000, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_capabilities",  ""},
-    {0x0000, 	0, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_present",  ""},
-    {0x0000, 	1, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_direction",  ""},
-    {0x0000, 	4, 	2, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_type",  ""},
-    {0x0000, 	8, 	8, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_number",  ""},
-    {0x0000, 	24, 	6, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_max_buffer_size",  ""},
-    {0x0004, 	0, 	32, 	0, 	0x0000C100,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_control",  ""},
-    {0x0004, 	0, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_enable",  ""},
-    {0x0004, 	1, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_active",  ""},
-    {0x0004, 	2, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_complete",  ""},
-    {0x0004, 	3, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_alignment_error",  ""},
-    {0x0004, 	4, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_fetch_error",  ""},
-    {0x0004, 	5, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_abort_error",  ""},
-    {0x0004, 	8, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_enable",  ""},
-    {0x0004, 	10, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_running",  ""},
-    {0x0004, 	11, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_waiting",  ""},
-    {0x0004, 	14, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset_request", ""},
-    {0x0004, 	15, 	1, 	0, 	0x0000C100,	PCILIB_REGISTER_W   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset", ""},
-    {0x0008, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_next_descriptor",  ""},
-    {0x000C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_descriptor",  ""},
-    {0x0010, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_last_descriptor",  ""},
-    {0x0014, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_active_time",  ""},
-    {0x0018, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_wait_time",  ""},
-    {0x001C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_counter",  ""},
-    {0x001C, 	0, 	2, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sample_count",  ""},
-    {0x001C, 	2, 	30, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_dword_count",  ""},
-    {0,		0,	0,	0,	0x00000000,	0,                                          0,                        0, NULL, NULL}
-};
-
-/*
- // XAUI registers
-static pcilib_register_description_t nwl_xaui_registers[] = {
-    {0,		0,	0,	0,	0,                                          0,                        0, NULL, NULL}
-};
-*/
-
- // XRAWDATA registers
-static pcilib_register_description_t nwl_xrawdata_registers[] = {
-    {0x9100, 	0, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_generator",  ""},
-    {0x9104, 	0, 	16, 	0, 	0x00000000,	PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_packet_length",  ""},
-    {0x9108, 	0, 	2, 	0, 	0x00000003,	PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_control",  ""},
-    {0x9108, 	0, 	1, 	0, 	0x00000003,	PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_checker",  ""},
-    {0x9108, 	1, 	1, 	0, 	0x00000003,	PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_loopback",  ""},
-    {0x910C, 	0, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_data_mistmatch",  ""},
-    {0,		0,	0,	0,	0x00000000,	0,                                            0,                        0, NULL, NULL}
-};
-
-#endif /* _PCILIB_NWL_REGISTERS_C */
-
-int nwl_add_registers(nwl_dma_t *ctx);
-
-#endif /* _PCILIB_NWL_REGISTERS_H */

+ 0 - 49
driver/Makefile

@@ -1,49 +0,0 @@
-
-obj-m := pciDriver.o
-pciDriver-objs := base.o int.o umem.o kmem.o sysfs.o ioctl.o
-
-KERNELDIR ?= /lib/modules/$(shell uname -r)/build
-INSTALLDIR ?= /lib/modules/$(shell uname -r)/extra
-PWD := $(shell pwd)
-
-EXTRA_CFLAGS += -I$(M)/..
-
-default:
-	@KERNEL_GCC_VERSION=`cat /proc/version | head -n1 | cut -d " " -f 7` ;\
-	GCC_VERSION=`$(CC) --version | head -n 1 | tr ' ' '\n' | grep -e "[0-9]\+\.[0-9]" | tail -n 1` ;\
-	if [ $$KERNEL_GCC_VERSION != $$GCC_VERSION ]; then \
-	    echo "Kernel is compiled with gcc $$KERNEL_GCC_VERSION, but you are now using $$GCC_VERSION" ;\
-	    GCC_MAJOR=`echo $$KERNEL_GCC_VERSION | cut -d "." -f 1-2` ;\
-	    newCC=gcc-$$GCC_MAJOR ;\
-	    CC=`which $$newCC 2>/dev/null` ;\
-	    if [ $$? -ne 0 ]; then \
-		echo "No compiler of $$GCC_MAJOR series is installed" ;\
-		exit 1 ;\
-	    fi ;\
-	    GCC_VERSION=`$$CC --version | head -n 1 | tr ' ' '\n' | grep -e "[0-9]\+\.[0-9]" | head -n 1` ;\
-	    if [ $$KERNEL_GCC_VERSION != $$GCC_VERSION ]; then \
-		echo "The $$GCC_VERSION of $$GCC_MAJOR series is installed" ;\
-		exit 1 ;\
-	    fi ;\
-	    echo "Setting CC to $$newCC" ;\
-	else \
-	    CC=$(CC) ;\
-	fi ;\
-	$(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(PWD) CC=$$CC modules
-
-install:
-	@mkdir -p $(INSTALLDIR)
-	@echo "INSTALL $(INSTALLDIR)/pciDriver.ko"
-	@install -m 755 pciDriver.ko $(INSTALLDIR)
-	@echo "INSTALL /usr/include/pciDriver/driver/pciDriver.h"
-	@mkdir -p /usr/include/pciDriver/driver
-	@install -m 644 pciDriver.h /usr/include/pciDriver/driver
-
-uninstall:
-	@echo "UNINSTALL $(INSTALLDIR)/pciDriver.ko"
-	@rm -f $(INSTALLDIR)/pciDriver.ko
-	@echo "UNINSTALL /usr/include/pciDriver/driver/pciDriver.h"
-	@rm -rf /usr/include/pciDriver/driver
-
-clean:
-	rm -rf *.o *.ko *.mod.c .*.o.cmd .*.o.tmp .*.ko.cmd  .*.o *.symvers modules.order .tmp_versions

+ 0 - 676
driver/base.c

@@ -1,676 +0,0 @@
-/**
- *
- * @file base.c
- * @author Guillermo Marcus
- * @date 2009-04-05
- * @brief Contains the main code which connects all the different parts and does
- * basic driver tasks like initialization.
- *
- * This is a full rewrite of the pciDriver.
- * New default is to support kernel 2.6, using kernel 2.6 APIs.
- *
- */
-
-/*
- * Change History:
- *
- * $Log: not supported by cvs2svn $
- * Revision 1.13  2008-05-30 11:38:15  marcus
- * Added patches for kernel 2.6.24
- *
- * Revision 1.12  2008-01-24 14:21:36  marcus
- * Added a CLEAR_INTERRUPT_QUEUE ioctl.
- * Added a sysfs attribute to show the outstanding IRQ queues.
- *
- * Revision 1.11  2008-01-24 12:53:11  marcus
- * Corrected wait_event condition in waiti_ioctl. Improved the loop too.
- *
- * Revision 1.10  2008-01-14 10:39:39  marcus
- * Set some messages as debug instead of normal.
- *
- * Revision 1.9  2008-01-11 10:18:28  marcus
- * Modified interrupt mechanism. Added atomic functions and queues, to address race conditions. Removed unused interrupt code.
- *
- * Revision 1.8  2007-07-17 13:15:55  marcus
- * Removed Tasklets.
- * Using newest map for the ABB interrupts.
- *
- * Revision 1.7  2007-07-06 15:56:04  marcus
- * Change default status for OLD_REGISTERS to not defined.
- *
- * Revision 1.6  2007-07-05 15:29:59  marcus
- * Corrected issue with the bar mapping for interrupt handling.
- * Added support up to kernel 2.6.20
- *
- * Revision 1.5  2007-05-29 07:50:18  marcus
- * Split code into 2 files. May get merged in the future again....
- *
- * Revision 1.4  2007/03/01 17:47:34  marcus
- * Fixed bug when the kernel memory was less than one page, it was not locked properly, recalling an old mapping issue in this case.
- *
- * Revision 1.3  2007/03/01 17:01:22  marcus
- * comment fix (again).
- *
- * Revision 1.2  2007/03/01 17:00:25  marcus
- * Changed some comment in the log.
- *
- * Revision 1.1  2007/03/01 16:57:43  marcus
- * Divided driver file to ease the interrupt hooks for the user of the driver.
- * Modified Makefile accordingly.
- *
- * From pciDriver.c:
- * Revision 1.11  2006/12/11 16:15:43  marcus
- * Fixed kernel buffer mmapping, and driver crash when application crashes.
- * Buffer memory is now marked reserved during allocation, and mmaped with
- * remap_xx_range.
- *
- * Revision 1.10  2006/11/21 09:50:49  marcus
- * Added PROGRAPE4 vendor/device IDs.
- *
- * Revision 1.9  2006/11/17 18:47:36  marcus
- * Removed MERGE_SGENTRIES flag, now it is selected at runtime with 'type'.
- * Removed noncached in non-prefetchable areas, to allow the use of MTRRs.
- *
- * Revision 1.8  2006/11/17 16:41:21  marcus
- * Added slot number to the PCI info IOctl.
- *
- * Revision 1.7  2006/11/13 12:30:34  marcus
- * Added a IOctl call, to confiure the interrupt response. (testing pending).
- * Basic interrupts are now supported, using a Tasklet and Completions.
- *
- * Revision 1.6  2006/11/08 21:30:02  marcus
- * Added changes after compile tests in kernel 2.6.16
- *
- * Revision 1.5  2006/10/31 07:57:38  marcus
- * Improved the pfn calculation in nopage(), to deal with some possible border
- * conditions. It was really no issue, because they are normally page-aligned
- * anyway, but to be on the safe side.
- *
- * Revision 1.4  2006/10/30 19:37:40  marcus
- * Solved bug on kernel memory not mapping properly.
- *
- * Revision 1.3  2006/10/18 11:19:20  marcus
- * Added kernel 2.6.8 support based on comments from Joern Adamczewski (GSI).
- *
- * Revision 1.2  2006/10/18 11:04:15  marcus
- * Bus Master is only activated when we detect a specific board.
- *
- * Revision 1.1  2006/10/10 14:46:51  marcus
- * Initial commit of the new pciDriver for kernel 2.6
- *
- * Revision 1.9  2006/10/05 11:30:46  marcus
- * Prerelease. Added bus and devfn to pciInfo for compatibility.
- *
- * Revision 1.8  2006/09/25 16:51:07  marcus
- * Added PCI config IOctls, and implemented basic mmap functions.
- *
- * Revision 1.7  2006/09/20 11:12:41  marcus
- * Added Merge SG entries
- *
- * Revision 1.6  2006/09/19 17:22:18  marcus
- * backup commit.
- *
- * Revision 1.5  2006/09/18 17:13:11  marcus
- * backup commit.
- *
- * Revision 1.4  2006/09/15 15:44:41  marcus
- * backup commit.
- *
- * Revision 1.3  2006/08/15 11:40:02  marcus
- * backup commit.
- *
- * Revision 1.2  2006/08/12 18:28:42  marcus
- * Sync with the laptop
- *
- * Revision 1.1  2006/08/11 15:30:46  marcus
- * Sync with the laptop
- *
- */
-
-#include <linux/version.h>
-
-/* Check macros and kernel version first */
-#ifndef KERNEL_VERSION
-#error "No KERNEL_VERSION macro! Stopping."
-#endif
-
-#ifndef LINUX_VERSION_CODE
-#error "No LINUX_VERSION_CODE macro! Stopping."
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
-#error "This driver has been tested only for Kernel 2.6.8 or above."
-#endif
-
-/* Required includes */
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/sysfs.h>
-#include <asm/atomic.h>
-#include <linux/pagemap.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <asm/scatterlist.h>
-#include <linux/vmalloc.h>
-#include <linux/stat.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-
-/* Configuration for the driver (what should be compiled in, module name, etc...) */
-#include "config.h"
-
-/* Compatibility functions/definitions (provides functions which are not available on older kernels) */
-#include "compat.h"
-
-/* External interface for the driver */
-#include "pciDriver.h"
-
-/* Internal definitions for all parts (prototypes, data, macros) */
-#include "common.h"
-
-/* Internal definitions for the base part */
-#include "base.h"
-
-/* Internal definitions of the IRQ handling part */
-#include "int.h"
-
-/* Internal definitions for kernel memory */
-#include "kmem.h"
-
-/* Internal definitions for user space memory */
-#include "umem.h"
-
-#include "ioctl.h"
-
-/*************************************************************************/
-/* Module device table associated with this driver */
-MODULE_DEVICE_TABLE(pci, pcidriver_ids);
-
-/* Module init and exit points */
-module_init(pcidriver_init);
-module_exit(pcidriver_exit);
-
-/* Module info */
-MODULE_AUTHOR("Guillermo Marcus");
-MODULE_DESCRIPTION("Simple PCI Driver");
-MODULE_LICENSE("GPL v2");
-
-/* Module class */
-static struct class_compat *pcidriver_class;
-
-/**
- *
- * Called when loading the driver
- *
- */
-static int __init pcidriver_init(void)
-{
-	int err;
-
-	/* Initialize the device count */
-	atomic_set(&pcidriver_deviceCount, 0);
-
-	/* Allocate character device region dynamically */
-	if ((err = alloc_chrdev_region(&pcidriver_devt, MINORNR, MAXDEVICES, NODENAME)) != 0) {
-		mod_info("Couldn't allocate chrdev region. Module not loaded.\n");
-		goto init_alloc_fail;
-	}
-	mod_info("Major %d allocated to nodename '%s'\n", MAJOR(pcidriver_devt), NODENAME);
-
-	/* Register driver class */
-	pcidriver_class = class_create(THIS_MODULE, NODENAME);
-
-	if (IS_ERR(pcidriver_class)) {
-		mod_info("No sysfs support. Module not loaded.\n");
-		goto init_class_fail;
-	}
-
-	/* Register PCI driver. This function returns the number of devices on some
-	 * systems, therefore check for errors as < 0. */
-	if ((err = pci_register_driver(&pcidriver_driver)) < 0) {
-		mod_info("Couldn't register PCI driver. Module not loaded.\n");
-		goto init_pcireg_fail;
-	}
-
-	mod_info("Module loaded\n");
-
-	return 0;
-
-init_pcireg_fail:
-	class_destroy(pcidriver_class);
-init_class_fail:
-	unregister_chrdev_region(pcidriver_devt, MAXDEVICES);
-init_alloc_fail:
-	return err;
-}
-
-/**
- *
- * Called when unloading the driver
- *
- */
-static void pcidriver_exit(void)
-{
-	pci_unregister_driver(&pcidriver_driver);
-	unregister_chrdev_region(pcidriver_devt, MAXDEVICES);
-
-	if (pcidriver_class != NULL)
-		class_destroy(pcidriver_class);
-
-	mod_info("Module unloaded\n");
-}
-
-/*************************************************************************/
-/* Driver functions */
-
-/**
- *
- * This struct defines the PCI entry points.
- * Will be registered at module init.
- *
- */
-static struct pci_driver pcidriver_driver = {
-	.name = MODNAME,
-	.id_table = pcidriver_ids,
-	.probe = pcidriver_probe,
-	.remove = pcidriver_remove,
-};
-
-/**
- *
- * This function is called when installing the driver for a device
- * @param pdev Pointer to the PCI device
- *
- */
-static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	int err;
-	int devno;
-	pcidriver_privdata_t *privdata;
-	int devid;
-
-	/* At the moment there is no difference between these boards here, other than
-	 * printing a different message in the log.
-	 *
-	 * However, there is some difference in the interrupt handling functions.
-	 */
-	if (id->vendor == PCIE_XILINX_VENDOR_ID) {
-	    if (id->device == PCIE_ML605_DEVICE_ID) {
-		mod_info("Found ML605 board at %s\n", dev_name(&pdev->dev));
-	    } else if (id->device == PCIE_IPECAMERA_DEVICE_ID) {
-		mod_info("Found IPE Camera at %s\n", dev_name(&pdev->dev));
-	    } else if (id->device == PCIE_KAPTURE_DEVICE_ID) {
-		mod_info("Found KAPTURE board at %s\n", dev_name(&pdev->dev));
-	    } else {
-		mod_info("Found unknown Xilinx device (%x) at %s\n", id->device, dev_name(&pdev->dev));
-	    }
-	} else {
-		/* It is something else */
-		mod_info( "Found unknown board (%x:%x) at %s\n", id->vendor, id->device, dev_name(&pdev->dev));
-	}
-
-	/* Enable the device */
-	if ((err = pci_enable_device(pdev)) != 0) {
-		mod_info("Couldn't enable device\n");
-		goto probe_pcien_fail;
-	}
-	
-	/* Bus master & dma */
-	if ((id->vendor == PCIE_XILINX_VENDOR_ID)&&(id->device == PCIE_IPECAMERA_DEVICE_ID)) {
-	    pci_set_master(pdev);
-	    
-	    err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-	    if (err < 0) {
-		printk(KERN_ERR "pci_set_dma_mask failed\n");
-		goto probe_dma_fail;
-	    }
-	}
-
-	/* Set Memory-Write-Invalidate support */
-	if ((err = pci_set_mwi(pdev)) != 0)
-		mod_info("MWI not supported. Continue without enabling MWI.\n");
-
-	/* Get / Increment the device id */
-	devid = atomic_inc_return(&pcidriver_deviceCount) - 1;
-	if (devid >= MAXDEVICES) {
-		mod_info("Maximum number of devices reached! Increase MAXDEVICES.\n");
-		err = -ENOMSG;
-		goto probe_maxdevices_fail;
-	}
-
-	/* Allocate and initialize the private data for this device */
-	if ((privdata = kcalloc(1, sizeof(*privdata), GFP_KERNEL)) == NULL) {
-		err = -ENOMEM;
-		goto probe_nomem;
-	}
-
-	INIT_LIST_HEAD(&(privdata->kmem_list));
-	spin_lock_init(&(privdata->kmemlist_lock));
-	atomic_set(&privdata->kmem_count, 0);
-	
-	INIT_LIST_HEAD(&(privdata->umem_list));
-	spin_lock_init(&(privdata->umemlist_lock));
-	atomic_set(&privdata->umem_count, 0);
-
-	pci_set_drvdata( pdev, privdata );
-	privdata->pdev = pdev;
-
-	/* Device add to sysfs */
-	devno = MKDEV(MAJOR(pcidriver_devt), MINOR(pcidriver_devt) + devid);
-	privdata->devno = devno;
-	if (pcidriver_class != NULL) {
-		/* FIXME: some error checking missing here */
-		privdata->class_dev = class_device_create(pcidriver_class, NULL, devno, &(pdev->dev), NODENAMEFMT, MINOR(pcidriver_devt) + devid, privdata);
-		class_set_devdata( privdata->class_dev, privdata );
-		mod_info("Device /dev/%s%d added\n",NODENAME,MINOR(pcidriver_devt) + devid);
-	}
-
-	/* Setup mmaped BARs into kernel space */
-	if ((err = pcidriver_probe_irq(privdata)) != 0)
-		goto probe_irq_probe_fail;
-
-	/* Populate sysfs attributes for the class device */
-	/* TODO: correct errorhandling. ewww. must remove the files in reversed order :-( */
-	#define sysfs_attr(name) do { \
-			if (class_device_create_file(sysfs_attr_def_pointer, &sysfs_attr_def_name(name)) != 0) \
-				goto probe_device_create_fail; \
-			} while (0)
-	#ifdef ENABLE_IRQ
-	sysfs_attr(irq_count);
-	sysfs_attr(irq_queues);
-	#endif
-
-	sysfs_attr(mmap_mode);
-	sysfs_attr(mmap_area);
-	sysfs_attr(kmem_count);
-	sysfs_attr(kmem_alloc);
-	sysfs_attr(kmem_free);
-	sysfs_attr(kbuffers);
-	sysfs_attr(umappings);
-	sysfs_attr(umem_unmap);
-	#undef sysfs_attr
-
-	/* Register character device */
-	cdev_init( &(privdata->cdev), &pcidriver_fops );
-	privdata->cdev.owner = THIS_MODULE;
-	privdata->cdev.ops = &pcidriver_fops;
-	err = cdev_add( &privdata->cdev, devno, 1 );
-	if (err) {
-		mod_info( "Couldn't add character device.\n" );
-		goto probe_cdevadd_fail;
-	}
-
-	return 0;
-
-probe_device_create_fail:
-probe_cdevadd_fail:
-probe_irq_probe_fail:
-	pcidriver_irq_unmap_bars(privdata);
-	kfree(privdata);
-probe_nomem:
-	atomic_dec(&pcidriver_deviceCount);
-probe_maxdevices_fail:
-probe_dma_fail:
-	pci_disable_device(pdev);
-probe_pcien_fail:
- 	return err;
-}
-
-/**
- *
- * This function is called when disconnecting a device
- *
- */
-static void __devexit pcidriver_remove(struct pci_dev *pdev)
-{
-	pcidriver_privdata_t *privdata;
-
-	/* Get private data from the device */
-	privdata = pci_get_drvdata(pdev);
-
-	/* Removing sysfs attributes from class device */
-	#define sysfs_attr(name) do { \
-			class_device_remove_file(sysfs_attr_def_pointer, &sysfs_attr_def_name(name)); \
-			} while (0)
-	#ifdef ENABLE_IRQ
-	sysfs_attr(irq_count);
-	sysfs_attr(irq_queues);
-	#endif
-
-	sysfs_attr(mmap_mode);
-	sysfs_attr(mmap_area);
-	sysfs_attr(kmem_count);
-	sysfs_attr(kmem_alloc);
-	sysfs_attr(kmem_free);
-	sysfs_attr(kbuffers);
-	sysfs_attr(umappings);
-	sysfs_attr(umem_unmap);
-	#undef sysfs_attr
-
-	/* Free all allocated kmem buffers before leaving */
-	pcidriver_kmem_free_all( privdata );
-
-#ifdef ENABLE_IRQ
-	pcidriver_remove_irq(privdata);
-#endif
-
-	/* Removing Character device */
-	cdev_del(&(privdata->cdev));
-
-	/* Removing the device from sysfs */
-	class_device_destroy(pcidriver_class, privdata->devno);
-
-	/* Releasing privdata */
-	kfree(privdata);
-
-	/* Disabling PCI device */
-	pci_disable_device(pdev);
-
-	mod_info("Device at %s removed\n", dev_name(&pdev->dev));
-}
-
-/*************************************************************************/
-/* File operations */
-/*************************************************************************/
-
-/**
- * This struct defines the file operation entry points.
- *
- * @see pcidriver_ioctl
- * @see pcidriver_mmap
- * @see pcidriver_open
- * @see pcidriver_release
- *
- */
-static struct file_operations pcidriver_fops = {
-	.owner = THIS_MODULE,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-	.ioctl = pcidriver_ioctl,
-#else
-	.unlocked_ioctl = pcidriver_ioctl,
-#endif 
-	.mmap = pcidriver_mmap,
-	.open = pcidriver_open,
-	.release = pcidriver_release,
-};
-
-void pcidriver_module_get(pcidriver_privdata_t *privdata) {
-    atomic_inc(&(privdata->refs));
-//    mod_info("Ref: %i\n", atomic_read(&(privdata->refs)));
-}
-
-void pcidriver_module_put(pcidriver_privdata_t *privdata) {
-    if (atomic_add_negative(-1, &(privdata->refs))) {
-	atomic_inc(&(privdata->refs));
-	mod_info("Reference counting error...");
-    } else {
-//	mod_info("Unref: %i\n", atomic_read(&(privdata->refs)));
-    }
-}
-
-/**
- *
- * Called when an application open()s a /dev/fpga*, attaches the private data
- * with the file pointer.
- *
- */
-int pcidriver_open(struct inode *inode, struct file *filp)
-{
-	pcidriver_privdata_t *privdata;
-
-	/* Set the private data area for the file */
-	privdata = container_of( inode->i_cdev, pcidriver_privdata_t, cdev);
-	filp->private_data = privdata;
-
-	pcidriver_module_get(privdata);
-
-	return 0;
-}
-
-/**
- *
- * Called when the application close()s the file descriptor. Does nothing at
- * the moment.
- *
- */
-int pcidriver_release(struct inode *inode, struct file *filp)
-{
-	pcidriver_privdata_t *privdata;
-
-	/* Get the private data area */
-	privdata = filp->private_data;
-
-	pcidriver_module_put(privdata);
-
-	return 0;
-}
-
-/**
- *
- * This function is the entry point for mmap() and calls either pcidriver_mmap_pci
- * or pcidriver_mmap_kmem
- *
- * @see pcidriver_mmap_pci
- * @see pcidriver_mmap_kmem
- *
- */
-int pcidriver_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	pcidriver_privdata_t *privdata;
-	int ret = 0, bar;
-
-	mod_info_dbg("Entering mmap\n");
-
-	/* Get the private data area */
-	privdata = filp->private_data;
-
-	/* Check the current mmap mode */
-	switch (privdata->mmap_mode) {
-		case PCIDRIVER_MMAP_PCI:
-			/* Mmap a PCI region */
-			switch (privdata->mmap_area) {
-				case PCIDRIVER_BAR0:	bar = 0; break;
-				case PCIDRIVER_BAR1:	bar = 1; break;
-				case PCIDRIVER_BAR2:	bar = 2; break;
-				case PCIDRIVER_BAR3:	bar = 3; break;
-				case PCIDRIVER_BAR4:	bar = 4; break;
-				case PCIDRIVER_BAR5:	bar = 5; break;
-				default:
-					mod_info("Attempted to mmap a PCI area with the wrong mmap_area value: %d\n",privdata->mmap_area);
-					return -EINVAL;			/* invalid parameter */
-					break;
-			}
-			ret = pcidriver_mmap_pci(privdata, vma, bar);
-			break;
-		case PCIDRIVER_MMAP_KMEM:
-			/* mmap a Kernel buffer */
-			ret = pcidriver_mmap_kmem(privdata, vma);
-			break;
-		default:
-			mod_info( "Invalid mmap_mode value (%d)\n",privdata->mmap_mode );
-			return -EINVAL;			/* Invalid parameter (mode) */
-	}
-
-	return ret;
-}
-
-/*************************************************************************/
-/* Internal driver functions */
-int pcidriver_mmap_pci(pcidriver_privdata_t *privdata, struct vm_area_struct *vmap, int bar)
-{
-	int ret = 0;
-	unsigned long bar_addr;
-	unsigned long bar_length, vma_size;
-	unsigned long bar_flags;
-
-	mod_info_dbg("Entering mmap_pci\n");
-
-	/* Get info of the BAR to be mapped */
-	bar_addr = pci_resource_start(privdata->pdev, bar);
-	bar_length = pci_resource_len(privdata->pdev, bar);
-	bar_flags = pci_resource_flags(privdata->pdev, bar);
-
-	/* Check sizes */
-	vma_size = (vmap->vm_end - vmap->vm_start);
-
-	if ((vma_size != bar_length) &&
-	   ((bar_length < PAGE_SIZE) && (vma_size != PAGE_SIZE))) {
-		mod_info( "mmap size is not correct! bar: %lu - vma: %lu\n", bar_length, vma_size );
-		return -EINVAL;
-	}
-
-	if (bar_flags & IORESOURCE_IO) {
-		/* Unlikely case, we will mmap a IO region */
-
-		/* IO regions are never cacheable */
-#ifdef pgprot_noncached
-		vmap->vm_page_prot = pgprot_noncached(vmap->vm_page_prot);
-#endif
-
-		/* Map the BAR */
-		ret = io_remap_pfn_range_compat(
-					vmap,
-					vmap->vm_start,
-					bar_addr,
-					bar_length,
-					vmap->vm_page_prot);
-	} else {
-		/* Normal case, mmap a memory region */
-
-		/* Ensure this VMA is non-cached, if it is not flaged as prefetchable.
-		 * If it is prefetchable, caching is allowed and will give better performance.
-		 * This should be set properly by the BIOS, but we want to be sure. */
-		/* adapted from drivers/char/mem.c, mmap function. */
-#ifdef pgprot_noncached
-/* Setting noncached disables MTRR registers, and we want to use them.
- * So we take this code out. This can lead to caching problems if and only if
- * the System BIOS set something wrong. Check LDDv3, page 425.
- */
-//		if (!(bar_flags & IORESOURCE_PREFETCH))
-//			vmap->vm_page_prot = pgprot_noncached(vmap->vm_page_prot);
-#endif
-
-		/* Map the BAR */
-		ret = remap_pfn_range_compat(
-					vmap,
-					vmap->vm_start,
-					bar_addr,
-					bar_length,
-					vmap->vm_page_prot);
-	}
-
-	if (ret) {
-		mod_info("remap_pfn_range failed\n");
-		return -EAGAIN;
-	}
-
-	return 0;	/* success */
-}

+ 0 - 85
driver/base.h

@@ -1,85 +0,0 @@
-#ifndef _PCIDRIVER_BASE_H
-#define _PCIDRIVER_BASE_H
-
-#include "sysfs.h"
-
-/**
- *
- * This file contains prototypes and data structures for internal use of the pciDriver.
- *
- *
- */
-
-/* prototypes for file_operations */
-static struct file_operations pcidriver_fops;
-int pcidriver_mmap( struct file *filp, struct vm_area_struct *vmap );
-int pcidriver_open(struct inode *inode, struct file *filp );
-int pcidriver_release(struct inode *inode, struct file *filp);
-
-/* prototypes for device operations */
-static struct pci_driver pcidriver_driver;
-static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_device_id *id);
-static void __devexit pcidriver_remove(struct pci_dev *pdev);
-
-
-
-/* prototypes for module operations */
-static int __init pcidriver_init(void);
-static void pcidriver_exit(void);
-
-/*
- * This is the table of PCI devices handled by this driver by default
- * If you want to add devices dynamically to this list, do:
- *
- *   echo "vendor device" > /sys/bus/pci/drivers/pciDriver/new_id
- * where vendor and device are in hex, without leading '0x'.
- *
- * The IDs themselves can be found in common.h
- *
- * For more info, see <kernel-source>/Documentation/pci.txt
- *
- * __devinitdata is applied because the kernel does not need those
- * tables any more after boot is finished on systems which don't
- * support hotplug.
- *
- */
-
-static const __devinitdata struct pci_device_id pcidriver_ids[] = {
-	{ PCI_DEVICE( PCIE_XILINX_VENDOR_ID, PCIE_ML605_DEVICE_ID ) },          // PCI-E Xilinx ML605
-	{ PCI_DEVICE( PCIE_XILINX_VENDOR_ID, PCIE_IPECAMERA_DEVICE_ID ) },      // PCI-E IPE Camera
-	{ PCI_DEVICE( PCIE_XILINX_VENDOR_ID, PCIE_KAPTURE_DEVICE_ID ) },        // PCI-E KAPTURE board for HEB
-	{0,0,0,0},
-};
-
-/* prototypes for internal driver functions */
-int pcidriver_pci_read( pcidriver_privdata_t *privdata, pci_cfg_cmd *pci_cmd );
-int pcidriver_pci_write( pcidriver_privdata_t *privdata, pci_cfg_cmd *pci_cmd );
-int pcidriver_pci_info( pcidriver_privdata_t *privdata, pcilib_board_info_t *pci_info );
-
-int pcidriver_mmap_pci( pcidriver_privdata_t *privdata, struct vm_area_struct *vmap , int bar );
-int pcidriver_mmap_kmem( pcidriver_privdata_t *privdata, struct vm_area_struct *vmap );
-
-/*************************************************************************/
-/* Static data */
-/* Hold the allocated major & minor numbers */
-static dev_t pcidriver_devt;
-
-/* Number of devices allocated */
-static atomic_t pcidriver_deviceCount;
-
-/* Sysfs attributes */
-static DEVICE_ATTR(mmap_mode, (S_IRUGO | S_IWUGO), pcidriver_show_mmap_mode, pcidriver_store_mmap_mode);
-static DEVICE_ATTR(mmap_area, (S_IRUGO | S_IWUGO), pcidriver_show_mmap_area, pcidriver_store_mmap_area);
-static DEVICE_ATTR(kmem_count, S_IRUGO, pcidriver_show_kmem_count, NULL);
-static DEVICE_ATTR(kbuffers, S_IRUGO, pcidriver_show_kbuffers, NULL);
-static DEVICE_ATTR(kmem_alloc, S_IWUGO, NULL, pcidriver_store_kmem_alloc);
-static DEVICE_ATTR(kmem_free, S_IWUGO, NULL, pcidriver_store_kmem_free);
-static DEVICE_ATTR(umappings, S_IRUGO, pcidriver_show_umappings, NULL);
-static DEVICE_ATTR(umem_unmap, S_IWUGO, NULL, pcidriver_store_umem_unmap);
-
-#ifdef ENABLE_IRQ
-static DEVICE_ATTR(irq_count, S_IRUGO, pcidriver_show_irq_count, NULL);
-static DEVICE_ATTR(irq_queues, S_IRUGO, pcidriver_show_irq_queues, NULL);
-#endif
-
-#endif

+ 0 - 108
driver/common.h

@@ -1,108 +0,0 @@
-#ifndef _PCIDRIVER_COMMON_H
-#define _PCIDRIVER_COMMON_H
-
-#include "pcilib_types.h"
-
-/*************************************************************************/
-/* Private data types and structures */
-
-
-/* Define an entry in the kmem list (this list is per device) */
-/* This list keeps references to the allocated kernel buffers */
-typedef struct {
-	int id;
-	enum dma_data_direction direction;
-	
-	struct list_head list;
-	dma_addr_t dma_handle;
-	unsigned long cpua;
-	unsigned long size;
-	unsigned long type;
-	unsigned long align;
-
-	unsigned long use;
-	unsigned long item;
-
-	spinlock_t lock;
-	unsigned long mode;
-	unsigned long refs;
-
-	struct class_device_attribute sysfs_attr;	/* initialized when adding the entry */
-} pcidriver_kmem_entry_t;
-
-/* Define an entry in the umem list (this list is per device) */
-/* This list keeps references to the SG lists for each mapped userspace region */
-typedef struct {
-	int id;
-	struct list_head list;
-	unsigned int nr_pages;		/* number of pages for this user memeory area */
-	struct page **pages;		/* list of pointers to the pages */
-	unsigned int nents;			/* actual entries in the scatter/gatter list (NOT nents for the map function, but the result) */
-	struct scatterlist *sg;		/* list of sg entries */
-	struct class_device_attribute sysfs_attr;	/* initialized when adding the entry */
-} pcidriver_umem_entry_t;
-
-/* Hold the driver private data */
-typedef struct  {
-	dev_t devno;						/* device number (major and minor) */
-	struct pci_dev *pdev;				/* PCI device */
-	struct class_device *class_dev;		/* Class device */
-	struct cdev cdev;					/* char device struct */
-	int mmap_mode;						/* current mmap mode */
-	int mmap_area;						/* current PCI mmap area */
-
-#ifdef ENABLE_IRQ
-	int irq_enabled;					/* Non-zero if IRQ is enabled */
-	int irq_count;						/* Just an IRQ counter */
-
-	wait_queue_head_t irq_queues[ PCIDRIVER_INT_MAXSOURCES ];
-										/* One queue per interrupt source */
-	atomic_t irq_outstanding[ PCIDRIVER_INT_MAXSOURCES ];
-										/* Outstanding interrupts per queue */
-	volatile unsigned int *bars_kmapped[6];		/* PCI BARs mmapped in kernel space */
-
-#endif
-	
-	spinlock_t kmemlist_lock;			/* Spinlock to lock kmem list operations */
-	struct list_head kmem_list;			/* List of 'kmem_list_entry's associated with this device */
-	atomic_t kmem_count;				/* id for next kmem entry */
-
-	int kmem_cur_id;				/* Currently selected kmem buffer, for mmap */
-	
-	spinlock_t umemlist_lock;			/* Spinlock to lock umem list operations */
-	struct list_head umem_list;			/* List of 'umem_list_entry's associated with this device */
-	atomic_t umem_count;				/* id for next umem entry */
-
-	int msi_mode;					/* Flag specifying if interrupt have been initialized in MSI mode */
-	atomic_t refs;					/* Reference counter */
-} pcidriver_privdata_t;
-
-
-void pcidriver_module_get(pcidriver_privdata_t *privdata);
-void pcidriver_module_put(pcidriver_privdata_t *privdata);
-
-/*************************************************************************/
-/* Some nice defines that make code more readable */
-/* This is to print nice info in the log */
-
-#ifdef DEBUG
- #define mod_info( args... ) \
-    do { printk( KERN_INFO "%s - %s : ", MODNAME , __FUNCTION__ );\
-    printk( args ); } while(0)
- #define mod_info_dbg( args... ) \
-    do { printk( KERN_INFO "%s - %s : ", MODNAME , __FUNCTION__ );\
-    printk( args ); } while(0)
-#else
- #define mod_info( args... ) \
-    do { printk( KERN_INFO "%s: ", MODNAME );\
-    printk( args ); } while(0)
- #define mod_info_dbg( args... ) 
-#endif
-
-#define mod_crit( args... ) \
-    do { printk( KERN_CRIT "%s: ", MODNAME );\
-    printk( args ); } while(0)
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#endif

+ 0 - 198
driver/compat.h

@@ -1,198 +0,0 @@
-/**
- *
- * @file compat.h
- * @author Michael Stapelberg
- * @date 2009-04-05
- * @brief Contains compatibility definitions for the different linux kernel versions to avoid
- * putting ifdefs all over the driver code.
- *
- */
-#ifndef _COMPAT_H
-#define _COMPAT_H
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
-# define __devinit
-# define __devexit
-# define __devinitdata
-#endif
-
-/* dev_name is the wrapper one needs to use to access what was formerly called
- * bus_id in struct device. However, before 2.6.27, direct access was necessary,
- * so we provide our own version. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-static inline const char *dev_name(struct device *dev) {
-	return dev->bus_id;
-}
-#endif
-
-/* SetPageLocked disappeared in v2.6.27 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-	#define compat_lock_page SetPageLocked
-	#define compat_unlock_page ClearPageLocked
-#else
-	/* in v2.6.28, __set_page_locked and __clear_page_locked was introduced */
-	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
-		#define compat_lock_page __set_page_locked
-		#define compat_unlock_page __clear_page_locked
-	#else
-		/* However, in v2.6.27 itself, neither of them is there, so
-		 * we need to use our own function fiddling with bits inside
-		 * the page struct :-\ */
-		static inline void compat_lock_page(struct page *page) {
-			__set_bit(PG_locked, &page->flags);
-		}
-
-		static inline void compat_unlock_page(struct page *page) {
-			__clear_bit(PG_locked, &page->flags);
-		}
-	#endif
-#endif
-
-/* Before 2.6.13, simple_class was the standard interface. Nowadays, it's just called class */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
-
-	#define class_compat class_simple
-
-	/* These functions are redirected to their old corresponding functions */
-	#define class_create(module, name) class_simple_create(module, name)
-	#define class_destroy(type) class_simple_destroy(type)
-	#define class_device_destroy(unused, devno) class_simple_device_remove(devno)
-	#define class_device_create(type, unused, devno, devpointer, nameformat, minor, unused) \
-		class_simple_device_add(type, devno, devpointer, nameformat, minor)
-	#define class_set_devdata(classdev, privdata) classdev->class_data = privdata
-	#define DEVICE_ATTR_COMPAT
-	#define sysfs_attr_def_name(name) class_device_attr_##name
-	#define sysfs_attr_def_pointer privdata->class_dev
-	#define SYSFS_GET_FUNCTION(name) ssize_t name(struct class_device *cls, char *buf)
-	#define SYSFS_SET_FUNCTION(name) ssize_t name(struct class_device *cls, const char *buf, size_t count)
-	#define SYSFS_GET_PRIVDATA (pcidriver_privdata_t*)cls->class_data
-
-#else
-
-/* In 2.6.26, device.h was changed quite significantly. Luckily, it only affected
-   type/function names, for the most part. */
-//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-	#define class_device_attribute device_attribute
-	#define CLASS_DEVICE_ATTR DEVICE_ATTR
-	#define class_device device
-	#define class_data dev
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-	#define class_device_create(type, parent, devno, devpointer, nameformat, minor, privdata) \
-		device_create(type, parent, devno, privdata, nameformat, minor)
-#else
-	#define class_device_create(type, parent, devno, devpointer, nameformat, minor, unused) \
-		device_create(type, parent, devno, nameformat, minor)
-#endif
-	#define class_device_create_file device_create_file
-	#define class_device_remove_file device_remove_file
-	#define class_device_destroy device_destroy
-	#define DEVICE_ATTR_COMPAT struct device_attribute *attr,
-	#define class_set_devdata dev_set_drvdata
-
-	#define sysfs_attr_def_name(name) dev_attr_##name
-	#define sysfs_attr_def_pointer privdata->class_dev
-	#define SYSFS_GET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, char *buf)
-	#define SYSFS_SET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-	#define SYSFS_GET_PRIVDATA dev_get_drvdata(dev)
-
-//#endif
-
-#define class_compat class
-
-#endif
-
-/* The arguments of IRQ handlers have been changed in 2.6.19. It's very likely that
-   int irq will disappear somewhen in the future (current is 2.6.29), too. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-	#define IRQ_HANDLER_FUNC(name) irqreturn_t name(int irq, void *dev_id)
-#else
-	#define IRQ_HANDLER_FUNC(name) irqreturn_t name(int irq, void *dev_id, struct pt_regs *regs)
-#endif
-
-/* atomic_inc_return appeared in 2.6.9, at least in CERN scientific linux, provide
-   compatibility wrapper for older kernels */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
-static int atomic_inc_return(atomic_t *variable) {
-	atomic_inc(variable);
-	return atomic_read(variable);
-}
-#endif
-
-/* sg_set_page is available starting at 2.6.24 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-
-#define sg_set_page(sg, set_page, set_length, set_offset) do { \
-	(sg)->page = set_page; \
-	(sg)->length = set_length; \
-	(sg)->offset = set_offset; \
-} while (0)
-
-#endif
-
-/* Before 2.6.20, disable was not an atomic counter, so this check was needed */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-#define pci_disable_device(pdev) do { \
-	if (pdev->is_enabled) \
-		pci_disable_device(pdev); \
-} while (0)
-#endif
-
-/* Before 2.6.24, scatter/gather lists did not need to be initialized */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-	#define sg_init_table(sg, nr_pages)
-#endif
-
-/* SA_SHIRQ was renamed to IRQF_SHARED in 2.6.24 */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-	#define request_irq(irq, irq_handler, modname, privdata) request_irq(irq, irq_handler, IRQF_SHARED, modname, privdata)
-#else
-	#define request_irq(irq, irq_handler, modname, privdata) request_irq(irq, irq_handler, SA_SHIRQ, modname, privdata)
-#endif
-
-/* In 2.6.13, io_remap_page_range was removed in favor for io_remap_pfn_range which works on
-   more platforms and allows more memory space */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-#define io_remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
-	io_remap_pfn_range(vmap, vm_start, (bar_addr >> PAGE_SHIFT), bar_length, vm_page_prot)
-#else
-#define io_remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
-	io_remap_page_range(vmap, vm_start, bar_addr, bar_length, vm_page_prot)
-#endif
-
-/* In 2.6.10, remap_pfn_range was introduced, see io_remap_pfn_range_compat */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-#define remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
-	remap_pfn_range(vmap, vm_start, (bar_addr >> PAGE_SHIFT), bar_length, vm_page_prot)
-
-#define remap_pfn_range_cpua_compat(vmap, vm_start, cpua, size, vm_page_prot) \
-	remap_pfn_range(vmap, vm_start, page_to_pfn(virt_to_page((void*)cpua)), size, vm_page_prot)
-
-#else
-#define remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \
-	remap_page_range(vmap, vm_start, bar_addr, bar_length, vm_page_prot)
-
-#define remap_pfn_range_cpua_compat(vmap, vm_start, cpua, size, vm_page_prot) \
-	remap_page_range(vmap, vm_start, virt_to_phys((void*)cpua), size, vm_page_prot)
-#endif
-
-/**
- * Go over the pages of the kmem buffer, and mark them as reserved.
- * This is needed, otherwise mmaping the kernel memory to user space
- * will fail silently (mmaping /dev/null) when using remap_xx_range.
- */
-static inline void set_pages_reserved_compat(unsigned long cpua, unsigned long size)
-{
-	/* Starting in 2.6.15, the PG_RESERVED bit was removed.
-	   See also http://lwn.net/Articles/161204/ */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-	struct page *page, *last_page;
-
-	page = virt_to_page(cpua);
-	last_page = virt_to_page(cpua + size - 1);
-
-	for (; page <= last_page; page++)
-               SetPageReserved(page);
-#endif
-}
-
-#endif

+ 0 - 23
driver/config.h

@@ -1,23 +0,0 @@
-/*******************************/
-/* Configuration of the driver */
-/*******************************/
-
-/* Debug messages */
-//#define DEBUG
-
-/* Enable/disable IRQ handling */
-#define ENABLE_IRQ
-
-/* The name of the module */
-#define MODNAME "pciDriver"
-
-/* Major number is allocated dynamically */
-/* Minor number */
-#define MINORNR 0
-
-/* Node name of the char device */
-#define NODENAME "fpga"
-#define NODENAMEFMT "fpga%d"
-
-/* Maximum number of devices*/
-#define MAXDEVICES 4

+ 0 - 258
driver/int.c

@@ -1,258 +0,0 @@
-/**
- *
- * @file int.c
- * @author Guillermo Marcus
- * @date 2009-04-05
- * @brief Contains the interrupt handler.
- *
- */
-
-/*
- * Change History:
- * 
- * $Log: not supported by cvs2svn $
- * Revision 1.7  2008-01-11 10:18:28  marcus
- * Modified interrupt mechanism. Added atomic functions and queues, to address race conditions. Removed unused interrupt code.
- *
- * Revision 1.6  2007-11-04 20:58:22  marcus
- * Added interrupt generator acknowledge.
- * Fixed wrong operator.
- *
- * Revision 1.5  2007-10-31 15:42:21  marcus
- * Added IG ack for testing, may be removed later.
- *
- * Revision 1.4  2007-07-17 13:15:56  marcus
- * Removed Tasklets.
- * Using newest map for the ABB interrupts.
- *
- * Revision 1.3  2007-07-05 15:30:30  marcus
- * Added support for both register maps of the ABB.
- *
- * Revision 1.2  2007-05-29 07:50:18  marcus
- * Split code into 2 files. May get merged in the future again....
- *
- * Revision 1.1  2007/03/01 16:57:43  marcus
- * Divided driver file to ease the interrupt hooks for the user of the driver.
- * Modified Makefile accordingly.
- *
- */
-
-#include <linux/version.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/cdev.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <stdbool.h>
-
-#include "config.h"
-
-#include "compat.h"
-
-#include "pciDriver.h"
-
-#include "common.h"
-
-#include "int.h"
-
-/*
- * The ID between IRQ_SOURCE in irq_outstanding and the actual source is arbitrary.
- * Therefore, be careful when communicating with multiple implementations. 
- */
-
-/* IRQ_SOURCES */
-#define ABB_IRQ_CH0 	        0
-#define ABB_IRQ_CH1 	        1
-#define ABB_IRQ_IG 	        2
-
-/* See ABB user’s guide, register definitions (3.1) */
-#define ABB_INT_ENABLE 	        (0x0010 >> 2)
-#define ABB_INT_STAT 	        (0x0008 >> 2)
-
-#define ABB_INT_CH1_TIMEOUT     (1 << 4)
-#define ABB_INT_CH0_TIMEOUT     (1 << 5)
-#define ABB_INT_IG  	        (1 << 2)
-#define ABB_INT_CH0 	        (1 << 1) /* downstream */
-#define ABB_INT_CH1 	        (1)     /* upstream */
-
-#define ABB_CH0_CTRL  	        (108 >> 2)
-#define ABB_CH1_CTRL  	        (72 >> 2)
-#define ABB_CH_RESET 	        (0x0201000A)
-#define ABB_IG_CTRL 	        (0x0080 >> 2)
-#define ABB_IG_ACK 	        (0x00F0)
-
-/**
- *
- * If IRQ-handling is enabled, this function will be called from pcidriver_probe
- * to initialize the IRQ handling (maps the BARs)
- *
- */
-int pcidriver_probe_irq(pcidriver_privdata_t *privdata)
-{
-	unsigned char int_pin, int_line;
-	unsigned long bar_addr, bar_len, bar_flags;
-	int i;
-	int err;
-
-	for (i = 0; i < 6; i++)
-		privdata->bars_kmapped[i] = NULL;
-
-	for (i = 0; i < 6; i++) {
-		bar_addr = pci_resource_start(privdata->pdev, i);
-		bar_len = pci_resource_len(privdata->pdev, i);
-		bar_flags = pci_resource_flags(privdata->pdev, i);
-
-		/* check if it is a valid BAR, skip if not */
-		if ((bar_addr == 0) || (bar_len == 0))
-			continue;
-
-		/* Skip IO regions (map only mem regions) */
-		if (bar_flags & IORESOURCE_IO)
-			continue;
-
-		/* Check if the region is available */
-		if ((err = pci_request_region(privdata->pdev, i, NULL)) != 0) {
-			mod_info( "Failed to request BAR memory region.\n" );
-			return err;
-		}
-
-		/* Map it into kernel space. */
-		/* For x86 this is just a dereference of the pointer, but that is
-		 * not portable. So we need to do the portable way. Thanks Joern!
-		 */
-
-		/* respect the cacheable-bility of the region */
-		if (bar_flags & IORESOURCE_PREFETCH)
-			privdata->bars_kmapped[i] = ioremap(bar_addr, bar_len);
-		else
-			privdata->bars_kmapped[i] = ioremap_nocache(bar_addr, bar_len);
-
-		/* check for error */
-		if (privdata->bars_kmapped[i] == NULL) {
-			mod_info( "Failed to remap BAR%d into kernel space.\n", i );
-			return -EIO;
-		}
-	}
-
-	/* Initialize the interrupt handler for this device */
-	/* Initialize the wait queues */
-	for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++) {
-		init_waitqueue_head(&(privdata->irq_queues[i]));
-		atomic_set(&(privdata->irq_outstanding[i]), 0);
-	}
-
-	/* Initialize the irq config */
-	if ((err = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_PIN, &int_pin)) != 0) {
-		/* continue without interrupts */
-		int_pin = 0;
-		mod_info("Error getting the interrupt pin. Disabling interrupts for this device\n");
-	}
-
-	/* Disable interrupts and activate them if everything can be set up properly */
-	privdata->irq_enabled = 0;
-
-	if (int_pin == 0)
-		return 0;
-
-	if ((err = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_LINE, &int_line)) != 0) {
-		mod_info("Error getting the interrupt line. Disabling interrupts for this device\n");
-		return 0;
-	}
-
-	/* Enable interrupts using MSI mode */
-	if (!pci_enable_msi(privdata->pdev)) 
-		privdata->msi_mode = 1;
-	
-	/* register interrupt handler */
-	if ((err = request_irq(privdata->pdev->irq, pcidriver_irq_handler, MODNAME, privdata)) != 0) {
-		mod_info("Error registering the interrupt handler. Disabling interrupts for this device\n");
-		return 0;
-	}
-
-	privdata->irq_enabled = 1;
-	mod_info("Registered Interrupt Handler at pin %i, line %i, IRQ %i\n", int_pin, int_line, privdata->pdev->irq );
-
-	return 0;
-}
-
-/**
- *
- * Frees/cleans up the data structures, called from pcidriver_remove()
- *
- */
-void pcidriver_remove_irq(pcidriver_privdata_t *privdata)
-{
-	/* Release the IRQ handler */
-	if (privdata->irq_enabled != 0)
-		free_irq(privdata->pdev->irq, privdata);
-	
-	if (privdata->msi_mode) {
-		pci_disable_msi(privdata->pdev);
-		privdata->msi_mode = 0;
-	}
-
-	pcidriver_irq_unmap_bars(privdata);
-}
-
-/**
- *
- * Unmaps the BARs and releases them
- *
- */
-void pcidriver_irq_unmap_bars(pcidriver_privdata_t *privdata)
-{
-	int i;
-
-	for (i = 0; i < 6; i++) {
-		if (privdata->bars_kmapped[i] == NULL)
-			continue;
-
-		iounmap((void*)privdata->bars_kmapped[i]);
-		pci_release_region(privdata->pdev, i);
-	}
-}
-
-/**
- *
- * Acknowledges the receival of an interrupt to the card.
- *
- * @returns true if the card was acknowledget
- * @returns false if the interrupt was not for one of our cards
- *
- * @see check_acknowlegde_channel
- *
- */
-static bool pcidriver_irq_acknowledge(pcidriver_privdata_t *privdata)
-{
-	int channel = 0;
-//	volatile unsigned int *bar;
-//	bar = privdata->bars_kmapped[0];
-//	mod_info_dbg("interrupt registers. ISR: %x, IER: %x\n", bar[ABB_INT_STAT], bar[ABB_INT_ENABLE]);
-
-	atomic_inc(&(privdata->irq_outstanding[channel]));
-	wake_up_interruptible(&(privdata->irq_queues[channel]));
-	
-	return true;
-}
-
-/**
- *
- * Handles IRQs. At the moment, this acknowledges the card that this IRQ
- * was received and then increases the driver's IRQ counter.
- *
- * @see pcidriver_irq_acknowledge
- *
- */
-IRQ_HANDLER_FUNC(pcidriver_irq_handler)
-{
-	pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)dev_id;
-
-	if (!pcidriver_irq_acknowledge(privdata))
-		return IRQ_NONE;
-
-	privdata->irq_count++;
-	return IRQ_HANDLED;
-}

+ 0 - 9
driver/int.h

@@ -1,9 +0,0 @@
-#if !defined(_PCIDRIVER_INT_H) && defined(ENABLE_IRQ)
-#define _PCIDRIVER_INT_H
-
-int pcidriver_probe_irq(pcidriver_privdata_t *privdata);
-void pcidriver_remove_irq(pcidriver_privdata_t *privdata);
-void pcidriver_irq_unmap_bars(pcidriver_privdata_t *privdata);
-IRQ_HANDLER_FUNC(pcidriver_irq_handler);
-
-#endif

+ 0 - 471
driver/ioctl.c

@@ -1,471 +0,0 @@
-/**
- *
- * @file ioctl.c
- * @author Guillermo Marcus
- * @date 2009-04-05
- * @brief Contains the functions handling the different ioctl calls.
- *
- */
-#include <linux/version.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/sysfs.h>
-#include <asm/atomic.h>
-#include <linux/pagemap.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <asm/scatterlist.h>
-#include <linux/vmalloc.h>
-#include <linux/stat.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-
-#include "config.h" 			/* Configuration for the driver */
-#include "compat.h" 			/* Compatibility functions/definitions */
-#include "pciDriver.h" 			/* External interface for the driver */
-#include "common.h" 			/* Internal definitions for all parts */
-#include "kmem.h" 			/* Internal definitions for kernel memory */
-#include "umem.h" 			/* Internal definitions for user space memory */
-#include "ioctl.h"			/* Internal definitions for the ioctl part */
-
-/** Declares a variable of the given type with the given name and copies it from userspace */
-#define READ_FROM_USER(type, name) \
-	type name; \
-	if ((ret = copy_from_user(&name, (type*)arg, sizeof(name))) != 0) \
-		return -EFAULT;
-
-/** Writes back the given variable with the given type to userspace */
-#define WRITE_TO_USER(type, name) \
-	if ((ret = copy_to_user((type*)arg, &name, sizeof(name))) != 0) \
-		return -EFAULT;
-
-/**
- *
- * Sets the mmap mode for following mmap() calls.
- *
- * @param arg Not a pointer, but either PCIDRIVER_MMAP_PCI or PCIDRIVER_MMAP_KMEM
- *
- */
-static int ioctl_mmap_mode(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	if ((arg != PCIDRIVER_MMAP_PCI) && (arg != PCIDRIVER_MMAP_KMEM))
-		return -EINVAL;
-
-	/* change the mode */
-	privdata->mmap_mode = arg;
-
-	return 0;
-}
-
-/**
- *
- * Sets the mmap area (BAR) for following mmap() calls.
- *
- */
-static int ioctl_mmap_area(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	/* validate input */
-	if ((arg < PCIDRIVER_BAR0) || (arg > PCIDRIVER_BAR5))
-		return -EINVAL;
-
-	/* change the PCI area to mmap */
-	privdata->mmap_area = arg;
-
-	return 0;
-}
-
-/**
- *
- * Reads/writes a byte/word/dword of the device's PCI config.
- *
- * @see pcidriver_pci_read
- * @see pcidriver_pci_write
- *
- */
-static int ioctl_pci_config_read_write(pcidriver_privdata_t *privdata, unsigned int cmd, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(pci_cfg_cmd, pci_cmd);
-
-	if (cmd == PCIDRIVER_IOC_PCI_CFG_RD) {
-		switch (pci_cmd.size) {
-			case PCIDRIVER_PCI_CFG_SZ_BYTE:
-				ret = pci_read_config_byte( privdata->pdev, pci_cmd.addr, &(pci_cmd.val.byte) );
-				break;
-			case PCIDRIVER_PCI_CFG_SZ_WORD:
-				ret = pci_read_config_word( privdata->pdev, pci_cmd.addr, &(pci_cmd.val.word) );
-				break;
-			case PCIDRIVER_PCI_CFG_SZ_DWORD:
-				ret = pci_read_config_dword( privdata->pdev, pci_cmd.addr, &(pci_cmd.val.dword) );
-				break;
-			default:
-				return -EINVAL;		/* Wrong size setting */
-		}
-	} else {
-		switch (pci_cmd.size) {
-			case PCIDRIVER_PCI_CFG_SZ_BYTE:
-				ret = pci_write_config_byte( privdata->pdev, pci_cmd.addr, pci_cmd.val.byte );
-				break;
-			case PCIDRIVER_PCI_CFG_SZ_WORD:
-				ret = pci_write_config_word( privdata->pdev, pci_cmd.addr, pci_cmd.val.word );
-				break;
-			case PCIDRIVER_PCI_CFG_SZ_DWORD:
-				ret = pci_write_config_dword( privdata->pdev, pci_cmd.addr, pci_cmd.val.dword );
-				break;
-			default:
-				return -EINVAL;		/* Wrong size setting */
-				break;
-		}
-	}
-
-	WRITE_TO_USER(pci_cfg_cmd, pci_cmd);
-
-	return 0;
-}
-
-/**
- *
- * Gets the PCI information for the device.
- *
- * @see pcidriver_pci_info
- *
- */
-static int ioctl_pci_info(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	int bar;
-	READ_FROM_USER(pcilib_board_info_t, pci_info);
-
-	pci_info.vendor_id = privdata->pdev->vendor;
-	pci_info.device_id = privdata->pdev->device;
-	pci_info.bus = privdata->pdev->bus->number;
-	pci_info.slot = PCI_SLOT(privdata->pdev->devfn);
-	pci_info.devfn = privdata->pdev->devfn;
-	pci_info.func = PCI_FUNC(privdata->pdev->devfn);
-
-	if ((ret = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_PIN, &(pci_info.interrupt_pin))) != 0)
-		return ret;
-
-	if ((ret = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_LINE, &(pci_info.interrupt_line))) != 0)
-		return ret;
-
-	for (bar = 0; bar < 6; bar++) {
-		pci_info.bar_start[bar] = pci_resource_start(privdata->pdev, bar);
-		pci_info.bar_length[bar] = pci_resource_len(privdata->pdev, bar);
-		pci_info.bar_flags[bar] = pci_resource_flags(privdata->pdev, bar);
-	}
-
-	WRITE_TO_USER(pcilib_board_info_t, pci_info);
-
-	return 0;
-}
-
-/**
- *
- * Allocates kernel memory.
- *
- * @see pcidriver_kmem_alloc
- *
- */
-static int ioctl_kmem_alloc(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(kmem_handle_t, khandle);
-
-	if ((ret = pcidriver_kmem_alloc(privdata, &khandle)) != 0)
-		return ret;
-
-	WRITE_TO_USER(kmem_handle_t, khandle);
-
-	return 0;
-}
-
-/**
- *
- * Frees kernel memory.
- *
- * @see pcidriver_kmem_free
- *
- */
-static int ioctl_kmem_free(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(kmem_handle_t, khandle);
-
-	if ((ret = pcidriver_kmem_free(privdata, &khandle)) != 0)
-		return ret;
-
-	return 0;
-}
-
-/**
- *
- * Syncs kernel memory.
- *
- * @see pcidriver_kmem_sync
- *
- */
-static int ioctl_kmem_sync(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(kmem_sync_t, ksync);
-
-	if ((ret =  pcidriver_kmem_sync(privdata, &ksync)) != 0)
-	    return ret;
-	
-	WRITE_TO_USER(kmem_sync_t, ksync);
-	
-	return 0;
-}
-
-/*
- *
- * Maps the given scatter/gather list from memory to PCI bus addresses.
- *
- * @see pcidriver_umem_sgmap
- *
- */
-static int ioctl_umem_sgmap(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(umem_handle_t, uhandle);
-
-	if ((ret = pcidriver_umem_sgmap(privdata, &uhandle)) != 0)
-		return ret;
-
-	WRITE_TO_USER(umem_handle_t, uhandle);
-
-	return 0;
-}
-
-/**
- *
- * Unmaps the given scatter/gather list.
- *
- * @see pcidriver_umem_sgunmap
- *
- */
-static int ioctl_umem_sgunmap(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	pcidriver_umem_entry_t *umem_entry;
-	READ_FROM_USER(umem_handle_t, uhandle);
-
-	/* Find the associated umem_entry for this buffer,
-	 * return -EINVAL if the specified handle id is invalid */
-	if ((umem_entry = pcidriver_umem_find_entry_id(privdata, uhandle.handle_id)) == NULL)
-		return -EINVAL;
-
-	if ((ret = pcidriver_umem_sgunmap(privdata, umem_entry)) != 0)
-		return ret;
-
-	return 0;
-}
-
-/**
- *
- * Copies the scatter/gather list from kernelspace to userspace.
- *
- * @see pcidriver_umem_sgget
- *
- */
-static int ioctl_umem_sgget(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(umem_sglist_t, usglist);
-
-	/* The umem_sglist_t has a pointer to the scatter/gather list itself which
-	 * needs to be copied separately. The number of elements is stored in ->nents.
-	 * As the list can get very big, we need to use vmalloc. */
-	if ((usglist.sg = vmalloc(usglist.nents * sizeof(umem_sgentry_t))) == NULL)
-		return -ENOMEM;
-
-	/* copy array to kernel structure */
-	ret = copy_from_user(usglist.sg, ((umem_sglist_t *)arg)->sg, (usglist.nents)*sizeof(umem_sgentry_t));
-	if (ret) return -EFAULT;
-
-	if ((ret = pcidriver_umem_sgget(privdata, &usglist)) != 0)
-		return ret;
-
-	/* write data to user space */
-	ret = copy_to_user(((umem_sglist_t *)arg)->sg, usglist.sg, (usglist.nents)*sizeof(umem_sgentry_t));
-	if (ret) return -EFAULT;
-
-	/* free array memory */
-	vfree(usglist.sg);
-
-	/* restore sg pointer to vma address in user space before copying */
-	usglist.sg = ((umem_sglist_t *)arg)->sg;
-
-	WRITE_TO_USER(umem_sglist_t, usglist);
-
-	return 0;
-}
-
-/**
- *
- * Syncs user memory.
- *
- * @see pcidriver_umem_sync
- *
- */
-static int ioctl_umem_sync(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-	int ret;
-	READ_FROM_USER(umem_handle_t, uhandle);
-
-	return pcidriver_umem_sync( privdata, &uhandle );
-}
-
-/**
- *
- * Waits for an interrupt
- *
- * @param arg Not a pointer, but the irq source to wait for (unsigned int)
- *
- */
-static int ioctl_wait_interrupt(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-#ifdef ENABLE_IRQ
-	int ret;
-	unsigned long timeout;
-	unsigned int irq_source;
-	unsigned long temp = 0;
-
-	READ_FROM_USER(interrupt_wait_t, irq_handle);
-
-	irq_source = irq_handle.source;
-
-	if (irq_source >= PCIDRIVER_INT_MAXSOURCES)
-		return -EFAULT;						/* User tried to overrun the IRQ_SOURCES array */
-
-	timeout = jiffies + (irq_handle.timeout * HZ / 1000000);
-
-	/* Thanks to Joern for the correction and tips! */
-	/* done this way to avoid wrong behaviour (endless loop) of the compiler in AMD platforms */
-	do {
-		/* We wait here with an interruptible timeout. This will be interrupted
-                 * by int.c:check_acknowledge_channel() as soon as in interrupt for
-                 * the specified source arrives. */
-		wait_event_interruptible_timeout( (privdata->irq_queues[irq_source]), (atomic_read(&(privdata->irq_outstanding[irq_source])) > 0), (10*HZ/1000) );
-
-		if (atomic_add_negative( -1, &(privdata->irq_outstanding[irq_source])) )
-			atomic_inc( &(privdata->irq_outstanding[irq_source]) );
-		else
-			temp = 1;
-	} while ((!temp)&&(jiffies < timeout));
-	
-	if ((temp)&&(irq_handle.count)) {
-	    while (!atomic_add_negative( -1, &(privdata->irq_outstanding[irq_source]))) temp++;
-	    atomic_inc( &(privdata->irq_outstanding[irq_source]) );
-	}
-	
-	irq_handle.count = temp;
-
-	WRITE_TO_USER(interrupt_wait_t, irq_handle);
-
-	return 0;
-#else
-	mod_info("Asked to wait for interrupt but interrupts are not enabled in the driver\n");
-	return -EFAULT;
-#endif
-}
-
-/**
- *
- * Clears the interrupt wait queue.
- *
- * @param arg Not a pointer, but the irq source (unsigned int)
- * @returns -EFAULT if the user specified an irq source out of range
- *
- */
-static int ioctl_clear_ioq(pcidriver_privdata_t *privdata, unsigned long arg)
-{
-#ifdef ENABLE_IRQ
-	unsigned int irq_source;
-
-	if (arg >= PCIDRIVER_INT_MAXSOURCES)
-		return -EFAULT;
-
-	irq_source = arg;
-	atomic_set(&(privdata->irq_outstanding[irq_source]), 0);
-
-	return 0;
-#else
-	mod_info("Asked to wait for interrupt but interrupts are not enabled in the driver\n");
-	return -EFAULT;
-#endif
-}
-
-/**
- *
- * This function handles all ioctl file operations.
- * Generally, the data of the ioctl is copied from userspace to kernelspace, a separate
- * function is called to handle the ioctl itself, then the data is copied back to userspace.
- *
- * @returns -EFAULT when an invalid memory pointer is passed
- *
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-int pcidriver_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-#else
-long pcidriver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-#endif
-{
-	pcidriver_privdata_t *privdata = filp->private_data;
-
-	/* Select the appropiate command */
-	switch (cmd) {
-		case PCIDRIVER_IOC_MMAP_MODE:
-			return ioctl_mmap_mode(privdata, arg);
-
-		case PCIDRIVER_IOC_MMAP_AREA:
-			return ioctl_mmap_area(privdata, arg);
-
-		case PCIDRIVER_IOC_PCI_CFG_RD:
-		case PCIDRIVER_IOC_PCI_CFG_WR:
-			return ioctl_pci_config_read_write(privdata, cmd, arg);
-
-		case PCIDRIVER_IOC_PCI_INFO:
-			return ioctl_pci_info(privdata, arg);
-
-		case PCIDRIVER_IOC_KMEM_ALLOC:
-			return ioctl_kmem_alloc(privdata, arg);
-
-		case PCIDRIVER_IOC_KMEM_FREE:
-			return ioctl_kmem_free(privdata, arg);
-
-		case PCIDRIVER_IOC_KMEM_SYNC:
-			return ioctl_kmem_sync(privdata, arg);
-
-		case PCIDRIVER_IOC_UMEM_SGMAP:
-			return ioctl_umem_sgmap(privdata, arg);
-
-		case PCIDRIVER_IOC_UMEM_SGUNMAP:
-			return ioctl_umem_sgunmap(privdata, arg);
-
-		case PCIDRIVER_IOC_UMEM_SGGET:
-			return ioctl_umem_sgget(privdata, arg);
-
-		case PCIDRIVER_IOC_UMEM_SYNC:
-			return ioctl_umem_sync(privdata, arg);
-
-		case PCIDRIVER_IOC_WAITI:
-			return ioctl_wait_interrupt(privdata, arg);
-
-		case PCIDRIVER_IOC_CLEAR_IOQ:
-			return ioctl_clear_ioq(privdata, arg);
-
-		default:
-			return -EINVAL;
-	}
-}

+ 0 - 5
driver/ioctl.h

@@ -1,5 +0,0 @@
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-int pcidriver_ioctl(struct inode  *inode, struct file *filp, unsigned int cmd, unsigned long arg);
-#else
-long pcidriver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
-#endif

+ 0 - 657
driver/kmem.c

@@ -1,657 +0,0 @@
-/**
- *
- * @file kmem.c
- * @brief This file contains all functions dealing with kernel memory.
- * @author Guillermo Marcus
- * @date 2009-04-05
- *
- */
-#include <linux/version.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/cdev.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-
-#include "config.h"			/* compile-time configuration */
-#include "compat.h"			/* compatibility definitions for older linux */
-#include "pciDriver.h"			/* external interface for the driver */
-#include "common.h"			/* internal definitions for all parts */
-#include "kmem.h"			/* prototypes for kernel memory */
-#include "sysfs.h"			/* prototypes for sysfs */
-
-/* VM_RESERVED is removed in 3.7-rc1 */
-#ifndef VM_RESERVED
-# define  VM_RESERVED   (VM_DONTEXPAND | VM_DONTDUMP)
-#endif
-
-/**
- *
- * Allocates new kernel memory including the corresponding management structure, makes
- * it available via sysfs if possible.
- *
- */
-int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle)
-{
-	int flags;
-	pcidriver_kmem_entry_t *kmem_entry;
-	void *retptr;
-
-	if (kmem_handle->flags&KMEM_FLAG_REUSE) {
-	    kmem_entry = pcidriver_kmem_find_entry_use(privdata, kmem_handle->use, kmem_handle->item);
-	    if (kmem_entry) {
-		unsigned long flags = kmem_handle->flags;
-		
-		if (flags&KMEM_FLAG_TRY) {
-		    kmem_handle->type = kmem_entry->type;
-		    kmem_handle->size = kmem_entry->size;
-		    kmem_handle->align = kmem_entry->align;
-		} else {
-		    if (kmem_handle->type != kmem_entry->type) {
-		    	mod_info("Invalid type of reusable kmem_entry, currently: %lu, but requested: %lu\n", kmem_entry->type, kmem_handle->type);
-			return -EINVAL;
-		    }
-
-		    if ((kmem_handle->type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_PAGE) {
-			    kmem_handle->size = kmem_entry->size;
-		    } else if (kmem_handle->size != kmem_entry->size) {
-			mod_info("Invalid size of reusable kmem_entry, currently: %lu, but requested: %lu\n", kmem_entry->size, kmem_handle->size);
-			return -EINVAL;
-		    }
-		    
-		    if (kmem_handle->align != kmem_entry->align) {
-			mod_info("Invalid alignment of reusable kmem_entry, currently: %lu, but requested: %lu\n", kmem_entry->align, kmem_handle->align);
-			return -EINVAL;
-		    }
-
-		    if (((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)?1:0) != ((flags&KMEM_FLAG_EXCLUSIVE)?1:0)) {
-			mod_info("Invalid mode of reusable kmem_entry\n");
-			return -EINVAL;
-		    }
-		}
-		
-
-		if ((kmem_entry->mode&KMEM_MODE_COUNT)==KMEM_MODE_COUNT) {
-			mod_info("Reuse counter of kmem_entry is overflown");
-			return -EBUSY;
-		}
-		
-		
-		kmem_handle->handle_id = kmem_entry->id;
-		kmem_handle->pa = (unsigned long)(kmem_entry->dma_handle);
-
-		kmem_handle->flags = KMEM_FLAG_REUSED;
-		if (kmem_entry->refs&KMEM_REF_HW) kmem_handle->flags |= KMEM_FLAG_REUSED_HW;
-		if (kmem_entry->mode&KMEM_MODE_PERSISTENT) kmem_handle->flags |= KMEM_FLAG_REUSED_PERSISTENT;
-
-		kmem_entry->mode += 1;
-		if (flags&KMEM_FLAG_HW) {
-		    if ((kmem_entry->refs&KMEM_REF_HW)==0)
-			pcidriver_module_get(privdata);
-			
-		    kmem_entry->refs |= KMEM_REF_HW;
-		}
-		if (flags&KMEM_FLAG_PERSISTENT) kmem_entry->mode |= KMEM_MODE_PERSISTENT;
-
-		privdata->kmem_cur_id = kmem_entry->id;
-		
-		return 0;
-	    }
-	    
-	    if (kmem_handle->flags&KMEM_FLAG_TRY) return -ENOENT;
-	}
-
-	/* First, allocate zeroed memory for the kmem_entry */
-	if ((kmem_entry = kcalloc(1, sizeof(pcidriver_kmem_entry_t), GFP_KERNEL)) == NULL)
-		goto kmem_alloc_entry_fail;
-
-	/* Initialize the kmem_entry */
-	kmem_entry->id = atomic_inc_return(&privdata->kmem_count) - 1;
-	privdata->kmem_cur_id = kmem_entry->id;
-	kmem_handle->handle_id = kmem_entry->id;
-
-	kmem_entry->use = kmem_handle->use;
-	kmem_entry->item = kmem_handle->item;
-	kmem_entry->type = kmem_handle->type;
-	kmem_entry->align = kmem_handle->align;
-	kmem_entry->direction = PCI_DMA_NONE;
-
-	/* Initialize sysfs if possible */
-	if (pcidriver_sysfs_initialize_kmem(privdata, kmem_entry->id, &(kmem_entry->sysfs_attr)) != 0)
-		goto kmem_alloc_mem_fail;
-
-	/* ...and allocate the DMA memory */
-	/* note this is a memory pair, referencing the same area: the cpu address (cpua)
-	 * and the PCI bus address (pa). The CPU and PCI addresses may not be the same.
-	 * The CPU sees only CPU addresses, while the device sees only PCI addresses.
-	 * CPU address is used for the mmap (internal to the driver), and
-	 * PCI address is the address passed to the DMA Controller in the device.
-	 */
-	switch (kmem_entry->type&PCILIB_KMEM_TYPE_MASK) {
-	 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:
-	    flags = GFP_KERNEL;
-
-	    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(flags, get_order(kmem_handle->size));
-	    kmem_entry->dma_handle = 0;
-	    
-	    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, kmem_handle->size, PCI_DMA_TODEVICE);
-		    if (pci_dma_mapping_error(privdata->pdev, kmem_entry->dma_handle)) {
-			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, kmem_handle->size, PCI_DMA_FROMDEVICE);
-		    if (pci_dma_mapping_error(privdata->pdev, kmem_entry->dma_handle)) {
-			free_pages((unsigned long)retptr, get_order(kmem_handle->size));
-			goto kmem_alloc_mem_fail;
-		    
-		    }
-		}
-	    }
-	    
-	    break;
-	 default:
-	    goto kmem_alloc_mem_fail;
-	}
-	
-	
-	if (retptr == NULL)
-		goto kmem_alloc_mem_fail;
-
-	kmem_entry->size = kmem_handle->size;
-	kmem_entry->cpua = (unsigned long)retptr;
-	kmem_handle->pa = (unsigned long)(kmem_entry->dma_handle);
-
-	kmem_entry->mode = 1;
-	if (kmem_handle->flags&KMEM_FLAG_REUSE) {
-	    kmem_entry->mode |= KMEM_MODE_REUSABLE;
-	    if (kmem_handle->flags&KMEM_FLAG_EXCLUSIVE) kmem_entry->mode |= KMEM_MODE_EXCLUSIVE;
-	    if (kmem_handle->flags&KMEM_FLAG_PERSISTENT) kmem_entry->mode |= KMEM_MODE_PERSISTENT;
-	}
-	
-	kmem_entry->refs = 0;
-	if (kmem_handle->flags&KMEM_FLAG_HW) {
-	    pcidriver_module_get(privdata);
-
-	    kmem_entry->refs |= KMEM_REF_HW;
-	}
-
-        kmem_handle->flags = 0;
-	
-	set_pages_reserved_compat(kmem_entry->cpua, kmem_entry->size);
-
-	/* Add the kmem_entry to the list of the device */
-	spin_lock( &(privdata->kmemlist_lock) );
-	list_add_tail( &(kmem_entry->list), &(privdata->kmem_list) );
-	spin_unlock( &(privdata->kmemlist_lock) );
-
-	return 0;
-
-kmem_alloc_mem_fail:
-		kfree(kmem_entry);
-kmem_alloc_entry_fail:
-		return -ENOMEM;
-}
-
-static int pcidriver_kmem_free_check(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle, pcidriver_kmem_entry_t *kmem_entry) {
-	if ((kmem_handle->flags & KMEM_FLAG_FORCE) == 0) {
-	    if (kmem_entry->mode&KMEM_MODE_COUNT)
-		kmem_entry->mode -= 1;
-
-	    if (kmem_handle->flags&KMEM_FLAG_HW) {
-		if (kmem_entry->refs&KMEM_REF_HW) 
-		    pcidriver_module_put(privdata);
-
-		kmem_entry->refs &= ~KMEM_REF_HW;
-	    }
-	
-	    if (kmem_handle->flags&KMEM_FLAG_PERSISTENT)
-		kmem_entry->mode &= ~KMEM_MODE_PERSISTENT;
-	
-	    if (kmem_handle->flags&KMEM_FLAG_REUSE) 
-		return 0;
-
-	    if (kmem_entry->refs) {
-		kmem_entry->mode += 1;
-		mod_info("can't free referenced kmem_entry\n");
-		return -EBUSY;
-	    }
-	
-	    if (kmem_entry->mode & KMEM_MODE_PERSISTENT) {
-		kmem_entry->mode += 1;
-		mod_info("can't free persistent kmem_entry\n");
-		return -EBUSY;
-	    }
-
-	    if (((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)==0)&&(kmem_entry->mode&KMEM_MODE_COUNT)&&((kmem_handle->flags&KMEM_FLAG_EXCLUSIVE)==0)) 
-		return 0;
-	} else {
-	    if (kmem_entry->refs&KMEM_REF_HW)
-		    pcidriver_module_put(privdata);
-		
-	    while (!atomic_add_negative(-1, &(privdata->refs))) pcidriver_module_put(privdata);
-	    atomic_inc(&(privdata->refs));
-		
-	}
-	
-	return 1;
-}
-
-static int pcidriver_kmem_free_use(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle)
-{
-	int err;
-	int failed = 0;
-	struct list_head *ptr, *next;
-	pcidriver_kmem_entry_t *kmem_entry;
-
-	/* iterate safely over the entries and delete them */
-	list_for_each_safe(ptr, next, &(privdata->kmem_list)) {
-		kmem_entry = list_entry(ptr, pcidriver_kmem_entry_t, list);
-		if (kmem_entry->use == kmem_handle->use) {
-		    err = pcidriver_kmem_free_check(privdata, kmem_handle, kmem_entry);
-		    if (err > 0)
-			pcidriver_kmem_free_entry(privdata, kmem_entry); 		/* spin lock inside! */
-		    else
-			failed = 1;
-		}
-	}
-	
-	if (failed) {
-		mod_info("Some kmem_entries for use %lx are still referenced\n", kmem_handle->use);
-		return -EBUSY;
-	}	
-
-	return 0;
-}
-
-/**
- *
- * Called via sysfs, frees kernel memory and the corresponding management structure
- *
- */
-int pcidriver_kmem_free( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle )
-{
-	int err;
-	pcidriver_kmem_entry_t *kmem_entry;
-
-	if (kmem_handle->flags&KMEM_FLAG_MASS) {
-	    kmem_handle->flags &= ~KMEM_FLAG_MASS;
-	    return pcidriver_kmem_free_use(privdata, kmem_handle);
-	}
-	
-	/* Find the associated kmem_entry for this buffer */
-	if ((kmem_entry = pcidriver_kmem_find_entry(privdata, kmem_handle)) == NULL)
-		return -EINVAL;					/* kmem_handle is not valid */
-
-	err = pcidriver_kmem_free_check(privdata, kmem_handle, kmem_entry);
-	
-	if (err > 0)
-		return pcidriver_kmem_free_entry(privdata, kmem_entry);
-	
-	return err;
-}
-
-/**
- *
- * Called when cleaning up, frees all kernel memory and their corresponding management structure
- *
- */
-int pcidriver_kmem_free_all(pcidriver_privdata_t *privdata)
-{
-//	int failed = 0;
-	struct list_head *ptr, *next;
-	pcidriver_kmem_entry_t *kmem_entry;
-
-	/* iterate safely over the entries and delete them */
-	list_for_each_safe(ptr, next, &(privdata->kmem_list)) {
-		kmem_entry = list_entry(ptr, pcidriver_kmem_entry_t, list);
-		/*if (kmem_entry->refs)
-			failed = 1;
-		else*/
-			pcidriver_kmem_free_entry(privdata, kmem_entry); 		/* spin lock inside! */
-	}
-/*	
-	if (failed) {
-		mod_info("Some kmem_entries are still referenced\n");
-		return -EBUSY;
-	}	
-*/
-	return 0;
-}
-
-
-/**
- *
- * Synchronize memory to/from the device (or in both directions).
- *
- */
-int pcidriver_kmem_sync_entry( pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry, int direction)
-{
-	if (kmem_entry->direction == PCI_DMA_NONE)
-		return -EINVAL;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
-	switch (direction) {
-		case PCILIB_KMEM_SYNC_TODEVICE:
-			pci_dma_sync_single_for_device( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			break;
-		case PCILIB_KMEM_SYNC_FROMDEVICE:
-			pci_dma_sync_single_for_cpu( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			break;
-		case PCILIB_KMEM_SYNC_BIDIRECTIONAL:
-			pci_dma_sync_single_for_device( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			pci_dma_sync_single_for_cpu( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			break;
-		default:
-			return -EINVAL;				/* wrong direction parameter */
-	}
-#else
-	switch (direction) {
-		case PCILIB_KMEM_SYNC_TODEVICE:
-			pci_dma_sync_single( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			break;
-		case PCILIB_KMEM_SYNC_FROMDEVICE:
-			pci_dma_sync_single( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			break;
-		case PCILIB_KMEM_SYNC_BIDIRECTIONAL:
-			pci_dma_sync_single( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction );
-			break;
-		default:
-			return -EINVAL;				/* wrong direction parameter */
-	}
-#endif
-
-	return 0;	/* success */
-}
-
-/**
- *
- * Synchronize memory to/from the device (or in both directions).
- *
- */
-int pcidriver_kmem_sync( pcidriver_privdata_t *privdata, kmem_sync_t *kmem_sync )
-{
-	pcidriver_kmem_entry_t *kmem_entry;
-
-	/* Find the associated kmem_entry for this buffer */
-	if ((kmem_entry = pcidriver_kmem_find_entry(privdata, &(kmem_sync->handle))) == NULL)
-		return -EINVAL;					/* kmem_handle is not valid */
-
-	return pcidriver_kmem_sync_entry(privdata, kmem_entry, kmem_sync->dir);
-}
-
-/**
- *
- * Free the given kmem_entry and its memory.
- *
- */
-int pcidriver_kmem_free_entry(pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry)
-{
-	pcidriver_sysfs_remove(privdata, &(kmem_entry->sysfs_attr));
-
-	/* Go over the pages of the kmem buffer, and mark them as not reserved */
-#if 0
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-	/*
-	 * This code is DISABLED.
-	 * Apparently, it is not needed to unreserve them. Doing so here
-	 * hangs the machine. Why?
-	 *
-	 * Uhm.. see links:
-	 *
-	 * http://lwn.net/Articles/161204/
-	 * http://lists.openfabrics.org/pipermail/general/2007-March/034101.html
-	 *
-	 * I insist, this should be enabled, but doing so hangs the machine.
-	 * Literature supports the point, and there is even a similar problem (see link)
-	 * But this is not the case. It seems right to me. but obviously is not.
-	 *
-	 * Anyway, this goes away in kernel >=2.6.15.
-	 */
-	unsigned long start = __pa(kmem_entry->cpua) >> PAGE_SHIFT;
-	unsigned long end = __pa(kmem_entry->cpua + kmem_entry->size) >> PAGE_SHIFT;
-	unsigned long i;
-	for(i=start;i<end;i++) {
-		struct page *kpage = pfn_to_page(i);
-		ClearPageReserved(kpage);
-	}
-#endif
-#endif
-
-	/* Release DMA memory */
-	switch (kmem_entry->type&PCILIB_KMEM_TYPE_MASK) {
-	 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) {
-		    pci_unmap_single(privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, PCI_DMA_TODEVICE);
-		} else if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_C2S_PAGE) {
-		    pci_unmap_single(privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, PCI_DMA_FROMDEVICE);
-		}
-	    }
-	    free_pages((unsigned long)kmem_entry->cpua, get_order(kmem_entry->size));
-	    break;
-	}
-
-
-	/* Remove the kmem list entry */
-	spin_lock( &(privdata->kmemlist_lock) );
-	list_del( &(kmem_entry->list) );
-	spin_unlock( &(privdata->kmemlist_lock) );
-
-	/* Release kmem_entry memory */
-	kfree(kmem_entry);
-
-	return 0;
-}
-
-/**
- *
- * Find the corresponding kmem_entry for the given kmem_handle.
- *
- */
-pcidriver_kmem_entry_t *pcidriver_kmem_find_entry(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle)
-{
-	struct list_head *ptr;
-	pcidriver_kmem_entry_t *entry, *result = NULL;
-
-	/* should I implement it better using the handle_id? */
-
-	spin_lock(&(privdata->kmemlist_lock));
-	list_for_each(ptr, &(privdata->kmem_list)) {
-		entry = list_entry(ptr, pcidriver_kmem_entry_t, list);
-
-		if (entry->id == kmem_handle->handle_id) {
-			result = entry;
-			break;
-		}
-	}
-
-	spin_unlock(&(privdata->kmemlist_lock));
-	return result;
-}
-
-/**
- *
- * find the corresponding kmem_entry for the given id.
- *
- */
-pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_id(pcidriver_privdata_t *privdata, int id)
-{
-	struct list_head *ptr;
-	pcidriver_kmem_entry_t *entry, *result = NULL;
-
-	spin_lock(&(privdata->kmemlist_lock));
-	list_for_each(ptr, &(privdata->kmem_list)) {
-		entry = list_entry(ptr, pcidriver_kmem_entry_t, list);
-
-		if (entry->id == id) {
-			result = entry;
-			break;
-		}
-	}
-
-	spin_unlock(&(privdata->kmemlist_lock));
-	return result;
-}
-
-/**
- *
- * find the corresponding kmem_entry for the given use and item.
- *
- */
-pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_use(pcidriver_privdata_t *privdata, unsigned long use, unsigned long item)
-{
-	struct list_head *ptr;
-	pcidriver_kmem_entry_t *entry, *result = NULL;
-
-	spin_lock(&(privdata->kmemlist_lock));
-	list_for_each(ptr, &(privdata->kmem_list)) {
-		entry = list_entry(ptr, pcidriver_kmem_entry_t, list);
-
-		if ((entry->use == use)&&(entry->item == item)&&(entry->mode&KMEM_MODE_REUSABLE)) {
-			result = entry;
-			break;
-		}
-	}
-
-	spin_unlock(&(privdata->kmemlist_lock));
-	return result;
-}
-
-
-void pcidriver_kmem_mmap_close(struct vm_area_struct *vma) {
-    unsigned long vma_size;
-    pcidriver_kmem_entry_t *kmem_entry = (pcidriver_kmem_entry_t*)vma->vm_private_data;
-    if (kmem_entry) {
-/*
-	if (kmem_entry->id == 0) {
-	    mod_info("refs: %p %p %lx\n", vma, vma->vm_private_data, kmem_entry->refs);
-	    mod_info("kmem_size: %lu vma_size: %lu, s: %lx, e: %lx\n", kmem_entry->size, (vma->vm_end - vma->vm_start), vma->vm_start, vma->vm_end);
-	}
-*/
-
-	vma_size = (vma->vm_end - vma->vm_start);
-	
-	if (kmem_entry->refs&KMEM_REF_COUNT) {
-	    kmem_entry->refs -= vma_size / PAGE_SIZE;
-	}
-    }
-}
-
-static struct vm_operations_struct pcidriver_kmem_mmap_ops = {
-    .close = pcidriver_kmem_mmap_close
-};
-
-/**
- *
- * mmap() kernel memory to userspace.
- *
- */
-int pcidriver_mmap_kmem(pcidriver_privdata_t *privdata, struct vm_area_struct *vma)
-{
-	unsigned long vma_size;
-	pcidriver_kmem_entry_t *kmem_entry;
-	int ret;
-
-	mod_info_dbg("Entering mmap_kmem\n");
-
-	/* FIXME: Is this really right? Always just the latest one? Can't we identify one? */
-	/* Get latest entry on the kmem_list */
-	kmem_entry = pcidriver_kmem_find_entry_id(privdata, privdata->kmem_cur_id);
-	if (!kmem_entry) {
-		mod_info("Trying to mmap a kernel memory buffer without creating it first!\n");
-		return -EFAULT;
-	}
-
-	mod_info_dbg("Got kmem_entry with id: %d\n", kmem_entry->id);
-
-	/* Check sizes */
-	vma_size = (vma->vm_end - vma->vm_start);
-	
-	if ((vma_size > kmem_entry->size) &&
-		((kmem_entry->size < PAGE_SIZE) && (vma_size != PAGE_SIZE))) {
-		mod_info("kem_entry size(%lu) and vma size do not match(%lu)\n", kmem_entry->size, vma_size);
-		return -EINVAL;
-	}
-
-	/* reference counting */
-	if ((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)&&(kmem_entry->refs&KMEM_REF_COUNT)) {
-		mod_info("can't make second mmaping for exclusive kmem_entry\n");
-		return -EBUSY;
-	}
-	if (((kmem_entry->refs&KMEM_REF_COUNT) + (vma_size / PAGE_SIZE)) > KMEM_REF_COUNT) {
-		mod_info("maximal amount of references is reached by kmem_entry\n");
-		return -EBUSY;
-	}
-	
-	kmem_entry->refs += vma_size / PAGE_SIZE;
-
-	vma->vm_flags |= (VM_RESERVED);
-
-#ifdef pgprot_noncached
-	// This is coherent memory, so it must not be cached.
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#endif
-
-	mod_info_dbg("Mapping address %08lx / PFN %08lx\n",
-			virt_to_phys((void*)kmem_entry->cpua),
-			page_to_pfn(virt_to_page((void*)kmem_entry->cpua)));
-
-	 if ((kmem_entry->type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) {
-		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);
-		kmem_entry->refs -= 1;
-		return -EAGAIN;
-	}
-
-	vma->vm_ops = &pcidriver_kmem_mmap_ops;
-	vma->vm_private_data = (void*)kmem_entry;
-	
-	return ret;
-}

+ 0 - 9
driver/kmem.h

@@ -1,9 +0,0 @@
-int pcidriver_kmem_alloc( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle );
-int pcidriver_kmem_free(  pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle );
-int pcidriver_kmem_sync_entry( pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry, int direction );
-int pcidriver_kmem_sync(  pcidriver_privdata_t *privdata, kmem_sync_t *kmem_sync );
-int pcidriver_kmem_free_all(  pcidriver_privdata_t *privdata );
-pcidriver_kmem_entry_t *pcidriver_kmem_find_entry( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle );
-pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_id( pcidriver_privdata_t *privdata, int id );
-pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_use(pcidriver_privdata_t *privdata, unsigned long use, unsigned long item);
-int pcidriver_kmem_free_entry( pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry );

+ 0 - 217
driver/pciDriver.h

@@ -1,217 +0,0 @@
-#ifndef PCIDRIVER_H_
-#define PCIDRIVER_H_
-
-/**
- * This is a full rewrite of the pciDriver.
- * New default is to support kernel 2.6, using kernel 2.6 APIs.
- * 
- * This header defines the interface to the outside world.
- * 
- * $Revision: 1.6 $
- * $Date: 2008-01-24 14:21:36 $
- * 
- */
-
-/*
- * Change History:
- * 
- * $Log: not supported by cvs2svn $
- * Revision 1.5  2008-01-11 10:15:14  marcus
- * Removed unused interrupt code.
- * Added intSource to the wait interrupt call.
- *
- * Revision 1.4  2006/11/17 18:44:42  marcus
- * Type of SG list can now be selected at runtime. Added type to sglist.
- *
- * Revision 1.3  2006/11/17 16:23:02  marcus
- * Added slot number to the PCI info IOctl.
- *
- * Revision 1.2  2006/11/13 12:29:09  marcus
- * Added a IOctl call, to confiure the interrupt response. (testing pending).
- * Basic interrupts are now supported.
- *
- * Revision 1.1  2006/10/10 14:46:52  marcus
- * Initial commit of the new pciDriver for kernel 2.6
- *
- * Revision 1.7  2006/10/06 15:18:06  marcus
- * Updated PCI info and PCI cmd
- *
- * Revision 1.6  2006/09/25 16:51:07  marcus
- * Added PCI config IOctls, and implemented basic mmap functions.
- *
- * Revision 1.5  2006/09/18 17:13:12  marcus
- * backup commit.
- *
- * Revision 1.4  2006/09/15 15:44:41  marcus
- * backup commit.
- *
- * Revision 1.3  2006/08/15 11:40:02  marcus
- * backup commit.
- *
- * Revision 1.2  2006/08/12 18:28:42  marcus
- * Sync with the laptop
- *
- * Revision 1.1  2006/08/11 15:30:46  marcus
- * Sync with the laptop
- *
- */
-
-#include <linux/ioctl.h>
-#include "../pcilib_types.h"
-
-/* Identifies the PCI-E Xilinx ML605 */
-#define PCIE_XILINX_VENDOR_ID 0x10ee
-#define PCIE_ML605_DEVICE_ID 0x6024
-
-/* Identifies the PCI-E IPE Camera */
-#define PCIE_IPECAMERA_DEVICE_ID 0x6081
-#define PCIE_KAPTURE_DEVICE_ID 0x6028
-//#define PCIE_IPECAMERA_DEVICE_ID 0x6018
-
-
-/* Possible values for ioctl commands */
-
-/* PCI mmap areas */
-#define	PCIDRIVER_BAR0		0
-#define	PCIDRIVER_BAR1		1
-#define	PCIDRIVER_BAR2		2
-#define	PCIDRIVER_BAR3		3
-#define	PCIDRIVER_BAR4		4
-#define	PCIDRIVER_BAR5		5
-
-/* mmap mode of the device */
-#define PCIDRIVER_MMAP_PCI	0
-#define PCIDRIVER_MMAP_KMEM 1
-
-/* Direction of a DMA operation */
-#define PCIDRIVER_DMA_BIDIRECTIONAL 	0
-#define	PCIDRIVER_DMA_TODEVICE		PCILIB_KMEM_SYNC_TODEVICE
-#define PCIDRIVER_DMA_FROMDEVICE	PCILIB_KMEM_SYNC_FROMDEVICE
-
-/* Possible sizes in a PCI command */
-#define PCIDRIVER_PCI_CFG_SZ_BYTE  1
-#define PCIDRIVER_PCI_CFG_SZ_WORD  2
-#define PCIDRIVER_PCI_CFG_SZ_DWORD 3
-
-/* Possible types of SG lists */
-#define PCIDRIVER_SG_NONMERGED 0
-#define PCIDRIVER_SG_MERGED 1
-
-/* Maximum number of interrupt sources */
-#define PCIDRIVER_INT_MAXSOURCES 16
-
-
-#define KMEM_FLAG_REUSE 1	/**< Try to reuse existing buffer with the same use & item */
-#define KMEM_FLAG_EXCLUSIVE 2	/**< Allow only a single application accessing a specified use & item */
-#define KMEM_FLAG_PERSISTENT 4	/**< Sets persistent mode */
-#define KMEM_FLAG_HW 8		/**< The buffer may be accessed by hardware, the hardware access will not occur any more if passed to _free function */
-#define KMEM_FLAG_FORCE 16	/**< Force memory cleanup even if references are present */
-#define KMEM_FLAG_MASS 32	/**< Apply to all buffers of selected use */
-#define KMEM_FLAG_TRY 64	/**< Do not allocate buffers, try to reuse and fail if not possible */
-
-#define KMEM_FLAG_REUSED 1		/**< Indicates if buffer with specified use & item was already allocated and reused */
-#define KMEM_FLAG_REUSED_PERSISTENT 4	/**< Indicates that reused buffer was persistent before the call */
-#define KMEM_FLAG_REUSED_HW 8		/**< Indicates that reused buffer had a HW reference before the call */
-
-
-/* Types */
-typedef struct {
-	unsigned long type;
-	unsigned long pa;
-	unsigned long size;
-	unsigned long align;
-	unsigned long use;
-	unsigned long item;
-	int flags;
-	int handle_id;
-} kmem_handle_t;
-
-typedef struct {
-	unsigned long addr;
-	unsigned long size;
-} umem_sgentry_t;
-
-typedef struct {
-	int handle_id;
-	int type;
-	int nents;
-	umem_sgentry_t *sg;
-} umem_sglist_t;
-
-typedef struct {
-	unsigned long vma;
-	unsigned long size;
-	int handle_id;
-	int dir;
-} umem_handle_t;
-
-typedef struct {
-	kmem_handle_t handle;
-	int dir;
-} kmem_sync_t;
-
-typedef struct {
-    unsigned long count;
-    unsigned long timeout;	// microseconds
-    unsigned int source;
-} interrupt_wait_t;
-
-typedef struct {
-	int size;
-	int addr;
-	union {
-		unsigned char byte;
-		unsigned short word;
-		unsigned int dword; 	/* not strict C, but if not can have problems */
-	} val;
-} pci_cfg_cmd;
-
-typedef struct {
-	unsigned short vendor_id;
-	unsigned short device_id;
-	unsigned short bus;
-	unsigned short slot;
-	unsigned short func;
-	unsigned short devfn;
-	unsigned char interrupt_pin;
-	unsigned char interrupt_line;
-	unsigned int irq;
-	unsigned long bar_start[6];
-	unsigned long bar_length[6];
-	unsigned long bar_flags[6];
-} pcilib_board_info_t;
-
-
-/* ioctl interface */
-/* See documentation for a detailed usage explanation */
-
-/* 
- * one of the problems of ioctl, is that requires a type definition.
- * This type is only 8-bits wide, and half-documented in 
- * <linux-src>/Documentation/ioctl-number.txt.
- * previous SHL -> 'S' definition, conflicts with several devices,
- * so I changed it to be pci -> 'p', in the range 0xA0-AF
- */
-#define PCIDRIVER_IOC_MAGIC 'p'
-#define PCIDRIVER_IOC_BASE  0xA0
-
-#define PCIDRIVER_IOC_MMAP_MODE  _IO(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 0 )
-#define PCIDRIVER_IOC_MMAP_AREA  _IO(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 1 )
-#define PCIDRIVER_IOC_KMEM_ALLOC _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 2, kmem_handle_t * )
-#define PCIDRIVER_IOC_KMEM_FREE  _IOW ( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 3, kmem_handle_t * )
-#define PCIDRIVER_IOC_KMEM_SYNC  _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 4, kmem_sync_t * )
-#define PCIDRIVER_IOC_UMEM_SGMAP _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 5, umem_handle_t * )
-#define PCIDRIVER_IOC_UMEM_SGUNMAP _IOW(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 6, umem_handle_t * )
-#define PCIDRIVER_IOC_UMEM_SGGET _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 7, umem_sglist_t * )
-#define PCIDRIVER_IOC_UMEM_SYNC  _IOW(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 8, umem_handle_t * )
-#define PCIDRIVER_IOC_WAITI      _IO(   PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 9 )
-
-/* And now, the methods to access the PCI configuration area */
-#define PCIDRIVER_IOC_PCI_CFG_RD  _IOWR(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 10, pci_cfg_cmd * )
-#define PCIDRIVER_IOC_PCI_CFG_WR  _IOWR(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 11, pci_cfg_cmd * )
-#define PCIDRIVER_IOC_PCI_INFO    _IOWR(  PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 12, pcilib_board_info_t * )
-
-/* Clear interrupt queues */
-#define PCIDRIVER_IOC_CLEAR_IOQ   _IO(   PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 13 )
-
-#endif

+ 0 - 308
driver/sysfs.c

@@ -1,308 +0,0 @@
-/**
- *
- * @file sysfs.c
- * @brief This file contains the functions providing the SysFS-interface.
- * @author Guillermo Marcus
- * @date 2010-03-01
- *
- */
-#include <linux/version.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/cdev.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/kernel.h>
-
-#include "compat.h"
-#include "config.h"
-#include "pciDriver.h"
-#include "common.h"
-#include "umem.h"
-#include "kmem.h"
-#include "sysfs.h"
-
-static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry);
-static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry);
-
-/**
- *
- * Initializes the sysfs attributes for an kmem/umem-entry
- *
- */
-static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata,
-					int id,
-					struct class_device_attribute *sysfs_attr,
-					const char *fmtstring,
-					SYSFS_GET_FUNCTION((*callback)))
-{
-	/* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as
-	   we have no mmap support before */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-	char namebuffer[16];
-
-	/* allocate space for the name of the attribute */
-	snprintf(namebuffer, sizeof(namebuffer), fmtstring, id);
-
-	if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL)
-		return -ENOMEM;
-
-	sysfs_attr->attr.mode = S_IRUGO;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-	    // DS: Shall we lock now while accessing driver data structures???
-	sysfs_attr->attr.owner = THIS_MODULE;
-#endif
-	sysfs_attr->show = callback;
-	sysfs_attr->store = NULL;
-			
-	/* name and add attribute */
-	if (class_device_create_file(privdata->class_dev, sysfs_attr) != 0)
-		return -ENXIO; /* Device not configured. Not the really best choice, but hm. */
-#endif
-
-	return 0;
-}
-
-int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr)
-{
-	return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry);
-}
-
-int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr)
-{
-	return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry);
-}
-
-/**
- *
- * Removes the file from sysfs and frees the allocated (kstrdup()) memory.
- *
- */
-void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-	class_device_remove_file(privdata->class_dev, sysfs_attr);
-	kfree(sysfs_attr->attr.name);
-#endif
-}
-
-static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-
-        /* As we can be sure that attr.name contains a filename which we
-         * created (see _pcidriver_sysfs_initialize), we do not need to have
-         * sanity checks but can directly call simple_strtol() */
-        int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10);
-	pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id);
-	if (entry) {
-	    unsigned long addr = entry->cpua;
-	    unsigned long dma_addr = entry->dma_handle;
-	    
-	    if (entry->size >= 16) {
-		pcidriver_kmem_sync_entry(privdata, entry, PCILIB_KMEM_SYNC_FROMDEVICE);
-		return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\ndata: %8x %8x %8x %8x\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode, *(u32*)(entry->cpua), *(u32*)(entry->cpua + 4),  *(u32*)(entry->cpua + 8), *(u32*)(entry->cpua + 12));
-	    } else
-		return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode);
-	} else
-	    return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id);
-#else
-	return 0;
-#endif
-}
-
-static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-#if 0
-	pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)cls->class_data;
-
-	return snprintf(buf, PAGE_SIZE, "I am in the umem_entry show function, class_device_kobj_name: %s\n", cls->kobj.name);
-#endif
-	return 0;
-#else
-	return 0;
-#endif
-}
-
-#ifdef ENABLE_IRQ
-SYSFS_GET_FUNCTION(pcidriver_show_irq_count)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count);
-}
-
-SYSFS_GET_FUNCTION(pcidriver_show_irq_queues)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	int i, offset;
-
-	/* output will be truncated to PAGE_SIZE */
-	offset = snprintf(buf, PAGE_SIZE, "Queue\tOutstanding IRQs\n");
-	for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++)
-		offset += snprintf(buf+offset, PAGE_SIZE-offset, "%d\t%d\n", i, atomic_read(&(privdata->irq_outstanding[i])) );
-
-	return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1);
-}
-#endif
-
-SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_mode);
-}
-
-SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	int mode = -1;
-
-	/* Set the mmap-mode if it is either PCIDRIVER_MMAP_PCI or PCIDRIVER_MMAP_KMEM */
-	if (sscanf(buf, "%d", &mode) == 1 &&
-	    (mode == PCIDRIVER_MMAP_PCI || mode == PCIDRIVER_MMAP_KMEM))
-		privdata->mmap_mode = mode;
-
-	return strlen(buf);
-}
-
-SYSFS_GET_FUNCTION(pcidriver_show_mmap_area)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_area);
-}
-
-SYSFS_SET_FUNCTION(pcidriver_store_mmap_area)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	int temp = -1;
-
-	sscanf(buf, "%d", &temp);
-
-	if ((temp >= PCIDRIVER_BAR0) && (temp <= PCIDRIVER_BAR5))
-		privdata->mmap_area = temp;
-
-	return strlen(buf);
-}
-
-SYSFS_GET_FUNCTION(pcidriver_show_kmem_count)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&(privdata->kmem_count)));
-}
-
-SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	kmem_handle_t kmem_handle;
-
-	/* FIXME: guillermo: is validation of parsing an unsigned int enough? */
-	if (sscanf(buf, "%lu", &kmem_handle.size) == 1)
-		pcidriver_kmem_alloc(privdata, &kmem_handle);
-
-	return strlen(buf);
-}
-
-SYSFS_SET_FUNCTION(pcidriver_store_kmem_free)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	unsigned int id;
-	pcidriver_kmem_entry_t *kmem_entry;
-
-	/* Parse the ID of the kernel memory to be freed, check bounds */
-	if (sscanf(buf, "%u", &id) != 1 ||
-	    (id >= atomic_read(&(privdata->kmem_count))))
-		goto err;
-
-	if ((kmem_entry = pcidriver_kmem_find_entry_id(privdata,id)) == NULL)
-		goto err;
-
-	pcidriver_kmem_free_entry(privdata, kmem_entry );
-err:
-	return strlen(buf);
-}
-
-SYSFS_GET_FUNCTION(pcidriver_show_kbuffers)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	int offset = 0;
-	struct list_head *ptr;
-	pcidriver_kmem_entry_t *entry;
-
-	/* print the header */
-	offset += snprintf(buf, PAGE_SIZE, "kbuf#\tcpu addr\tsize\n");
-
-	spin_lock(&(privdata->kmemlist_lock));
-	list_for_each(ptr, &(privdata->kmem_list)) {
-		entry = list_entry(ptr, pcidriver_kmem_entry_t, list);
-
-		/* print entry info */
-		if (offset > PAGE_SIZE) {
-			spin_unlock( &(privdata->kmemlist_lock) );
-			return PAGE_SIZE;
-		}
-
-		offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%08lx\t%lu\n", entry->id, (unsigned long)(entry->dma_handle), entry->size );
-	}
-
-	spin_unlock(&(privdata->kmemlist_lock));
-
-	/* output will be truncated to PAGE_SIZE */
-	return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1);
-}
-
-SYSFS_GET_FUNCTION(pcidriver_show_umappings)
-{
-	int offset = 0;
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	struct list_head *ptr;
-	pcidriver_umem_entry_t *entry;
-
-	/* print the header */
-	offset += snprintf(buf, PAGE_SIZE, "umap#\tn_pages\tsg_ents\n");
-
-	spin_lock( &(privdata->umemlist_lock) );
-	list_for_each( ptr, &(privdata->umem_list) ) {
-		entry = list_entry(ptr, pcidriver_umem_entry_t, list );
-
-		/* print entry info */
-		if (offset > PAGE_SIZE) {
-			spin_unlock( &(privdata->umemlist_lock) );
-			return PAGE_SIZE;
-		}
-
-		offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%lu\t%lu\n", entry->id,
-				(unsigned long)(entry->nr_pages), (unsigned long)(entry->nents));
-	}
-
-	spin_unlock( &(privdata->umemlist_lock) );
-
-	/* output will be truncated to PAGE_SIZE */
-	return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1);
-}
-
-SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap)
-{
-	pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
-	pcidriver_umem_entry_t *umem_entry;
-	unsigned int id;
-
-	if (sscanf(buf, "%u", &id) != 1 ||
-	    (id >= atomic_read(&(privdata->umem_count))))
-		goto err;
-
-	if ((umem_entry = pcidriver_umem_find_entry_id(privdata, id)) == NULL)
-		goto err;
-
-	pcidriver_umem_sgunmap(privdata, umem_entry);
-err:
-	return strlen(buf);
-}

+ 0 - 23
driver/sysfs.h

@@ -1,23 +0,0 @@
-#ifndef _PCIDRIVER_SYSFS_H
-#define _PCIDRIVER_SYSFS_H
-int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr);
-int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr);
-void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr);
-
-#ifdef ENABLE_IRQ
-SYSFS_GET_FUNCTION(pcidriver_show_irq_count);
-SYSFS_GET_FUNCTION(pcidriver_show_irq_queues);
-#endif
-
-/* prototypes for sysfs operations */
-SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode);
-SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode);
-SYSFS_GET_FUNCTION(pcidriver_show_mmap_area);
-SYSFS_SET_FUNCTION(pcidriver_store_mmap_area);
-SYSFS_GET_FUNCTION(pcidriver_show_kmem_count);
-SYSFS_GET_FUNCTION(pcidriver_show_kbuffers);
-SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc);
-SYSFS_SET_FUNCTION(pcidriver_store_kmem_free);
-SYSFS_GET_FUNCTION(pcidriver_show_umappings);
-SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap);
-#endif

+ 0 - 438
driver/umem.c

@@ -1,438 +0,0 @@
-/**
- *
- * @file umem.c
- * @brief This file contains the functions handling user space memory.
- * @author Guillermo Marcus
- * @date 2009-04-05
- *
- */
-#include <linux/version.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/cdev.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/sched.h>
-
-#include "config.h"			/* compile-time configuration */
-#include "compat.h"			/* compatibility definitions for older linux */
-#include "pciDriver.h"			/* external interface for the driver */
-#include "common.h"		/* internal definitions for all parts */
-#include "umem.h"		/* prototypes for kernel memory */
-#include "sysfs.h"		/* prototypes for sysfs */
-
-/**
- *
- * Reserve a new scatter/gather list and map it from memory to PCI bus addresses.
- *
- */
-int pcidriver_umem_sgmap(pcidriver_privdata_t *privdata, umem_handle_t *umem_handle)
-{
-	int i, res, nr_pages;
-	struct page **pages;
-	struct scatterlist *sg = NULL;
-	pcidriver_umem_entry_t *umem_entry;
-	unsigned int nents;
-	unsigned long count,offset,length;
-
-	/*
-	 * We do some checks first. Then, the following is necessary to create a
-	 * Scatter/Gather list from a user memory area:
-	 *  - Determine the number of pages
-	 *  - Get the pages for the memory area
-	 * 	- Lock them.
-	 *  - Create a scatter/gather list of the pages
-	 *  - Map the list from memory to PCI bus addresses
-	 *
-	 * Then, we:
-	 *  - Create an entry on the umem list of the device, to cache the mapping.
-	 *  - Create a sysfs attribute that gives easy access to the SG list
-	 */
-
-	/* zero-size?? */
-	if (umem_handle->size == 0)
-		return -EINVAL;
-
-	/* Direction is better ignoring during mapping. */
-	/* We assume bidirectional buffers always, except when sync'ing */
-
-	/* calculate the number of pages */
-	nr_pages = ((umem_handle->vma & ~PAGE_MASK) + umem_handle->size + ~PAGE_MASK) >> PAGE_SHIFT;
-
-	mod_info_dbg("nr_pages computed: %u\n", nr_pages);
-
-	/* Allocate space for the page information */
-	/* This can be very big, so we use vmalloc */
-	if ((pages = vmalloc(nr_pages * sizeof(*pages))) == NULL)
-		return -ENOMEM;
-
-	mod_info_dbg("allocated space for the pages.\n");
-
-	/* Allocate space for the scatterlist */
-	/* We do not know how many entries will be, but the maximum is nr_pages. */
-	/* This can be very big, so we use vmalloc */
-	if ((sg = vmalloc(nr_pages * sizeof(*sg))) == NULL)
-		goto umem_sgmap_pages;
-
-	sg_init_table(sg, nr_pages);
-
-	mod_info_dbg("allocated space for the SG list.\n");
-
-	/* Get the page information */
-	down_read(&current->mm->mmap_sem);
-	res = get_user_pages(
-				current,
-				current->mm,
-				umem_handle->vma,
-				nr_pages,
-				1,
-				0,  /* do not force, FIXME: shall I? */
-				pages,
-				NULL );
-	up_read(&current->mm->mmap_sem);
-
-	/* Error, not all pages mapped */
-	if (res < (int)nr_pages) {
-		mod_info("Could not map all user pages (%d of %d)\n", res, nr_pages);
-		/* If only some pages could be mapped, we release those. If a real
-		 * error occured, we set nr_pages to 0 */
-		nr_pages = (res > 0 ? res : 0);
-		goto umem_sgmap_unmap;
-	}
-
-	mod_info_dbg("Got the pages (%d).\n", res);
-
-	/* Lock the pages, then populate the SG list with the pages */
-	/* page0 is different */
-	if ( !PageReserved(pages[0]) )
-		compat_lock_page(pages[0]);
-
-	offset = (umem_handle->vma & ~PAGE_MASK);
-	length = (umem_handle->size > (PAGE_SIZE-offset) ? (PAGE_SIZE-offset) : umem_handle->size);
-
-	sg_set_page(&sg[0], pages[0], length, offset);
-
-	count = umem_handle->size - length;
-	for(i=1;i<nr_pages;i++) {
-		/* Lock page first */
-		if ( !PageReserved(pages[i]) )
-			compat_lock_page(pages[i]);
-
-		/* Populate the list */
-		sg_set_page(&sg[i], pages[i], ((count > PAGE_SIZE) ? PAGE_SIZE : count), 0);
-		count -= sg[i].length;
-	}
-
-	/* Use the page list to populate the SG list */
-	/* SG entries may be merged, res is the number of used entries */
-	/* We have originally nr_pages entries in the sg list */
-	if ((nents = pci_map_sg(privdata->pdev, sg, nr_pages, PCI_DMA_BIDIRECTIONAL)) == 0)
-		goto umem_sgmap_unmap;
-
-	mod_info_dbg("Mapped SG list (%d entries).\n", nents);
-
-	/* Add an entry to the umem_list of the device, and update the handle with the id */
-	/* Allocate space for the new umem entry */
-	if ((umem_entry = kmalloc(sizeof(*umem_entry), GFP_KERNEL)) == NULL)
-		goto umem_sgmap_entry;
-
-	/* Fill entry to be added to the umem list */
-	umem_entry->id = atomic_inc_return(&privdata->umem_count) - 1;
-	umem_entry->nr_pages = nr_pages;	/* Will be needed when unmapping */
-	umem_entry->pages = pages;
-	umem_entry->nents = nents;
-	umem_entry->sg = sg;
-
-	if (pcidriver_sysfs_initialize_umem(privdata, umem_entry->id, &(umem_entry->sysfs_attr)) != 0)
-		goto umem_sgmap_name_fail;
-
-	/* Add entry to the umem list */
-	spin_lock( &(privdata->umemlist_lock) );
-	list_add_tail( &(umem_entry->list), &(privdata->umem_list) );
-	spin_unlock( &(privdata->umemlist_lock) );
-
-	/* Update the Handle with the Handle ID of the entry */
-	umem_handle->handle_id = umem_entry->id;
-
-	return 0;
-
-umem_sgmap_name_fail:
-	kfree(umem_entry);
-umem_sgmap_entry:
-	pci_unmap_sg( privdata->pdev, sg, nr_pages, PCI_DMA_BIDIRECTIONAL );
-umem_sgmap_unmap:
-	/* release pages */
-	if (nr_pages > 0) {
-		for(i=0;i<nr_pages;i++) {
-			if (PageLocked(pages[i]))
-				compat_unlock_page(pages[i]);
-			if (!PageReserved(pages[i]))
-				set_page_dirty(pages[i]);
-			page_cache_release(pages[i]);
-		}
-	}
-	vfree(sg);
-umem_sgmap_pages:
-	vfree(pages);
-	return -ENOMEM;
-
-}
-
-/**
- *
- * Unmap a scatter/gather list
- *
- */
-int pcidriver_umem_sgunmap(pcidriver_privdata_t *privdata, pcidriver_umem_entry_t *umem_entry)
-{
-	int i;
-	pcidriver_sysfs_remove(privdata, &(umem_entry->sysfs_attr));
-
-	/* Unmap user memory */
-	pci_unmap_sg( privdata->pdev, umem_entry->sg, umem_entry->nr_pages, PCI_DMA_BIDIRECTIONAL );
-
-	/* Release the pages */
-	if (umem_entry->nr_pages > 0) {
-		for(i=0;i<(umem_entry->nr_pages);i++) {
-			/* Mark pages as Dirty and unlock it */
-			if ( !PageReserved( umem_entry->pages[i] )) {
-				SetPageDirty( umem_entry->pages[i] );
-				compat_unlock_page(umem_entry->pages[i]);
-			}
-			/* and release it from the cache */
-			page_cache_release( umem_entry->pages[i] );
-		}
-	}
-
-	/* Remove the umem list entry */
-	spin_lock( &(privdata->umemlist_lock) );
-	list_del( &(umem_entry->list) );
-	spin_unlock( &(privdata->umemlist_lock) );
-
-	/* Release SG list and page list memory */
-	/* These two are in the vm area of the kernel */
-	vfree(umem_entry->pages);
-	vfree(umem_entry->sg);
-
-	/* Release umem_entry memory */
-	kfree(umem_entry);
-
-	return 0;
-}
-
-/**
- *
- * Unmap all scatter/gather lists.
- *
- */
-int pcidriver_umem_sgunmap_all(pcidriver_privdata_t *privdata)
-{
-	struct list_head *ptr, *next;
-	pcidriver_umem_entry_t *umem_entry;
-
-	/* iterate safely over the entries and delete them */
-	list_for_each_safe( ptr, next, &(privdata->umem_list) ) {
-		umem_entry = list_entry(ptr, pcidriver_umem_entry_t, list );
-		pcidriver_umem_sgunmap( privdata, umem_entry ); 		/* spin lock inside! */
-	}
-
-	return 0;
-}
-
-/**
- *
- * Copies the scatter/gather list from kernelspace to userspace.
- *
- */
-int pcidriver_umem_sgget(pcidriver_privdata_t *privdata, umem_sglist_t *umem_sglist)
-{
-	int i;
-	pcidriver_umem_entry_t *umem_entry;
-	struct scatterlist *sg;
-	int idx = 0;
-	dma_addr_t cur_addr;
-	unsigned int cur_size;
-
-	/* Find the associated umem_entry for this buffer */
-	umem_entry = pcidriver_umem_find_entry_id( privdata, umem_sglist->handle_id );
-	if (umem_entry == NULL)
-		return -EINVAL;					/* umem_handle is not valid */
-
-	/* Check if passed SG list is enough */
-	if (umem_sglist->nents < umem_entry->nents)
-		return -EINVAL;					/* sg has not enough entries */
-
-	/* Copy the SG list to the user format */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-	if (umem_sglist->type == PCIDRIVER_SG_MERGED) {
-		for_each_sg(umem_entry->sg, sg, umem_entry->nents, i ) {
-			if (i==0) {
-				umem_sglist->sg[0].addr = sg_dma_address( sg );
-				umem_sglist->sg[0].size = sg_dma_len( sg );
-				idx = 0;
-			}
-			else {
-				cur_addr = sg_dma_address( sg );
-				cur_size = sg_dma_len( sg );
-
-				/* Check if entry fits after current entry */
-				if (cur_addr == (umem_sglist->sg[idx].addr + umem_sglist->sg[idx].size)) {
-					umem_sglist->sg[idx].size += cur_size;
-					continue;
-				}
-
-				/* Skip if the entry is zero-length (yes, it can happen.... at the end of the list) */
-				if (cur_size == 0)
-					continue;
-
-				/* None of the above, add new entry */
-				idx++;
-				umem_sglist->sg[idx].addr = cur_addr;
-				umem_sglist->sg[idx].size = cur_size;
-			}
-		}
-		/* Set the used size of the SG list */
-		umem_sglist->nents = idx+1;
-	} else {
-		for_each_sg(umem_entry->sg, sg, umem_entry->nents, i ) {
-			mod_info("entry: %d\n",i);
-			umem_sglist->sg[i].addr = sg_dma_address( sg );
-			umem_sglist->sg[i].size = sg_dma_len( sg );
-		}
-
-		/* Set the used size of the SG list */
-		/* Check if the last one is zero-length */
-		if ( umem_sglist->sg[ umem_entry->nents - 1].size == 0)
-			umem_sglist->nents = umem_entry->nents -1;
-		else
-			umem_sglist->nents = umem_entry->nents;
-	}
-#else
-	if (umem_sglist->type == PCIDRIVER_SG_MERGED) {
-		/* Merge entries that are contiguous into a single entry */
-		/* Non-optimal but fast for most cases */
-		/* First one always true */
-		sg=umem_entry->sg;
-		umem_sglist->sg[0].addr = sg_dma_address( sg );
-		umem_sglist->sg[0].size = sg_dma_len( sg );
-		sg++;
-		idx = 0;
-
-		/* Iterate over the SG entries */
-		for(i=1; i< umem_entry->nents; i++, sg++ ) {
-			cur_addr = sg_dma_address( sg );
-			cur_size = sg_dma_len( sg );
-
-			/* Check if entry fits after current entry */
-			if (cur_addr == (umem_sglist->sg[idx].addr + umem_sglist->sg[idx].size)) {
-				umem_sglist->sg[idx].size += cur_size;
-				continue;
-			}
-
-			/* Skip if the entry is zero-length (yes, it can happen.... at the end of the list) */
-			if (cur_size == 0)
-				continue;
-
-			/* None of the above, add new entry */
-			idx++;
-			umem_sglist->sg[idx].addr = cur_addr;
-			umem_sglist->sg[idx].size = cur_size;
-		}
-		/* Set the used size of the SG list */
-		umem_sglist->nents = idx+1;
-	} else {
-		/* Assume pci_map_sg made a good job (ehem..) and just copy it.
-		 * actually, now I assume it just gives them plainly to me. */
-		for(i=0, sg=umem_entry->sg ; i< umem_entry->nents; i++, sg++ ) {
-			umem_sglist->sg[i].addr = sg_dma_address( sg );
-			umem_sglist->sg[i].size = sg_dma_len( sg );
-		}
-		/* Set the used size of the SG list */
-		/* Check if the last one is zero-length */
-		if ( umem_sglist->sg[ umem_entry->nents - 1].size == 0)
-			umem_sglist->nents = umem_entry->nents -1;
-		else
-			umem_sglist->nents = umem_entry->nents;
-	}
-#endif
-
-	return 0;
-}
-
-/**
- *
- * Sync user space memory from/to device
- *
- */
-int pcidriver_umem_sync( pcidriver_privdata_t *privdata, umem_handle_t *umem_handle )
-{
-	pcidriver_umem_entry_t *umem_entry;
-
-	/* Find the associated umem_entry for this buffer */
-	umem_entry = pcidriver_umem_find_entry_id( privdata, umem_handle->handle_id );
-	if (umem_entry == NULL)
-		return -EINVAL;					/* umem_handle is not valid */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
-	switch (umem_handle->dir) {
-		case PCIDRIVER_DMA_TODEVICE:
-			pci_dma_sync_sg_for_device( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_TODEVICE );
-			break;
-		case PCIDRIVER_DMA_FROMDEVICE:
-			pci_dma_sync_sg_for_cpu( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_FROMDEVICE );
-			break;
-		case PCIDRIVER_DMA_BIDIRECTIONAL:
-			pci_dma_sync_sg_for_device( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_BIDIRECTIONAL );
-			pci_dma_sync_sg_for_cpu( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_BIDIRECTIONAL );
-			break;
-		default:
-			return -EINVAL;				/* wrong direction parameter */
-	}
-#else
-	switch (umem_handle->dir) {
-		case PCIDRIVER_DMA_TODEVICE:
-			pci_dma_sync_sg( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_TODEVICE );
-			break;
-		case PCIDRIVER_DMA_FROMDEVICE:
-			pci_dma_sync_sg( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_FROMDEVICE );
-			break;
-		case PCIDRIVER_DMA_BIDIRECTIONAL:
-			pci_dma_sync_sg( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_BIDIRECTIONAL );
-			break;
-		default:
-			return -EINVAL;				/* wrong direction parameter */
-	}
-#endif
-
-	return 0;
-}
-
-/*
- *
- * Get the pcidriver_umem_entry_t structure for the given id.
- *
- * @param id ID of the umem entry to search for
- *
- */
-pcidriver_umem_entry_t *pcidriver_umem_find_entry_id(pcidriver_privdata_t *privdata, int id)
-{
-	struct list_head *ptr;
-	pcidriver_umem_entry_t *entry;
-
-	spin_lock(&(privdata->umemlist_lock));
-	list_for_each(ptr, &(privdata->umem_list)) {
-		entry = list_entry(ptr, pcidriver_umem_entry_t, list );
-
-		if (entry->id == id) {
-			spin_unlock( &(privdata->umemlist_lock) );
-			return entry;
-		}
-	}
-
-	spin_unlock(&(privdata->umemlist_lock));
-	return NULL;
-}

+ 0 - 5
driver/umem.h

@@ -1,5 +0,0 @@
-int pcidriver_umem_sgmap( pcidriver_privdata_t *privdata, umem_handle_t *umem_handle );
-int pcidriver_umem_sgunmap( pcidriver_privdata_t *privdata, pcidriver_umem_entry_t *umem_entry );
-int pcidriver_umem_sgget( pcidriver_privdata_t *privdata, umem_sglist_t *umem_sglist );
-int pcidriver_umem_sync( pcidriver_privdata_t *privdata, umem_handle_t *umem_handle );
-pcidriver_umem_entry_t *pcidriver_umem_find_entry_id( pcidriver_privdata_t *privdata, int id );

+ 0 - 27
error.c

@@ -1,27 +0,0 @@
-#define _PCILIB_ERROR_C
-
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "error.h"
-
-static void pcilib_print_error(const char *msg, ...) {
-    va_list va;
-    
-    va_start(va, msg);
-    vprintf(msg, va);
-    va_end(va);
-    printf("\n");
-}
-
-void (*pcilib_error)(const char *msg, ...) = pcilib_print_error;
-void (*pcilib_warning)(const char *msg, ...) = pcilib_print_error;
-
-int pcilib_set_error_handler(void (*err)(const char *msg, ...), void (*warn)(const char *msg, ...)) {
-    if (err) pcilib_error = err;
-    else pcilib_error = pcilib_print_error;
-    if (warn) pcilib_warning = warn;
-    else pcilib_warning = pcilib_print_error;
-
-    return 0;
-}

+ 0 - 34
error.h

@@ -1,34 +0,0 @@
-#ifndef _PCILIB_ERROR_H
-#define _PCILIB_ERROR_H
-
-#include <errno.h>
- 
-enum {
-    PCILIB_ERROR_SUCCESS = 0,
-    PCILIB_ERROR_MEMORY = ENOMEM,
-    PCILIB_ERROR_INVALID_REQUEST = EBADR,
-    PCILIB_ERROR_INVALID_ADDRESS = EFAULT,
-    PCILIB_ERROR_INVALID_BANK = ENOENT,
-    PCILIB_ERROR_INVALID_DATA = EILSEQ,
-    PCILIB_ERROR_INVALID_STATE =  EBADFD,
-    PCILIB_ERROR_INVALID_ARGUMENT = EINVAL,
-    PCILIB_ERROR_TIMEOUT = ETIME,
-    PCILIB_ERROR_FAILED = EBADE,
-    PCILIB_ERROR_VERIFY = EREMOTEIO,
-    PCILIB_ERROR_NOTSUPPORTED = ENOTSUP,
-    PCILIB_ERROR_NOTFOUND = ESRCH,
-    PCILIB_ERROR_OUTOFRANGE = ERANGE,
-    PCILIB_ERROR_NOTAVAILABLE = ENAVAIL,
-    PCILIB_ERROR_NOTINITIALIZED = EBADFD,
-    PCILIB_ERROR_TOOBIG = EFBIG,
-    PCILIB_ERROR_OVERWRITTEN = ESTALE,
-    PCILIB_ERROR_BUSY = EBUSY
-} pcilib_errot_t;
-
-
-#ifndef _PCILIB_ERROR_C
-extern void (*pcilib_error)(const char *msg, ...);
-extern void (*pcilib_warning)(const char *msg, ...);
-#endif /* _PCILIB_ERROR_C */
-
-#endif /* _PCILIB_ERROR_H */

+ 0 - 450
event.c

@@ -1,450 +0,0 @@
-#define _POSIX_C_SOURCE 199309L
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <assert.h>
-#include <time.h>
-
-#include "pci.h"
-
-#include "tools.h"
-#include "error.h"
-
-#ifndef __timespec_defined
-struct timespec {
-    time_t tv_sec;
-    long tv_nsec;
-};
-#endif /* __timespec_defined */
-
-
-pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
-    int i;
-
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_event_description_t *events = model_info->events;
-
-    for (i = 0; events[i].name; i++) {
-	if (!strcasecmp(events[i].name, event)) return events[i].evid;
-    }
-
-    return (pcilib_event_t)-1;
-}
-
-pcilib_event_data_type_t pcilib_find_event_data_type(pcilib_t *ctx, pcilib_event_t event, const char *data_type) {
-    int i;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_event_data_type_description_t *data_types = model_info->data_types;
-    
-    for (i = 0; data_types[i].name; i++) {
-	if ((data_types[i].evid&event)&&(!strcasecmp(data_types[i].name, data_type))) return data_types[i].data_type;
-    }
-
-    return (pcilib_event_data_type_t)-1;
-}
-
-int pcilib_init_event_engine(pcilib_t *ctx) {
-    pcilib_event_api_description_t *api;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-
-//    api = pcilib_model[model].event_api;
-    if ((api)&&(api->init)) {
-	ctx->event_ctx = api->init(ctx);
-	if (ctx->event_ctx) {
-	    ctx->event_ctx->pcilib = ctx;
-	}
-    }
-    
-    return 0;
-}
-
-int pcilib_reset(pcilib_t *ctx) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-    
-    if (api->reset) 
-	return api->reset(ctx->event_ctx);
-	
-    return 0;
-}
-
-int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    ctx->event_ctx->params.rawdata.callback = callback;
-    ctx->event_ctx->params.rawdata.user = user;
-    
-    return 0;    
-}
-
-int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t duration) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    ctx->event_ctx->params.autostop.max_events = max_events;
-    ctx->event_ctx->params.autostop.duration = duration;
-    
-    return 0;    
-}
-
-int pcilib_configure_autotrigger(pcilib_t *ctx, pcilib_timeout_t interval, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
-	/* To support hardware without autotriggering, we need to provide in event.c a code 
-	to generate multiple triggers in a thread (available in cli). The function should 
-	be re-enabled afterwards: just set parameters and let implementation decide if it 
-	can make triggering in hardware or will use our emulation */
-	
-    return PCILIB_ERROR_NOTSUPPORTED;
-}
-
-int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    ctx->event_ctx->params.parallel.max_threads = max_threads;
-
-    return 0;
-}
-
-int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->start) 
-	return api->start(ctx->event_ctx, event_mask, flags);
-
-    return 0;
-}
-
-int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->stop) 
-	return api->stop(ctx->event_ctx, flags);
-
-    return 0;
-}
-
-int pcilib_stream(pcilib_t *ctx, pcilib_event_callback_t callback, void *user) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->stream)
-	return api->stream(ctx->event_ctx, callback, user);
-
-    if (api->next_event) {
-	pcilib_error("Streaming using next_event API is not implemented yet");
-    }
-
-    pcilib_error("Event enumeration is not suppored by API");
-    return PCILIB_ERROR_NOTSUPPORTED;
-}
-/*
-typedef struct {
-    pcilib_event_id_t event_id;
-    pcilib_event_info_t *info;
-} pcilib_return_event_callback_context_t;
-
-static int pcilib_return_event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) {
-    pcilib_return_event_callback_context_t *ctx = (pcilib_return_event_callback_context_t*)user;
-    ctx->event_id = event_id;
-    ctx->info = info;
-}
-*/
-
-int pcilib_get_next_event(pcilib_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info) {
-    pcilib_event_api_description_t *api;
-//    pcilib_return_event_callback_context_t user;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->next_event) 
-	return api->next_event(ctx->event_ctx, timeout, evid, info_size, info);
-
-/*	
-    if (api->stream) {
-	err = api->stream(ctx->event_ctx, 1, timeout, pcilib_return_event_callback, &user);
-	if (err) return err;
-	
-	if (evid) *evid = user->event_id;
-	if (info) *info = user->info;
-
-	return 0;
-    }
-*/
-
-    pcilib_error("Event enumeration is not suppored by API");
-    return PCILIB_ERROR_NOTSUPPORTED;
-}
-
-int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
-    pcilib_event_api_description_t *api;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->trigger) 
-	return api->trigger(ctx->event_ctx, event, trigger_size, trigger_data);
-
-    pcilib_error("Self triggering is not supported by the selected model");
-    return PCILIB_ERROR_NOTSUPPORTED;
-}
-
-
-void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size) {
-    int err;
-    void *res = NULL;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    pcilib_event_api_description_t *api = model_info->event_api;
-    if (!api) {
-	if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
-	pcilib_error("Event API is not supported by the selected model");
-	return NULL;
-    }
-
-    if (api->get_data) {
-	err = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, size, &res);
-	if (err) {
-	    if (size) *size = (size_t)err;
-	    return NULL;
-	}
-	return res;
-    }
-    
-    if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
-    return NULL;
-}
-
-int pcilib_copy_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t size, void *buf, size_t *retsize) {
-    int err;
-    void *res = buf;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    pcilib_event_api_description_t *api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->get_data) {
-	err = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, &size, &res);
-	if (err) return err;
-	
-	if (buf != res) memcpy(buf, res, size);
-	
-	if (retsize) *retsize = size;
-	return 0;
-    }	
-
-    return PCILIB_ERROR_NOTSUPPORTED;
-}
-
-
-void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) {
-    int err;
-    void *res = NULL;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    pcilib_event_api_description_t *api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
-	return NULL;
-    }
-
-    if (api->get_data) {
-	err = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, size, &res);
-	if (err) {
-	    if (size) *size = (size_t)err;
-	    return NULL;
-	}
-	return res;
-    }
-
-    if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED;
-    return NULL;
-}
-
-int pcilib_copy_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t size, void *buf, size_t *ret_size) {
-    int err;
-    void *res = buf;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    pcilib_event_api_description_t *api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->get_data) {
-	err = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, &size, &res);
-	if (err) return err;
-	
-	if (buf != res) memcpy(buf, res, size);
-
-	if (ret_size) *ret_size = size;
-	return 0;
-    }
-
-    return PCILIB_ERROR_NOTSUPPORTED;
-}
-
-int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data) {
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    
-    pcilib_event_api_description_t *api = model_info->event_api;
-    if (!api) {
-	pcilib_error("Event API is not supported by the selected model");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    }
-
-    if (api->return_data) 
-	return api->return_data(ctx->event_ctx, event_id, data_type, data);
-
-    return 0;
-}
-
-
-typedef struct {
-    pcilib_t *ctx;
-    
-    size_t *size;
-    void **data;
-} pcilib_grab_callback_user_data_t;
-
-
-static int pcilib_grab_callback(pcilib_event_t event, pcilib_event_id_t event_id, void *vuser) {
-    int err;
-    void *data;
-    size_t size;
-    int allocated = 0;
-
-    pcilib_grab_callback_user_data_t *user = (pcilib_grab_callback_user_data_t*)vuser;
-
-    data = pcilib_get_data(user->ctx, event_id, PCILIB_EVENT_DATA, &size);
-    if (!data) {
-	pcilib_error("Error getting event data");
-	return -(int)size;
-    }
-    
-    if (*(user->data)) {
-	if ((user->size)&&(*(user->size) < size)) {
-	    pcilib_error("The supplied buffer does not have enough space to hold the event data. Buffer size is %z, but %z is required", user->size, size);
-	    return -PCILIB_ERROR_MEMORY;
-	}
-
-	*(user->size) = size;
-    } else {
-	*(user->data) = malloc(size);
-	if (!*(user->data)) {
-	    pcilib_error("Memory allocation (%i bytes) for event data is failed");
-	    return -PCILIB_ERROR_MEMORY;
-	}
-	if (*(user->size)) *(user->size) = size;
-	allocated = 1;
-    }
-    
-    memcpy(*(user->data), data, size);
-    
-    err = pcilib_return_data(user->ctx, event_id, PCILIB_EVENT_DATA, data);
-    if (err) {
-	if (allocated) {
-	    free(*(user->data));
-	    *(user->data) = NULL;
-	}
-	pcilib_error("The event data had been overwritten before it was returned, data corruption may occur");
-	return -err;
-    }
-    
-    return PCILIB_STREAMING_CONTINUE;
-}
-
-int pcilib_grab(pcilib_t *ctx, pcilib_event_t event_mask, size_t *size, void **data, pcilib_timeout_t timeout) {
-    int err;
-    pcilib_event_id_t eid;
-    
-    pcilib_grab_callback_user_data_t user = {ctx, size, data};
-    
-    err = pcilib_start(ctx, event_mask, PCILIB_EVENT_FLAGS_DEFAULT);
-    if (!err) err = pcilib_trigger(ctx, event_mask, 0, NULL);
-    if (!err) {
-	err = pcilib_get_next_event(ctx, timeout, &eid, 0, NULL);
-	if (!err) pcilib_grab_callback(event_mask, eid, &user);
-    }
-    pcilib_stop(ctx, PCILIB_EVENT_FLAGS_DEFAULT);
-    return err;
-}

+ 0 - 69
event.h

@@ -1,69 +0,0 @@
-#ifndef _PCILIB_EVENT_H
-#define _PCILIB_EVENT_H
-
-#include "pcilib.h"
-
-
-/*
- * get_data: This call is used by get_data and copy_data functions of public  
- * interface. When copy_data is the caller, the data parameter will be passed.
- * Therefore, depending on data the parameter, the function should behave
- * diferently. If get get_data function is used (buf == NULL), the caller is 
- * expected to call return_data afterwards. Otherwise, if buf != NULL and 
- * copy_data is used, the return call will not be executed.
- * Still, the get_data function is not obliged to return the data in the
- * passed buf, but a reference to the staticaly allocated memory may be 
- * returned instead. The copy can be managed by the envelope function.
- */
-
-struct pcilib_event_api_description_s {
-    const char *title;
-    
-    pcilib_context_t *(*init)(pcilib_t *ctx);
-    void (*free)(pcilib_context_t *ctx);
-
-    pcilib_dma_context_t *(*init_dma)(pcilib_context_t *ctx);
-
-    int (*reset)(pcilib_context_t *ctx);
-
-    int (*start)(pcilib_context_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags);
-    int (*stop)(pcilib_context_t *ctx, pcilib_event_flags_t flags);
-    int (*trigger)(pcilib_context_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data);
-    
-    int (*stream)(pcilib_context_t *ctx, pcilib_event_callback_t callback, void *user);
-    int (*next_event)(pcilib_context_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info);
-
-    int (*get_data)(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **data);
-    int (*return_data)(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data);
-};
-
-
-typedef struct {
-    size_t max_events;
-    pcilib_timeout_t duration;
-} pcilib_autostop_parameters_t;
-
-typedef struct {
-    pcilib_event_rawdata_callback_t callback;
-    void *user;
-} pcilib_rawdata_parameters_t;
-
-typedef struct {
-    size_t max_threads;
-} pcilib_parallel_parameters_t;
-
-typedef struct {
-    pcilib_autostop_parameters_t autostop;
-    pcilib_rawdata_parameters_t rawdata;
-    pcilib_parallel_parameters_t parallel;
-} pcilib_event_parameters_t;
-
-struct pcilib_event_context_s {
-    pcilib_event_parameters_t params;
-    pcilib_t *pcilib;
-};
-
-
-int pcilib_init_event_engine(pcilib_t *ctx);
-
-#endif /* _PCILIB_EVENT_H */

+ 4 - 4
ipecamera/events.c → events.c

@@ -11,11 +11,11 @@
 
 #include <ufodecode.h>
 
-#include "../tools.h"
-#include "../error.h"
+#include <pcilib.h>
+#include <pcilib/tools.h>
+#include <pcilib/error.h>
 
-#include "pcilib.h"
-#include "public.h"
+#include "ipecamera.h"
 #include "private.h"
 #include "events.h"
 

+ 0 - 0
ipecamera/events.h → events.h


+ 1 - 0
ipecamera/ipecamera.h → ipecamera.h

@@ -35,4 +35,5 @@ typedef struct {
 
 int ipecamera_set_buffer_size(ipecamera_t *ctx, int size);
 
+
 #endif /* _IPECAMERA_H */

+ 0 - 12
ipecamera/CMakeLists.txt

@@ -1,12 +0,0 @@
-include_directories(
-    ${CMAKE_SOURCE_DIR}
-    ${UFODECODE_INCLUDE_DIRS}
-)
-
-set(HEADERS ${HEADERS} ipecamera.h model.h reader.h events.h data.h public.h private.h)
-
-add_library(ipecamera STATIC ipecamera.c model.c reader.c events.c data.c)
-
-install(FILES ipecamera.h
-    DESTINATION include
-)

+ 0 - 55
irq.c

@@ -1,55 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "pci.h"
-
-#include "tools.h"
-#include "error.h"
-
-int pcilib_wait_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source, pcilib_timeout_t timeout, size_t *count) {
-    int err;
-    
-    interrupt_wait_t arg = { 0 };
-    
-    arg.source = source;
-    arg.timeout = timeout;
-
-    if (count) arg.count = 1;
-
-    err = ioctl(ctx->handle, PCIDRIVER_IOC_WAITI, &arg);
-    if (err) {
-	pcilib_error("PCIDRIVER_IOC_WAITI ioctl have failed");
-	return PCILIB_ERROR_FAILED;
-    }
-    
-    if (!arg.count) return PCILIB_ERROR_TIMEOUT;
-
-    if (count) *count = arg.count;
-    
-    return 0;
-}
-
-int pcilib_clear_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source) {
-    int err;
-    
-    err = ioctl(ctx->handle, PCIDRIVER_IOC_CLEAR_IOQ, source);
-    if (err) {
-	pcilib_error("PCIDRIVER_IOC_CLEAR_IOQ ioctl have failed");
-	return PCILIB_ERROR_FAILED;
-    }
-    
-    return 0;
-}
-
-

+ 0 - 5
irq.h

@@ -1,5 +0,0 @@
-#ifndef _PCILIB_IRQ_H
-#define _PCILIB_IRQ_H
-
-
-#endif /* _PCILIB_IRQ_H */

+ 0 - 9
kapture/CMakeLists.txt

@@ -1,9 +0,0 @@
-include_directories(
-    ${CMAKE_SOURCE_DIR}
-    ${UFODECODE_INCLUDE_DIRS}
-)
-
-set(HEADERS ${HEADERS} model.h)
-
-add_library(kapture STATIC kapture.c)
-

+ 0 - 62
kapture/kapture.c

@@ -1,62 +0,0 @@
-#define _KAPTURE_C
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <pthread.h>
-#include <assert.h>
-
-#include "../tools.h"
-#include "../error.h"
-#include "../event.h"
-
-#include "pcilib.h"
-#include "model.h"
-#include "kapture.h"
-#include "private.h"
-
-
-pcilib_context_t *kapture_init(pcilib_t *vctx) {
-    kapture_t *ctx = malloc(sizeof(kapture_t));
-
-    if (ctx) {
-	memset(ctx, 0, sizeof(kapture_t));
-    }
-
-    return ctx;
-}
-
-void kapture_free(pcilib_context_t *vctx) {
-    if (vctx) {
-	kapture_t *ctx = (kapture_t*)vctx;
-	kapture_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
-	free(ctx);
-    }
-}
-
-int kapture_reset(pcilib_context_t *ctx) {
-}
-
-int kapture_start(pcilib_context_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
-}
-
-int kapture_stop(pcilib_context_t *ctx, pcilib_event_flags_t flags) {
-}
-
-int kapture_trigger(pcilib_context_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
-}
-
-int kapture_stream(pcilib_context_t *ctx, pcilib_event_callback_t callback, void *user) {
-}
-
-int kapture_next_event(pcilib_context_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info) {
-}
-
-int kapture_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **data) {
-}
-
-int kapture_return(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data) {
-}
-
-

+ 0 - 6
kapture/kapture.h

@@ -1,6 +0,0 @@
-#ifndef _KAPTURE_H
-#define _KAPTURE_H
-
-typedef struct kapture_s kapture_t;
-
-#endif /* _KAPTURE_H */

+ 0 - 81
kapture/model.h

@@ -1,81 +0,0 @@
-#ifndef _KAPTURE_MODEL_H
-#define _KAPTURE_MODEL_H
-
-#include <stdio.h>
-
-#include "../pcilib.h"
-
-
-#define KAPTURE_REGISTER_SPACE 0x9000
-
-#ifdef _KAPTURE_C
-pcilib_register_bank_description_t kapture_register_banks[] = {
-//    { PCILIB_REGISTER_BANK0,    PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL    , KAPTURE_REGISTER_SPACE, KAPTURE_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "KAPTURE Registers" },
-    { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL    , 0,                        0,                    PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
-};
-
-pcilib_register_description_t kapture_registers[] = {
-{0,	0,	0,	0,	0,                        0,                  0,                        0,                     NULL, NULL}
-};
-
-pcilib_register_range_t kapture_register_ranges[] = {
-    {0, 0, 0, 0}
-};
-
-pcilib_event_description_t kapture_events[] = {
-    {PCILIB_EVENT0, "event", ""},
-    {0, NULL, NULL}
-};
-
-pcilib_event_data_type_description_t kapture_data_types[] = {
-    {PCILIB_EVENT_RAW_DATA, PCILIB_EVENT0, "raw", "raw data from kapture" },
-    {0, 0, NULL, NULL}
-};
-
-#else
-extern pcilib_register_description_t kapture_registers[];
-extern pcilib_register_bank_description_t kapture_register_banks[];
-extern pcilib_register_range_t kapture_register_ranges[];
-extern pcilib_event_description_t kapture_events[];
-extern pcilib_event_data_type_description_t kapture_data_types[];
-#endif 
-
-
-pcilib_context_t *kapture_init(pcilib_t *pcilib);
-void kapture_free(pcilib_context_t *ctx);
-
-int kapture_reset(pcilib_context_t *ctx);
-int kapture_start(pcilib_context_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags);
-int kapture_stop(pcilib_context_t *ctx, pcilib_event_flags_t flags);
-int kapture_trigger(pcilib_context_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data);
-int kapture_stream(pcilib_context_t *vctx, pcilib_event_callback_t callback, void *user);
-int kapture_next_event(pcilib_context_t *vctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info);
-int kapture_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **buf);
-int kapture_return(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data);
-
-#ifdef _KAPTURE_C
-pcilib_event_api_description_t kapture_api = {
-    "kapture",
-    
-    kapture_init,
-    kapture_free,
-
-    NULL,
-
-    kapture_reset,
-    kapture_start,
-    kapture_stop,
-    kapture_trigger,
-    
-    kapture_stream,
-    kapture_next_event,
-    kapture_get,
-    kapture_return
-};
-#else
-extern pcilib_event_api_description_t kapture_api;
-#endif
-
-
-#endif /* _KAPTURE_MODEL_H */

+ 0 - 10
kapture/private.h

@@ -1,10 +0,0 @@
-#ifndef _KAPTURE_PRIVATE_H
-#define _KAPTURE_PRIVATE_H
-
-struct kapture_s {
-    pcilib_context_t event;
-
-};
-
-
-#endif /* _KAPTURE_PRIVATE_H */

+ 0 - 81
kernel.h

@@ -1,81 +0,0 @@
-/*
- * Extract from kernel headers
- * iomap.h
- */
-
-/*
- * IO resources have these defined flags.
- */
-#define IORESOURCE_BITS		0x000000ff	/* Bus-specific bits */
-
-#define IORESOURCE_TYPE_BITS	0x00000f00	/* Resource type */
-#define IORESOURCE_IO		0x00000100
-#define IORESOURCE_MEM		0x00000200
-#define IORESOURCE_IRQ		0x00000400
-#define IORESOURCE_DMA		0x00000800
-
-#define IORESOURCE_PREFETCH	0x00001000	/* No side effects */
-#define IORESOURCE_READONLY	0x00002000
-#define IORESOURCE_CACHEABLE	0x00004000
-#define IORESOURCE_RANGELENGTH	0x00008000
-#define IORESOURCE_SHADOWABLE	0x00010000
-
-#define IORESOURCE_SIZEALIGN	0x00020000	/* size indicates alignment */
-#define IORESOURCE_STARTALIGN	0x00040000	/* start field is alignment */
-
-#define IORESOURCE_MEM_64	0x00100000
-
-#define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
-#define IORESOURCE_DISABLED	0x10000000
-#define IORESOURCE_UNSET	0x20000000
-#define IORESOURCE_AUTO		0x40000000
-#define IORESOURCE_BUSY		0x80000000	/* Driver has marked this resource busy */
-
-/* PnP IRQ specific bits (IORESOURCE_BITS) */
-#define IORESOURCE_IRQ_HIGHEDGE		(1<<0)
-#define IORESOURCE_IRQ_LOWEDGE		(1<<1)
-#define IORESOURCE_IRQ_HIGHLEVEL	(1<<2)
-#define IORESOURCE_IRQ_LOWLEVEL		(1<<3)
-#define IORESOURCE_IRQ_SHAREABLE	(1<<4)
-#define IORESOURCE_IRQ_OPTIONAL 	(1<<5)
-
-/* PnP DMA specific bits (IORESOURCE_BITS) */
-#define IORESOURCE_DMA_TYPE_MASK	(3<<0)
-#define IORESOURCE_DMA_8BIT		(0<<0)
-#define IORESOURCE_DMA_8AND16BIT	(1<<0)
-#define IORESOURCE_DMA_16BIT		(2<<0)
-
-#define IORESOURCE_DMA_MASTER		(1<<2)
-#define IORESOURCE_DMA_BYTE		(1<<3)
-#define IORESOURCE_DMA_WORD		(1<<4)
-
-#define IORESOURCE_DMA_SPEED_MASK	(3<<6)
-#define IORESOURCE_DMA_COMPATIBLE	(0<<6)
-#define IORESOURCE_DMA_TYPEA		(1<<6)
-#define IORESOURCE_DMA_TYPEB		(2<<6)
-#define IORESOURCE_DMA_TYPEF		(3<<6)
-
-/* PnP memory I/O specific bits (IORESOURCE_BITS) */
-#define IORESOURCE_MEM_WRITEABLE	(1<<0)	/* dup: IORESOURCE_READONLY */
-#define IORESOURCE_MEM_CACHEABLE	(1<<1)	/* dup: IORESOURCE_CACHEABLE */
-#define IORESOURCE_MEM_RANGELENGTH	(1<<2)	/* dup: IORESOURCE_RANGELENGTH */
-#define IORESOURCE_MEM_TYPE_MASK	(3<<3)
-#define IORESOURCE_MEM_8BIT		(0<<3)
-#define IORESOURCE_MEM_16BIT		(1<<3)
-#define IORESOURCE_MEM_8AND16BIT	(2<<3)
-#define IORESOURCE_MEM_32BIT		(3<<3)
-#define IORESOURCE_MEM_SHADOWABLE	(1<<5)	/* dup: IORESOURCE_SHADOWABLE */
-#define IORESOURCE_MEM_EXPANSIONROM	(1<<6)
-
-/* PnP I/O specific bits (IORESOURCE_BITS) */
-#define IORESOURCE_IO_16BIT_ADDR	(1<<0)
-#define IORESOURCE_IO_FIXED		(1<<1)
-
-/* PCI ROM control bits (IORESOURCE_BITS) */
-#define IORESOURCE_ROM_ENABLE		(1<<0)	/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
-#define IORESOURCE_ROM_SHADOW		(1<<1)	/* ROM is copy at C000:0 */
-#define IORESOURCE_ROM_COPY		(1<<2)	/* ROM is alloc'd copy, resource field overlaid */
-#define IORESOURCE_ROM_BIOS_COPY	(1<<3)	/* ROM is BIOS copy, resource field overlaid */
-
-/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
-#define IORESOURCE_PCI_FIXED		(1<<4)	/* Do not move resource */

+ 0 - 310
kmem.c

@@ -1,310 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "pcilib.h"
-#include "pci.h"
-#include "kmem.h"
-#include "error.h"
-
-int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags) {
-    kmem_handle_t kh = {0};
-    kh.use = use;
-    kh.flags = flags|KMEM_FLAG_MASS;
-
-    return ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_FREE, &kh);
-}
-
-
-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);
-    kh.handle_id = kbuf->buf.blocks[i].handle_id;
-    kh.pa = kbuf->buf.blocks[i].pa;
-    kh.flags = flags;
-    
-    return ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_FREE, &kh);
-}
-
-static void pcilib_cancel_kernel_memory(pcilib_t *ctx, pcilib_kmem_list_t *kbuf, pcilib_kmem_flags_t flags, int last_flags) {
-    int ret;
-    
-    if (!kbuf->buf.n_blocks) return;
-
-	// consistency error during processing of last block, special treatment could be needed
-    if (last_flags) {
-	pcilib_kmem_flags_t failed_flags = flags;
-	
-	if (last_flags&KMEM_FLAG_REUSED_PERSISTENT) flags&=~PCILIB_KMEM_FLAG_PERSISTENT;
-	if (last_flags&KMEM_FLAG_REUSED_HW) flags&=~PCILIB_KMEM_FLAG_HARDWARE;
-	
-	if (failed_flags != flags) {
-	    ret = pcilib_free_kernel_buffer(ctx, kbuf, --kbuf->buf.n_blocks, failed_flags);
-	    if (ret) pcilib_error("PCIDRIVER_IOC_KMEM_FREE ioctl have failed");
-	}
-    }
-
-    pcilib_free_kernel_memory(ctx, kbuf, flags);
-}
-
-pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type_t type, size_t nmemb, size_t size, size_t alignment, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags) {
-    int err = 0;
-    const char *error = NULL;
-    
-    int ret;
-    int i;
-    void *addr;
-    
-    pcilib_tristate_t reused = PCILIB_TRISTATE_NO;
-    int persistent = -1;
-    int hardware = -1;
-
-    kmem_handle_t kh = {0};
-    
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)malloc(sizeof(pcilib_kmem_list_t) + nmemb * sizeof(pcilib_kmem_addr_t));
-    if (!kbuf) {
-	pcilib_error("Memory allocation has failed");
-	return NULL;
-    }
-    
-    memset(kbuf, 0, sizeof(pcilib_kmem_list_t) + nmemb * sizeof(pcilib_kmem_addr_t));
-    
-    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_KMEM );
-    if (ret) {
-	pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed");
-	return NULL;
-    }
-    
-    kh.type = type;
-    kh.size = size;
-    kh.align = alignment;
-    kh.use = use;
-
-    if ((type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) {
-	kh.align = 0;
-    } else if ((type&PCILIB_KMEM_TYPE_MASK) != PCILIB_KMEM_TYPE_PAGE) {
-	kh.size += alignment;
-    }
-
-    for ( i = 0; i < nmemb; i++) {
-	kh.item = i;
-	kh.flags = flags;
-
-	if ((type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) {
-	    kh.pa = alignment + i * size;
-	}
-	
-        ret = ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_ALLOC, &kh);
-	if (ret) {
-	    kbuf->buf.n_blocks = i;
-	    error = "PCIDRIVER_IOC_KMEM_ALLOC ioctl have failed";
-	    break;
-	}
-	
-	kbuf->buf.blocks[i].handle_id = kh.handle_id;
-	kbuf->buf.blocks[i].pa = kh.pa;
-	kbuf->buf.blocks[i].size = kh.size;
-	
-	if (!i) reused = (kh.flags&KMEM_FLAG_REUSED)?PCILIB_TRISTATE_YES:PCILIB_TRISTATE_NO;
-
-        if (kh.flags&KMEM_FLAG_REUSED) {
-	    if (!i) reused = PCILIB_TRISTATE_YES;
-	    else if (!reused) reused = PCILIB_TRISTATE_PARTIAL;
-	
-	    if (persistent) {
-		if (persistent < 0) {
-		    /*if (((flags&PCILIB_KMEM_FLAG_PERSISTENT) == 0)&&(kh.flags&KMEM_FLAG_REUSED_PERSISTENT)) err = PCILIB_ERROR_INVALID_STATE;
-		    else*/ persistent = (kh.flags&KMEM_FLAG_REUSED_PERSISTENT)?1:0;
-		} else if ((kh.flags&KMEM_FLAG_REUSED_PERSISTENT) == 0) err = PCILIB_ERROR_INVALID_STATE;
-	    } else if (kh.flags&KMEM_FLAG_REUSED_PERSISTENT) err = PCILIB_ERROR_INVALID_STATE;
-	    
-	    if (hardware) {
-		if (hardware < 0) {
-		    /*if (((flags&PCILIB_KMEM_FLAG_HARDWARE) == 0)&&(kh.flags&KMEM_FLAG_REUSED_HW)) err = PCILIB_ERROR_INVALID_STATE;
-		    else*/ hardware = (kh.flags&KMEM_FLAG_REUSED_HW)?1:0;
-		} else if ((kh.flags&KMEM_FLAG_REUSED_HW) == 0) err = PCILIB_ERROR_INVALID_STATE;
-	    } else if (kh.flags&KMEM_FLAG_REUSED_HW) err = PCILIB_ERROR_INVALID_STATE;
-	    
-	} else {
-	    if (!i) reused = PCILIB_TRISTATE_NO;
-	    else if (reused) reused = PCILIB_TRISTATE_PARTIAL;
-	    
-	    if ((persistent > 0)&&((flags&PCILIB_KMEM_FLAG_PERSISTENT) == 0)) err = PCILIB_ERROR_INVALID_STATE;
-	    if ((hardware > 0)&&((flags&PCILIB_KMEM_FLAG_HARDWARE) == 0)) err = PCILIB_ERROR_INVALID_STATE;
-	}
-	
-	if (err) {
-	    kbuf->buf.n_blocks = i + 1;
-	    break;
-	}
-    
-        if ((kh.align)&&((kh.type&PCILIB_KMEM_TYPE_MASK) != PCILIB_KMEM_TYPE_PAGE)) {
-	    if (kh.pa % kh.align) kbuf->buf.blocks[i].alignment_offset = kh.align - kh.pa % kh.align;
-	    kbuf->buf.blocks[i].size -= kh.align;
-	}
-
-    	addr = mmap( 0, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset, PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 );
-	if ((!addr)||(addr == MAP_FAILED)) {
-	    kbuf->buf.n_blocks = i + 1;
-	    error = "Failed to mmap allocated kernel memory";
-	    break;
-	}
-
-	kbuf->buf.blocks[i].ua = addr;
-//	if (use == PCILIB_KMEM_USE_DMA_PAGES) {
-//	memset(addr, 10, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset);
-//	}
-	
-	kbuf->buf.blocks[i].mmap_offset = kh.pa & ctx->page_mask;
-    }
-
-	//This is possible in the case of error (nothing is allocated yet) or if buffers are not reused
-    if (persistent < 0) persistent = 0;
-    if (hardware < 0) hardware = 0;
-
-    if (err||error) {
-	pcilib_kmem_flags_t free_flags = 0;
-	
-	    // for the sake of simplicity always clean partialy reused buffers
-	if ((persistent == PCILIB_TRISTATE_PARTIAL)||((persistent <= 0)&&(flags&PCILIB_KMEM_FLAG_PERSISTENT))) {
-	    free_flags |= PCILIB_KMEM_FLAG_PERSISTENT;
-	}
-	
-	if ((hardware <= 0)&&(flags&PCILIB_KMEM_FLAG_HARDWARE)) {
-	    free_flags |= PCILIB_KMEM_FLAG_HARDWARE;
-	}
-	
-	    // do not clean if we have reused peresistent buffers
-	    //  we don't care about -1, because it will be the value only if no buffers actually allocated
-	if ((!persistent)||(reused != PCILIB_TRISTATE_YES)) {
-	    pcilib_cancel_kernel_memory(ctx, kbuf, free_flags, err?kh.flags:0);
-	}
-
-	if (!error) error = "Reused buffers are inconsistent";
-	pcilib_error(error);
-
-	return NULL;
-    }
-    
-    if (nmemb == 1) {
-	memcpy(&kbuf->buf.addr, &kbuf->buf.blocks[0], sizeof(pcilib_kmem_addr_t));
-    }
-    
-    kbuf->buf.reused = reused|(persistent?PCILIB_KMEM_REUSE_PERSISTENT:0)|(hardware?PCILIB_KMEM_REUSE_HARDWARE:0);
-    kbuf->buf.n_blocks = nmemb;
-    
-    kbuf->prev = NULL;
-    kbuf->next = ctx->kmem_list;
-    if (ctx->kmem_list) ctx->kmem_list->prev = kbuf;
-    ctx->kmem_list = kbuf;
-
-    return (pcilib_kmem_handle_t*)kbuf;
-}
-
-void pcilib_free_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_flags_t flags) {
-    int ret, err = 0; 
-    int i;
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
-
-	// if linked in to the list
-    if (kbuf->next) kbuf->next->prev = kbuf->prev;
-    if (kbuf->prev) kbuf->prev->next = kbuf->next;
-    else if (ctx->kmem_list == kbuf) ctx->kmem_list = kbuf->next;
-
-    for (i = 0; i < kbuf->buf.n_blocks; i++) {
-        ret = pcilib_free_kernel_buffer(ctx, kbuf, i, flags);
-    	if ((ret)&&(!err)) err = ret;
-    }
-    
-    free(kbuf);
-    
-    if (err) {
-	pcilib_error("PCIDRIVER_IOC_KMEM_FREE ioctl have failed");
-    }
-}
-
-/*
-int pcilib_kmem_sync(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir) {
-    int i;
-    int ret;
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
-    
-    for (i = 0; i < kbuf->buf.n_blocks; i++) {
-	ret = pcilib_kmem_sync_block(ctx, k, dir, i);
-	if (ret) {
-	    pcilib_error("PCIDRIVER_IOC_KMEM_SYNC ioctl have failed");
-	    return PCILIB_ERROR_FAILED;
-	}
-    }
-    
-    return 0;    
-}
-*/
-
-int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir, size_t block) {
-    int ret;
-    kmem_sync_t ks;
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
-
-    ks.dir = dir;
-    ks.handle.handle_id = kbuf->buf.blocks[block].handle_id;
-    ks.handle.pa = kbuf->buf.blocks[block].pa;
-    ret = ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_SYNC, &ks);
-    if (ret) {
-	pcilib_error("PCIDRIVER_IOC_KMEM_SYNC ioctl have failed");
-	return PCILIB_ERROR_FAILED;
-    }
-    
-    return 0;
-}
-
-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;
-}
-
-uintptr_t pcilib_kmem_get_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k) {
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
-    return kbuf->buf.addr.pa + kbuf->buf.addr.alignment_offset;
-}
-
-uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k) {
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
-    return kbuf->buf.addr.pa + kbuf->buf.addr.alignment_offset;
-}
-
-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;
-}
-
-uintptr_t pcilib_kmem_get_block_pa(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].pa + kbuf->buf.blocks[block].alignment_offset;
-}
-
-uintptr_t pcilib_kmem_get_block_ba(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].pa + kbuf->buf.blocks[block].alignment_offset;
-}
-
-size_t pcilib_kmem_get_block_size(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].size;
-}
-
-pcilib_kmem_reuse_state_t  pcilib_kmem_is_reused(pcilib_t *ctx, pcilib_kmem_handle_t *k) {
-    pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k;
-    return kbuf->buf.reused;
-}

+ 0 - 80
kmem.h

@@ -1,80 +0,0 @@
-#ifndef _PCILIB_KMEM_H
-#define _PCILIB_KMEM_H
-
-#include "pcilib.h"
-
-typedef struct pcilib_kmem_list_s pcilib_kmem_list_t;
-
-#include "tools.h"
-
-typedef enum {
-    PCILIB_KMEM_FLAG_REUSE = KMEM_FLAG_REUSE,
-    PCILIB_KMEM_FLAG_EXCLUSIVE = KMEM_FLAG_EXCLUSIVE,
-    PCILIB_KMEM_FLAG_PERSISTENT = KMEM_FLAG_PERSISTENT,
-    PCILIB_KMEM_FLAG_HARDWARE = KMEM_FLAG_HW,
-    PCILIB_KMEM_FLAG_FORCE = KMEM_FLAG_FORCE,
-    PCILIB_KMEM_FLAG_TRY =  KMEM_FLAG_TRY
-} pcilib_kmem_flags_t;
-
-
-typedef enum {
-    PCILIB_KMEM_REUSE_ALLOCATED = PCILIB_TRISTATE_NO,
-    PCILIB_KMEM_REUSE_REUSED = PCILIB_TRISTATE_YES,
-    PCILIB_KMEM_REUSE_PARTIAL = PCILIB_TRISTATE_PARTIAL,
-    PCILIB_KMEM_REUSE_PERSISTENT = 0x100,
-    PCILIB_KMEM_REUSE_HARDWARE = 0x200
-} pcilib_kmem_reuse_state_t;
-
-
-typedef struct {
-    int handle_id;
-    pcilib_kmem_reuse_state_t reused;
-    
-    uintptr_t pa;
-//    uintptr_t va;
-    void *ua;
-    size_t size;
-    
-    size_t alignment_offset;
-    size_t mmap_offset;
-} pcilib_kmem_addr_t;
-
-/**
- * single allocation - we set only addr, n_blocks = 0
- * multiple allocation - addr is not set, blocks are set, n_blocks > 0
- * sgmap allocation - addr contains ua, but pa's are set in blocks, n_blocks > 0
- */
-typedef struct {
-    pcilib_kmem_addr_t addr;
-    
-    pcilib_kmem_reuse_state_t reused;
-
-    size_t n_blocks;
-    pcilib_kmem_addr_t blocks[];
-} pcilib_kmem_buffer_t;
-
-typedef void pcilib_kmem_handle_t;
-
-
-struct pcilib_kmem_list_s {
-    pcilib_kmem_list_t *next, *prev;
-
-    pcilib_kmem_buffer_t buf;	// variable size, should be last item in struct
-};
-
-pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type_t type, size_t nmemb, size_t size, size_t alignment, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags);
-void pcilib_free_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_flags_t flags);
-//int pcilib_kmem_sync(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir);
-int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir, size_t block);
-void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k);
-uintptr_t pcilib_kmem_get_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k);
-uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k);
-void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
-uintptr_t pcilib_kmem_get_block_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
-uintptr_t pcilib_kmem_get_block_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
-size_t pcilib_kmem_get_block_size(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
-pcilib_kmem_reuse_state_t pcilib_kmem_is_reused(pcilib_t *ctx, pcilib_kmem_handle_t *k);
-
-int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags);
-
-#endif /* _PCILIB_KMEM_H */

+ 0 - 1
misc/50-pcidriver.rules

@@ -1 +0,0 @@
-KERNEL=="fpga*", NAME="%k", GROUP="users", MODE="0660"

+ 60 - 45
ipecamera/model.h → model.c

@@ -1,32 +1,39 @@
-#ifndef _IPECAMERA_MODEL_H
-#define _IPECAMERA_MODEL_H
-
 #include <stdio.h>
 
-#include "../pcilib.h"
-#include "public.h"
+#include <pcilib.h>
+#include <pcilib/model.h>
+
+#include "base.h"
+#include "cmosis.h"
+#include "model.h"
+
+enum ipecamera_protocol_s {
+    IPECAMERA_PROTOCOL_CMOSIS = PCILIB_REGISTER_PROTOCOL0,
+};
 
-//#define IPECAMERA_DEBUG
 
-#define IPECAMERA_DMA_R3
-#define IPECAMERA_DMA_ADDRESS 0
-#define IPECAMERA_DMA_PACKET_LENGTH 4096
+static const pcilib_register_protocol_api_description_t ipecamera_cmosis_protocol_api =
+    { NULL, NULL, ipecamera_cmosis_read, ipecamera_cmosis_write };
 
-//#define IPECAMERA_REGISTER_SPACE 0xfeaffc00
-#define IPECAMERA_REGISTER_SPACE 0x9000
-#define IPECAMERA_REGISTER_WRITE (IPECAMERA_REGISTER_SPACE + 0)
-#define IPECAMERA_REGISTER_READ (IPECAMERA_REGISTER_WRITE + 16)
+/*
+static const pcilib_dma_description_t ipecamera_dma =
+    { &ipe_dma_api, ipe_dma_banks, ipe_dma_registers, ipe_dma_engines, NULL, NULL, "ipedma", "DMA engine developed by M. Caselle" };
+*/
 
-#ifdef _IPECAMERA_MODEL_C
-pcilib_register_bank_description_t ipecamera_register_banks[] = {
-    { PCILIB_REGISTER_BANK0,    PCILIB_BAR0,    128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ , IPECAMERA_REGISTER_WRITE, PCILIB_LITTLE_ENDIAN, 8 , PCILIB_LITTLE_ENDIAN, "%lu"  , "cmosis", "CMOSIS CMV2000 Registers" },
-    { PCILIB_REGISTER_BANK1,    PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL    , IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" },
-//    { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0xA000, PCILIB_DEFAULT_PROTOCOL    , 0,                        0,                        PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
-    { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL    , 0,                        0,                    PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
+static const pcilib_register_protocol_description_t ipecamera_protocols[] = {
+//    {IPECAMERA_PROTOCOL_FPGA,	&pcilib_default_protocol_api, "ipecamera", NULL, "cmosis", "Protocol to access FPGA registers"},
+    {IPECAMERA_PROTOCOL_CMOSIS,	&ipecamera_cmosis_protocol_api, NULL, NULL, "cmosis", "Protocol to access CMOSIS registers"},
+    { 0 }
+};
+
+static const pcilib_register_bank_description_t ipecamera_banks[] = {
+    { PCILIB_REGISTER_BANK0, 	IPECAMERA_PROTOCOL_CMOSIS,		PCILIB_BAR0, IPECAMERA_CMOSIS_REGISTER_READ , 	IPECAMERA_CMOSIS_REGISTER_WRITE, 	 8,    128, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "%lu"  , "cmosis", "CMOSIS CMV2000 Registers" },
+    { PCILIB_REGISTER_BANK1, 	PCILIB_REGISTER_PROTOCOL_DEFAULT,	PCILIB_BAR0, IPECAMERA_REGISTER_SPACE, 		IPECAMERA_REGISTER_SPACE,		32, 0x0200, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" },
+//    { PCILIB_REGISTER_BANK_DMA, PCILIB_REGISTER_PROTOCOL_DEFAULT, 	PCILIB_BAR0, 0,					0, 					32, 0x0200, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
     { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
 };
 
-pcilib_register_description_t ipecamera_registers[] = {
+static const pcilib_register_description_t ipecamera_registers[] = {
 {1, 	0, 	16, 	1088, 	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_number_lines",  ""},
 {3, 	0, 	16, 	0, 	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_start1", ""},
 {5, 	0, 	16, 	0, 	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_start2", ""},
@@ -72,7 +79,6 @@ pcilib_register_description_t ipecamera_registers[] = {
 {111, 	0, 	1, 	1, 	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_bit_mode", ""},
 {112, 	0, 	2, 	0, 	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_adc_resolution", ""},
 {115, 	0, 	1, 	1, 	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_special_115", ""},
-/*{126, 	0, 	16, 	0,                        	PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "temp", ""},*/
 {0x00,	0, 	32,	0,	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_input", ""},
 {0x10,	0, 	32,	0,	0,                        PCILIB_REGISTER_R,  PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_output", ""},
 {0x20,	0, 	32,	0,	0,                        PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""},
@@ -125,36 +131,25 @@ pcilib_register_description_t ipecamera_registers[] = {
 {0,	0,	0,	0,	0,                        0,                  0,                        0,                     NULL, NULL}
 };
 
-pcilib_register_range_t ipecamera_register_ranges[] = {
+static const pcilib_register_range_t ipecamera_ranges[] = {
 //    {0xF000, 	0xF000 + 128, 	PCILIB_REGISTER_BANK0, 0},
 //    {0x9000,	0x9FFF,	PCILIB_REGISTER_BANK1, -0x9000},
     {0, 0, 0, 0}
 };
 
-pcilib_event_description_t ipecamera_events[] = {
+static const pcilib_event_description_t ipecamera_events[] = {
     {PCILIB_EVENT0, "new_frame", ""},
     {0, NULL, NULL}
 };
 
-pcilib_event_data_type_description_t ipecamera_data_types[] = {
-    {IPECAMERA_IMAGE_DATA, PCILIB_EVENT0, "image", "16 bit pixel data" },
-    {IPECAMERA_RAW_DATA, PCILIB_EVENT0, "raw", "raw data from camera" },
-    {IPECAMERA_CHANGE_MASK, PCILIB_EVENT0, "cmask", "change mask" },
+static const pcilib_event_data_type_description_t ipecamera_data_types[] = {
+    {IPECAMERA_IMAGE_DATA,	PCILIB_EVENT0, "image",	"16 bit pixel data" },
+    {IPECAMERA_RAW_DATA,	PCILIB_EVENT0, "raw", 	"raw data from camera" },
+    {IPECAMERA_CHANGE_MASK,	PCILIB_EVENT0, "cmask",	"change mask" },
     {0, 0, NULL, NULL}
 };
 
-#else
-extern pcilib_register_description_t ipecamera_registers[];
-extern pcilib_register_bank_description_t ipecamera_register_banks[];
-extern pcilib_register_range_t ipecamera_register_ranges[];
-extern pcilib_event_description_t ipecamera_events[];
-extern pcilib_event_data_type_description_t ipecamera_data_types[];
-#endif 
-
-#ifdef _IPECAMERA_IMAGE_C
 pcilib_event_api_description_t ipecamera_image_api = {
-    "ipecamera",
-    
     ipecamera_init,
     ipecamera_free,
 
@@ -164,17 +159,37 @@ pcilib_event_api_description_t ipecamera_image_api = {
     ipecamera_start,
     ipecamera_stop,
     ipecamera_trigger,
-    
+
     ipecamera_stream,
     ipecamera_next_event,
     ipecamera_get,
     ipecamera_return
 };
-#else
-extern pcilib_event_api_description_t ipecamera_image_api;
-#endif
 
-int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
-int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
 
-#endif /* _IPECAMERA_MODEL_H */
+static const pcilib_model_description_t ipecamera_models[] = {{
+    PCILIB_EVENT_INTERFACE_VERSION,
+    &ipecamera_image_api,
+    &pcilib_ipedma,
+    ipecamera_registers,
+    ipecamera_banks,
+    ipecamera_protocols,
+    ipecamera_ranges,
+    ipecamera_events,
+    ipecamera_data_types,
+    "ipecamera",
+    "IPE Camera"
+}, { 0 }};
+
+
+const pcilib_model_description_t *pcilib_get_event_model(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model) {
+	// Enumeration call
+    if ((!vendor_id)&&(!device_id)&&(!model)) {
+	return ipecamera_models;
+    }
+
+    if ((vendor_id != 0x10ee)&&((!model)||(strcasecmp(model, "ipecamera"))))
+	return NULL;
+
+    return &ipecamera_models[0];
+}

+ 18 - 0
model.h

@@ -0,0 +1,18 @@
+#ifndef _IPECAMERA_MODEL_H
+#define _IPECAMERA_MODEL_H
+
+#include <stdio.h>
+#include <pcilib/model.h>
+
+//#define IPECAMERA_DEBUG
+
+#define IPECAMERA_DMA_ADDRESS 			0					/**< Address of DMA engine to use for communication */
+#define IPECAMERA_DMA_PACKET_LENGTH 		4096					/**< IPECamera always use buffers of fixed size adding padding in the end. 
+											This is used to compute expected amount of data for each frame */
+#define IPECAMERA_REGISTER_SPACE 0x9000
+#define IPECAMERA_CMOSIS_REGISTER_WRITE 	(IPECAMERA_REGISTER_SPACE + 0)
+#define IPECAMERA_CMOSIS_REGISTER_READ 		(IPECAMERA_REGISTER_SPACE + 16)
+
+const pcilib_model_description_t *pcilib_get_event_model(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model);
+
+#endif /* _IPECAMERA_MODEL_H */

+ 0 - 473
pci.c

@@ -1,473 +0,0 @@
-#define _PCILIB_PCI_C
-//#define PCILIB_FILE_IO
-#define _POSIX_C_SOURCE 199309L
-
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "pcilib.h"
-#include "pci.h"
-#include "kernel.h"
-#include "tools.h"
-#include "error.h"
-
-#include "ipecamera/model.h"
-#include "kapture/model.h"
-
-
-pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
-    pcilib_t *ctx = malloc(sizeof(pcilib_t));
-
-    if (ctx) {
-	memset(ctx, 0, sizeof(pcilib_t));	
-    
-	ctx->handle = open(device, O_RDWR);
-	if (ctx->handle < 0) {
-	    pcilib_error("Error opening device (%s)", device);
-	    free(ctx);
-	    return NULL;
-	}
-	
-	ctx->page_mask = (uintptr_t)-1;
-	ctx->model = model;
-
-	if (!model) model = pcilib_get_model(ctx);
-	
-	memcpy(&ctx->model_info, pcilib_model + model, sizeof(pcilib_model_description_t));
-
-	pcilib_init_event_engine(ctx);
-    }
-
-    return ctx;
-}
-
-pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx) {
-    return &ctx->model_info;
-}
-
-const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) {
-    int ret;
-    
-    if (ctx->page_mask ==  (uintptr_t)-1) {
-	ret = ioctl( ctx->handle, PCIDRIVER_IOC_PCI_INFO, &ctx->board_info );
-	if (ret) {
-	    pcilib_error("PCIDRIVER_IOC_PCI_INFO ioctl have failed");
-	    return NULL;
-	}
-	
-	ctx->page_mask = pcilib_get_page_mask();
-    }
-    
-    return &ctx->board_info;
-}
-
-
-
-pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx) {
-    return ctx->event_ctx;
-}
-
-pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
-    if (ctx->model == PCILIB_MODEL_DETECT) {
-//	unsigned short vendor_id;
-//	unsigned short device_id;
-
-	//return PCILIB_MODEL_PCI;
-	
-	const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-	if (!board_info) return PCILIB_MODEL_PCI;
-
-	if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_IPECAMERA_DEVICE_ID))
-	    ctx->model = PCILIB_MODEL_IPECAMERA;
-	else if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_KAPTURE_DEVICE_ID))
-	    ctx->model = PCILIB_MODEL_IPECAMERA;
-	else
-	    ctx->model = PCILIB_MODEL_PCI;
-    }
-    
-    return ctx->model;
-}
-
-static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
-    int n = 0;
-    pcilib_bar_t i;
-	
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-    if (!board_info) return PCILIB_BAR_INVALID;
-		
-    for (i = 0; i < PCILIB_MAX_BANKS; i++) {
-	if (board_info->bar_length[i] > 0) {
-	    if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i;
-
-	    if (n) n = -1;
-	    else n = i + 1;
-	}
-    }
-
-    if (n > 0) return n - 1;
-
-    return PCILIB_BAR_INVALID;
-}
-
-int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) {
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-    if (!board_info) return PCILIB_ERROR_NOTFOUND;
-    
-    if (*bar == PCILIB_BAR_DETECT) {
-	*bar = pcilib_detect_bar(ctx, *addr, size);
-	if (*bar == PCILIB_BAR_INVALID) {
-	    pcilib_error("The requested data block at address 0x%x with size %zu does not belongs to any available memory bank", *addr, size);
-	    return PCILIB_ERROR_NOTFOUND;
-	}
-	if (*addr < board_info->bar_start[*bar]) 
-	    *addr += board_info->bar_start[*bar];
-    } else {
-	if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) {
-	    if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) {
-		*addr += board_info->bar_start[*bar];
-	    } else {
-		pcilib_error("The requested data block at address 0x%x with size %zu does not belong the specified memory bank (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]);
-		return PCILIB_ERROR_NOTFOUND;
-	    }
-	}
-    }
-
-    *addr -= board_info->bar_start[*bar];
-    *addr += board_info->bar_start[*bar] & ctx->page_mask;
-
-    return 0;
-}
-
-void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
-    void *res;
-    int ret; 
-
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-    if (!board_info) return NULL;
-    
-    if (ctx->bar_space[bar]) return ctx->bar_space[bar];
-    
-    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI );
-    if (ret) {
-	pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar);
-	return NULL;
-    }
-
-    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar );
-    if (ret) {
-	pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar);
-	return NULL;
-    }
-
-#ifdef PCILIB_FILE_IO
-    file_io_handle = open("/root/data", O_RDWR);
-    res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 );
-#else
-    res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 );
-#endif
-    if ((!res)||(res == MAP_FAILED)) {
-	pcilib_error("Failed to mmap data bank %i", bar);
-	return NULL;
-    }
-
-    
-    return res;
-}
-
-void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) {
-    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-    if (!board_info) return;
-
-    if (ctx->bar_space[bar]) return;
-    
-    munmap(data, board_info->bar_length[bar]);
-#ifdef PCILIB_FILE_IO
-    close(ctx->file_io_handle);
-#endif
-}
-
-int pcilib_map_register_space(pcilib_t *ctx) {
-    int err;
-    pcilib_register_bank_t i;
-    
-    if (!ctx->reg_bar_mapped)  {
-	pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-	pcilib_register_bank_description_t *banks = model_info->banks;
-    
-	for (i = 0; ((banks)&&(banks[i].access)); i++) {
-//	    uint32_t buf[2];
-	    void *reg_space;
-            pcilib_bar_t bar = banks[i].bar;
-
-	    if (bar == PCILIB_BAR_DETECT) {
-		uintptr_t addr = banks[0].read_addr;
-	    
-		err = pcilib_detect_address(ctx, &bar, &addr, 1);
-		if (err) return err;
-		
-		if (!ctx->bar_space[bar]) {
-		    reg_space = pcilib_map_bar(ctx, bar);
-//		    pcilib_memcpy(&buf, reg_space, 8);
-	    
-		    if (reg_space) {
-			ctx->bar_space[bar] = reg_space;
-		    } else {
-			return PCILIB_ERROR_FAILED;
-		    }
-		}
-	    } else if (!ctx->bar_space[bar]) {
-		reg_space = pcilib_map_bar(ctx, bar);
-		if (reg_space) {
-		    ctx->bar_space[bar] = reg_space;
-		} else {
-		    return PCILIB_ERROR_FAILED;
-		}
-//		pcilib_memcpy(&buf, reg_space, 8);
-		
-	    }
-	    if (!i) ctx->reg_bar = bar;
-	}
-	
-	ctx->reg_bar_mapped = 1;
-    }
-    
-    return 0;
-}
-
-int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
-    int err;
-    pcilib_bar_t i;
-    
-    if (!ctx->data_bar_mapped) {
-        const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-	if (!board_info) return PCILIB_ERROR_FAILED;
-
-	err = pcilib_map_register_space(ctx);
-	if (err) {
-	    pcilib_error("Error mapping register space");
-	    return err;
-	}
-	
-	int data_bar = -1;	
-	
-	for (i = 0; i < PCILIB_MAX_BANKS; i++) {
-	    if ((ctx->bar_space[i])||(!board_info->bar_length[i])) continue;
-	    
-	    if (addr) {
-	        if (board_info->bar_start[i] == addr) {
-		    data_bar = i;
-		    break;
-		}
-	    } else {
-		if (data_bar >= 0) {
-		    data_bar = -1;
-		    break;
-		}
-		
-		data_bar = i;
-	    }
-	}
-	    
-
-	if (data_bar < 0) {
-	    if (addr) pcilib_error("Unable to find the specified data space (%lx)", addr);
-	    else pcilib_error("Unable to find the data space");
-	    return PCILIB_ERROR_NOTFOUND;
-	}
-	
-	ctx->data_bar = data_bar;
-	
-	if (!ctx->bar_space[data_bar]) {
-	    char *data_space = pcilib_map_bar(ctx, data_bar);
-	    if (data_space) ctx->bar_space[data_bar] = data_space;
-	    else {
-	        pcilib_error("Unable to map the data space");
-		return PCILIB_ERROR_FAILED;
-	    }
-	}
-	
-	ctx->data_bar_mapped = 0;
-    }
-    
-    return 0;
-}
-	
-/*
-static void pcilib_unmap_register_space(pcilib_t *ctx) {
-    if (ctx->reg_space) {
-	pcilib_unmap_bar(ctx, ctx->reg_bar, ctx->reg_space);
-	ctx->reg_space = NULL;
-    }
-}
-
-static void pcilib_unmap_data_space(pcilib_t *ctx) {
-    if (ctx->data_space) {
-	pcilib_unmap_bar(ctx, ctx->data_bar, ctx->data_space);
-	ctx->data_space = NULL;
-    }
-}
-*/
-
-char  *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) {
-    if (bar == PCILIB_BAR_DETECT) {
-	    // First checking the default register bar
-	size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar];
-	if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) {
-	    if (!ctx->bar_space[ctx->reg_bar]) {
-		pcilib_error("The register bar is not mapped");
-		return NULL;
-	    }
-
-	    return ctx->bar_space[ctx->reg_bar] + offset + (ctx->board_info.bar_start[ctx->reg_bar] & ctx->page_mask);
-	}
-	    
-	    // Otherwise trying to detect
-	bar = pcilib_detect_bar(ctx, addr, 1);
-	if (bar != PCILIB_BAR_INVALID) {
-	    size_t offset = addr - ctx->board_info.bar_start[bar];
-	    if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) {
-		if (!ctx->bar_space[bar]) {
-		    pcilib_error("The requested bar (%i) is not mapped", bar);
-		    return NULL;
-		}
-		return ctx->bar_space[bar] + offset + (ctx->board_info.bar_start[bar] & ctx->page_mask);
-	    }
-	}
-    } else {
-	if (!ctx->bar_space[bar]) {
-	    pcilib_error("The requested bar (%i) is not mapped", bar);
-	    return NULL;
-	}
-	
-	if (addr < ctx->board_info.bar_length[bar]) {
-	    return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask);
-	}
-	
-	if ((addr >= ctx->board_info.bar_start[bar])&&(addr < (ctx->board_info.bar_start[bar] + ctx->board_info.bar_length[ctx->reg_bar]))) {
-	    return ctx->bar_space[bar] + (addr - ctx->board_info.bar_start[bar]) + (ctx->board_info.bar_start[bar] & ctx->page_mask);
-	}
-    }
-
-    return NULL;
-}
-
-char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size) {
-    int err;
-    
-    err = pcilib_map_data_space(ctx, addr);
-    if (err) {
-	pcilib_error("Failed to map the specified address space (%lx)", addr);
-	return NULL;
-    }
-    
-    if (size) *size = ctx->board_info.bar_length[ctx->data_bar];
-    
-    return ctx->bar_space[ctx->data_bar] + (ctx->board_info.bar_start[ctx->data_bar] & ctx->page_mask);
-}
-
-
-void pcilib_close(pcilib_t *ctx) {
-    pcilib_bar_t i;
-    
-    if (ctx) {
-	pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-	pcilib_event_api_description_t *eapi = model_info->event_api;
-	pcilib_dma_api_description_t *dapi = model_info->dma_api;
-    
-        if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx);
-        if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx);
-	
-	if (ctx->model_info.registers != model_info->registers) {
-	    free(ctx->model_info.registers);
-	    ctx->model_info.registers = pcilib_model[ctx->model].registers;
-	}
-	
-	if (ctx->kmem_list) {
-	    pcilib_warning("Not all kernel buffers are properly cleaned");
-	
-	    while (ctx->kmem_list) {
-		pcilib_free_kernel_memory(ctx, ctx->kmem_list, 0);
-	    }
-	}
-
-	for (i = 0; i < PCILIB_MAX_BANKS; i++) {
-	    if (ctx->bar_space[i]) {
-		char *ptr = ctx->bar_space[i];
-		ctx->bar_space[i] = NULL;
-		pcilib_unmap_bar(ctx, i, ptr);
-	    }
-	}
-	close(ctx->handle);
-	
-	free(ctx);
-    }
-}
-
-int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
-    void *data;
-
-    pcilib_detect_address(ctx, &bar, &addr, size);
-    data = pcilib_map_bar(ctx, bar);
-
-    pcilib_memcpy(buf, data + addr, size);
-
-    pcilib_unmap_bar(ctx, bar, data);
-
-    return 0;
-}
-
-int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
-    void *data;
-
-    pcilib_detect_address(ctx, &bar, &addr, size);
-    data = pcilib_map_bar(ctx, bar);
-
-    pcilib_memcpy(data + addr, buf, size);
-
-    pcilib_unmap_bar(ctx, bar, data);
-
-    return 0;
-}
-
-
-int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) {
-    int i;
-    void *data;
-
-    pcilib_detect_address(ctx, &bar, &addr, fifo_size);
-    data = pcilib_map_bar(ctx, bar);
-
-    for (i = 0; i < n; i++) {
-	pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size);
-    }
-
-    pcilib_unmap_bar(ctx, bar, data);
-
-    return 0;
-}
-
-int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) {
-    int i;
-    void *data;
-
-    pcilib_detect_address(ctx, &bar, &addr, fifo_size);
-    data = pcilib_map_bar(ctx, bar);
-
-    for (i = 0; i < n; i++) {
-	pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size);
-    }
-
-    pcilib_unmap_bar(ctx, bar, data);
-
-    return 0;
-}

+ 0 - 85
pci.h

@@ -1,85 +0,0 @@
-#ifndef _PCITOOL_PCI_H
-#define _PCITOOL_PCI_H
-
-#define PCILIB_DEFAULT_CPU_COUNT 2
-#define PCILIB_EVENT_TIMEOUT 1000000		/**< us */
-#define PCILIB_TRIGGER_TIMEOUT 100000		/**< us */
-#define PCILIB_DMA_TIMEOUT 10000		/**< us */
-#define PCILIB_DMA_SKIP_TIMEOUT 1000000		/**< us */
-#define PCILIB_REGISTER_TIMEOUT 10000		/**< us */
-
-#include "driver/pciDriver.h"
-#include "pcilib_types.h"
-
-#include "pcilib.h"
-#include "register.h"
-#include "kmem.h"
-#include "irq.h"
-#include "dma.h"
-#include "event.h"
-
-struct pcilib_s {
-    int handle;
-    
-    uintptr_t page_mask;
-    pcilib_board_info_t board_info;
-    pcilib_dma_info_t dma_info;
-    pcilib_model_t model;
-    
-    char *bar_space[PCILIB_MAX_BANKS];
-
-    int reg_bar_mapped;
-    pcilib_bar_t reg_bar;
-//    char *reg_space;
-
-    int data_bar_mapped;
-    pcilib_bar_t data_bar;
-//    char *data_space;
-//    size_t data_size;
-    
-    pcilib_kmem_list_t *kmem_list;
-
-    size_t num_reg, alloc_reg;
-    pcilib_model_description_t model_info;
-    
-    pcilib_dma_context_t *dma_ctx;
-    pcilib_context_t *event_ctx;
-    
-#ifdef PCILIB_FILE_IO
-    int file_io_handle;
-#endif /* PCILIB_FILE_IO */
-};
-
-#ifdef _PCILIB_PCI_C
-# include "ipecamera/model.h"
-# include "kapture/model.h"
-# include "dma/nwl.h"
-# include "dma/ipe.h"
-# include "default.h"
-
-pcilib_model_description_t pcilib_model[4] = {
-    { 4, PCILIB_HOST_ENDIAN, 	NULL, NULL, NULL, NULL, NULL, NULL },
-    { 4, PCILIB_HOST_ENDIAN, 	NULL, NULL, NULL, NULL, NULL, NULL },
-    { 4, PCILIB_LITTLE_ENDIAN,	ipecamera_registers, ipecamera_register_banks, ipecamera_register_ranges, ipecamera_events, ipecamera_data_types, &ipe_dma_api, &ipecamera_image_api },
-    { 4, PCILIB_LITTLE_ENDIAN,	kapture_registers, kapture_register_banks, kapture_register_ranges, kapture_events, kapture_data_types, &ipe_dma_api, &kapture_api },
-};
-
-pcilib_protocol_description_t pcilib_protocol[3] = {
-    { pcilib_default_read, pcilib_default_write },
-    { ipecamera_read, ipecamera_write },
-    { NULL, NULL }
-};
-#else
-extern pcilib_model_description_t pcilib_model[];
-extern pcilib_protocol_description_t pcilib_protocol[];
-#endif /* _PCILIB_PCI_C */
-
-const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx);
-const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx);
-
-int pcilib_map_register_space(pcilib_t *ctx);
-int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr);
-int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size);
-
-
-#endif /* _PCITOOL_PCI_H */

+ 0 - 380
pcilib.h

@@ -1,380 +0,0 @@
-#ifndef _PCITOOL_PCILIB_H
-#define _PCITOOL_PCILIB_H
-
-#define PCILIB_MAX_BANKS 6
-#define PCILIB_MAX_DMA_ENGINES 32
-
-#include <sys/time.h>
-#include <stdint.h>
-
-#define pcilib_memcpy pcilib_memcpy32
-#define pcilib_datacpy pcilib_datacpy32
-
-typedef struct pcilib_s pcilib_t;
-typedef struct pcilib_event_context_s pcilib_context_t;
-typedef struct pcilib_dma_context_s pcilib_dma_context_t;
-
-
-typedef struct pcilib_dma_api_description_s pcilib_dma_api_description_t;
-typedef struct pcilib_event_api_description_s pcilib_event_api_description_t;
-typedef struct  pcilib_protocol_description_s pcilib_protocol_description_t;
-typedef unsigned int pcilib_irq_hw_source_t;
-typedef uint32_t pcilib_irq_source_t;
-
-typedef uint8_t pcilib_bar_t;			/**< Type holding the PCI Bar number */
-typedef uint8_t pcilib_register_t;		/**< Type holding the register ID within the Bank */
-typedef uint32_t pcilib_register_addr_t;	/**< Type holding the register ID within the Bank */
-typedef uint8_t pcilib_register_bank_t;		/**< Type holding the register bank number */
-typedef uint8_t pcilib_register_bank_addr_t;	/**< Type holding the register bank number */
-typedef uint8_t pcilib_register_size_t;		/**< Type holding the size in bits of the register */
-typedef uint32_t pcilib_register_value_t;	/**< Type holding the register value */
-typedef uint8_t pcilib_dma_engine_addr_t;
-typedef uint8_t pcilib_dma_engine_t;
-typedef uint64_t pcilib_event_id_t;
-typedef uint32_t pcilib_event_t;
-typedef uint64_t pcilib_timeout_t;		/**< In microseconds */
-
-typedef enum {
-    PCILIB_HOST_ENDIAN = 0,
-    PCILIB_LITTLE_ENDIAN,
-    PCILIB_BIG_ENDIAN
-} pcilib_endianess_t;
-
-typedef enum {
-    PCILIB_MODEL_DETECT,
-    PCILIB_MODEL_PCI,
-    PCILIB_MODEL_IPECAMERA,
-    PCILIB_MODEL_KAPTURE
-} pcilib_model_t;
-
-typedef enum {
-    PCILIB_REGISTER_R = 1,
-    PCILIB_REGISTER_W = 2,
-    PCILIB_REGISTER_RW = 3,
-    PCILIB_REGISTER_W1C = 4,		/**< writting 1 resets the flag */
-    PCILIB_REGISTER_RW1C = 5
-} pcilib_register_mode_t;
-
-typedef enum {
-    PCILIB_DEFAULT_PROTOCOL,
-    IPECAMERA_REGISTER_PROTOCOL
-} pcilib_register_protocol_t;
-
-typedef enum {
-    PCILIB_EVENT_DATA = 0,		/**< default data format */
-    PCILIB_EVENT_RAW_DATA = 1		/**< raw data */
-} pcilib_event_data_type_t;
-
-typedef enum {
-    PCILIB_DMA_FLAGS_DEFAULT = 0,
-    PCILIB_DMA_FLAG_EOP = 1,		/**< last buffer of the packet */
-    PCILIB_DMA_FLAG_WAIT = 2,		/**< wait completion of write operation / wait for data during read operation */
-    PCILIB_DMA_FLAG_MULTIPACKET = 4,	/**< read multiple packets */
-    PCILIB_DMA_FLAG_PERSISTENT = 8,	/**< do not stop DMA engine on application termination / permanently close DMA engine on dma_stop */
-    PCILIB_DMA_FLAG_IGNORE_ERRORS = 16	/**< do not crash on errors, but return appropriate error codes */
-} pcilib_dma_flags_t;
-
-typedef enum {
-    PCILIB_STREAMING_STOP = 0, 		/**< stop streaming */
-    PCILIB_STREAMING_CONTINUE = 1, 	/**< wait the default DMA timeout for a new data */
-    PCILIB_STREAMING_WAIT = 2,		/**< wait the specified timeout for a new data */
-    PCILIB_STREAMING_CHECK = 3,		/**< do not wait for the data, bail out imideatly if no data ready */
-    PCILIB_STREAMING_FAIL = 4,		/**< fail if data is not available on timeout */
-    PCILIB_STREAMING_REQ_FRAGMENT = 5,	/**< only fragment of a packet is read, wait for next fragment and fail if no data during DMA timeout */
-    PCILIB_STREAMING_REQ_PACKET = 6,	/**< wait for next packet and fail if no data during the specified timeout */
-    PCILIB_STREAMING_TIMEOUT_MASK = 3	/**< mask specifying all timeout modes */
-} pcilib_streaming_action_t;
-
-
-typedef enum {
-    PCILIB_EVENT_FLAGS_DEFAULT = 0,
-    PCILIB_EVENT_FLAG_RAW_DATA_ONLY = 1,	/**< Do not parse data, just read raw and pass it to rawdata callback. If passed to rawdata callback, idicates the data is not identified as event (most probably just padding) */
-    PCILIB_EVENT_FLAG_STOP_ONLY = 1,		/**< Do not cleanup, just stop acquiring new frames, the cleanup should be requested afterwards */
-    PCILIB_EVENT_FLAG_EOF = 2,			/**< Indicates that it is the last part of the frame (not required) */
-    PCILIB_EVENT_FLAG_PREPROCESS = 4		/**< Enables preprocessing of the raw data (decoding frames, etc.) */
-} pcilib_event_flags_t;
-
-typedef enum {
-    PCILIB_EVENT_INFO_FLAG_BROKEN = 1		/**< Indicates broken frames (if this flag is fales, the frame still can be broken) */
-} pcilib_event_info_flags_t;
-
-typedef enum {
-    PCILIB_REGISTER_STANDARD = 0,
-    PCILIB_REGISTER_FIFO,
-    PCILIB_REGISTER_BITS
-} pcilib_register_type_t;
-
-#define PCILIB_BAR_DETECT 		((pcilib_bar_t)-1)
-#define PCILIB_BAR_INVALID		((pcilib_bar_t)-1)
-#define PCILIB_BAR0			0
-#define PCILIB_BAR1			1
-#define PCILIB_DMA_ENGINE_INVALID	((pcilib_dma_engine_t)-1)
-#define PCILIB_DMA_ENGINE_ALL		((pcilib_dma_engine_t)-1)
-#define PCILIB_DMA_FLAGS_DEFAULT	((pcilib_dma_flags_t)0)
-#define PCILIB_DMA_ENGINE_ADDR_INVALID	((pcilib_dma_engine_addr_t)-1)
-#define PCILIB_REGISTER_INVALID		((pcilib_register_t)-1)
-#define PCILIB_ADDRESS_INVALID		((uintptr_t)-1)
-#define PCILIB_REGISTER_BANK_INVALID	((pcilib_register_bank_t)-1)
-#define PCILIB_REGISTER_BANK0 		0
-#define PCILIB_REGISTER_BANK1 		1
-#define PCILIB_REGISTER_BANK2 		2
-#define PCILIB_REGISTER_BANK3 		3
-#define PCILIB_REGISTER_BANK_DMA	128
-#define PCILIB_EVENT0			1
-#define PCILIB_EVENT1			2
-#define PCILIB_EVENT2			4
-#define PCILIB_EVENT3			8
-#define PCILIB_EVENTS_ALL		((pcilib_event_t)-1)
-#define PCILIB_EVENT_INVALID		((pcilib_event_t)-1)
-#define PCILIB_EVENT_DATA_TYPE_INVALID	((pcilib_event_data_type_t)-1)
-#define PCILIB_TIMEOUT_INFINITE		((pcilib_timeout_t)-1)
-#define PCILIB_TIMEOUT_IMMEDIATE	0
-#define PCILIB_IRQ_TYPE_ALL 		0
-#define PCILIB_IRQ_SOURCE_DEFAULT	0
-#define PCILIB_REGISTER_NO_BITS		0
-#define PCILIB_REGISTER_ALL_BITS	((pcilib_register_value_t)-1)
-
-typedef struct {
-    pcilib_event_t type;
-    uint64_t seqnum;			/**< we will add seqnum_overflow if required */
-    uint64_t offset;			/**< nanoseconds */
-    struct timeval timestamp;		/**< most accurate timestamp */
-    pcilib_event_info_flags_t flags;	/**< flags */
-} pcilib_event_info_t;
-
-/**<
- * Callback function called when new data is read by DMA streaming function
- * @ctx - DMA Engine context
- * @flags - DMA Flags
- * @bufsize - size of data in bytes
- * @buf - data
- * @returns 
- * <0 - error, stop streaming (the value is negative error code)
- *  0 - stop streaming (PCILIB_STREAMING_STOP)
- *  1 - wait DMA timeout and return gracefuly if no data (PCILIB_STREAMING_CONTINUE)
- *  2 - wait the specified timeout and return gracefuly if no data (PCILIB_STREAMING_WAIT)
- *  3 - check if more data is available without waiting, return gracefuly if not (PCILIB_STREAMING_CHECK)
- *  5 - wait DMA timeout and fail if no data (PCILIB_STREAMING_REQ_FRAGMENT)
- *  6 - wait the specified timeout and fail if no data (PCILIB_STREAMING_REQ_PACKET)
- */
-typedef int (*pcilib_dma_callback_t)(void *ctx, pcilib_dma_flags_t flags, size_t bufsize, void *buf); 
-typedef int (*pcilib_event_callback_t)(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user);
-typedef int (*pcilib_event_rawdata_callback_t)(pcilib_event_id_t event_id, pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user);
-
-typedef struct {
-    pcilib_register_bank_addr_t addr;
-
-    pcilib_bar_t bar;			// optional
-    size_t size;
-    
-    pcilib_register_protocol_t protocol;
-
-    uintptr_t read_addr;		// or offset if bar specified
-    uintptr_t write_addr;		// or offset if bar specified
-    uint8_t raw_endianess;
-
-    uint8_t access;
-    uint8_t endianess;
-    
-    const char *format;
-    const char *name;
-    const char *description;
-} pcilib_register_bank_description_t;
-
-typedef struct {
-    pcilib_register_addr_t addr;
-    pcilib_register_size_t offset;
-    pcilib_register_size_t bits;
-    pcilib_register_value_t defvalue;
-    pcilib_register_value_t rwmask;	/**< 1 - read before write bits, 0 - zero should be written to preserve value 
-					Used to define how external bits of PCILIB_REGISTER_BITS registers are treated.
-					Currently it is a bit confusing, we may find a better way in the next release */
-    pcilib_register_mode_t mode;
-    pcilib_register_type_t type;
-    
-    pcilib_register_bank_t bank;
-    
-    const char *name;
-    const char *description;
-} pcilib_register_description_t;
-
-/**
-  * Default mappings
-  */
-typedef struct {
-    uintptr_t start;
-    uintptr_t end;
-    pcilib_register_bank_addr_t bank;
-    long addr_shift;
-} pcilib_register_range_t;
-
-typedef struct {
-    pcilib_event_t evid;
-    const char *name;
-    const char *description;
-} pcilib_event_description_t;
-
-typedef struct {
-    pcilib_event_data_type_t data_type;
-    pcilib_event_t evid;
-    const char *name;
-    const char *description;
-} pcilib_event_data_type_description_t;
-
-typedef enum {
-    PCILIB_DMA_IRQ = 1,
-    PCILIB_EVENT_IRQ = 2
-} pcilib_irq_type_t;
-
-typedef enum {
-    PCILIB_DMA_TO_DEVICE = 1,
-    PCILIB_DMA_FROM_DEVICE = 2,
-    PCILIB_DMA_BIDIRECTIONAL = 3
-} pcilib_dma_direction_t;
-
-typedef enum {
-    PCILIB_DMA_TYPE_BLOCK,
-    PCILIB_DMA_TYPE_PACKET,
-    PCILIB_DMA_TYPE_UNKNOWN
-} pcilib_dma_engine_type_t;
-
-typedef struct {
-    pcilib_dma_engine_addr_t addr;
-    pcilib_dma_engine_type_t type;
-    pcilib_dma_direction_t direction;
-    size_t addr_bits;
-} pcilib_dma_engine_description_t;
-
-typedef struct {
-    pcilib_dma_engine_description_t *engines[PCILIB_MAX_DMA_ENGINES +  1];
-} pcilib_dma_info_t;
-
-typedef struct {
-    uint8_t access;
-    uint8_t endianess;
-    
-    pcilib_register_description_t *registers;
-    pcilib_register_bank_description_t *banks;
-    pcilib_register_range_t *ranges;
-    pcilib_event_description_t *events;
-    pcilib_event_data_type_description_t *data_types;
-
-    pcilib_dma_api_description_t *dma_api;    
-    pcilib_event_api_description_t *event_api;
-} pcilib_model_description_t;
-
-int pcilib_set_error_handler(void (*err)(const char *msg, ...), void (*warn)(const char *msg, ...));
-
-pcilib_model_t pcilib_get_model(pcilib_t *ctx);
-pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx);
-pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx);
-
-pcilib_t *pcilib_open(const char *device, pcilib_model_t model);
-void pcilib_close(pcilib_t *ctx);
-
-int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags);
-
-    // Interrupt API is preliminary and can be significantly changed in future
-int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags);
-int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source);
-int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags);
-
-int pcilib_wait_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source, pcilib_timeout_t timeout, size_t *count);
-int pcilib_clear_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source);
-
-void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar);
-void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data);
-char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr);	// addr is offset if bar is specified
-char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size);
-
-pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank);
-pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname);
-pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank);
-pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg);
-pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event);
-pcilib_event_data_type_t pcilib_find_event_data_type(pcilib_t *ctx, pcilib_event_t event, const char *data_type);
-pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma);
-
-int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf);
-int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf);
-int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf);
-int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf);
-
-int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma);
-int pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr);
-int pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written_bytes);
-int pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *read_bytes);
-int pcilib_read_dma_custom(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *read_bytes);
-int pcilib_write_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *written_bytes);
-double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction);
-
-int pcilib_read_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf);
-int pcilib_write_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf);
-int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t *value);
-int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t value);
-int pcilib_read_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t *value);
-int pcilib_write_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t value);
-
-int pcilib_reset(pcilib_t *ctx);
-int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data);
-
-/*
- * The recording of new events will be stopped after reaching max_events records
- * or when the specified amount of time is elapsed. However, the @pcilib_stop
- * function should be called still. 
- * NOTE: This options may not be respected if the PCILIB_EVENT_FLAG_RAW_DATA_ONLY
- * is specified.
- */
-int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t duration);
-
-/*
- * Request auto-triggering while grabbing
- */
-int pcilib_configure_autotrigger(pcilib_t *ctx, pcilib_timeout_t interval, pcilib_event_t event, size_t trigger_size, void *trigger_data);
-/*
- * Request streaming the rawdata from the event engine. It is fastest way to acuqire data.
- * No memory copies will be performed and DMA buffers will be directly passed to the user
- * callback. However, to prevent data loss, no processing should be done on the data. The
- * user callback is only expected to copy data into the appropriate place and return control
- * to the event engine.
- * The performance can be boosted further by disabling any data processing within the event
- * engine. Just pass PCILIB_EVENT_FLAG_RAW_DATA_ONLY flag to the @pcilib_start function.
- */
-int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user);
-
-/*
- * Configures maximal number of preprocessing threads. Actual amount of threads 
- * may be bigger. For instance, additionaly a real-time reader thread will be 
- * executed for most of hardware
- */
-int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads);
-
-
-int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags);
-int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags);
-
-int pcilib_stream(pcilib_t *ctx, pcilib_event_callback_t callback, void *user);
-int pcilib_get_next_event(pcilib_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info);
-
-int pcilib_copy_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t size, void *buf, size_t *retsize);
-int pcilib_copy_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t size, void *buf, size_t *retsize);
-void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size_or_err);
-void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size_or_err);
-
-/*
- * This function is provided to find potentially corrupted data. If the data is overwritten by 
- * the time return_data is called it will return error. 
- */
-int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data);
-
-
-
-/*
- * @param data - will be allocated and shuld be freed if NULL, otherwise used and size should contain correct size.
- *   In case of failure the content of data is undefined.
- * @param timeout - will be autotriggered if NULL
- */
-int pcilib_grab(pcilib_t *ctx, pcilib_event_t event_mask, size_t *size, void **data, pcilib_timeout_t timeout);
-
-#endif /* _PCITOOL_PCILIB_H */

+ 0 - 44
pcilib_types.h

@@ -1,44 +0,0 @@
-#ifndef _PCILIB_TYPES_H
-#define _PCILIB_TYPES_H
-
-#define KMEM_REF_HW 		0x80000000	/**< Special reference to indicate hardware access */
-#define KMEM_REF_COUNT		0x0FFFFFFF	/**< Mask of reference counter (mmap/munmap), couting in mmaped memory pages */
-
-#define KMEM_MODE_REUSABLE	0x80000000	/**< Indicates reusable buffer */
-#define KMEM_MODE_EXCLUSIVE	0x40000000	/**< Only a single process is allowed to mmap the buffer */
-#define KMEM_MODE_PERSISTENT	0x20000000	/**< Persistent mode instructs kmem_free to preserve buffer in memory */
-#define KMEM_MODE_COUNT		0x0FFFFFFF	/**< Mask of reuse counter (alloc/free) */
-
-#define PCILIB_KMEM_TYPE_MASK	0xFFFF0000
-
-typedef enum {
-    PCILIB_KMEM_TYPE_CONSISTENT = 0x00000,
-    PCILIB_KMEM_TYPE_PAGE = 0x10000,
-    PCILIB_KMEM_TYPE_DMA_S2C_PAGE = 0x10001,
-    PCILIB_KMEM_TYPE_DMA_C2S_PAGE = 0x10002,
-    PCILIB_KMEM_TYPE_REGION = 0x20000,
-    PCILIB_KMEM_TYPE_REGION_S2C = 0x20001,
-    PCILIB_KMEM_TYPE_REGION_C2S = 0x20002
-} pcilib_kmem_type_t;
-
-typedef enum {
-    PCILIB_KMEM_USE_STANDARD = 0,
-    PCILIB_KMEM_USE_DMA_RING = 1,
-    PCILIB_KMEM_USE_DMA_PAGES = 2,
-    PCILIB_KMEM_USE_USER = 0x10
-} pcilib_kmem_use_t;
-
-typedef enum {
-    PCILIB_KMEM_SYNC_BIDIRECTIONAL = 0,
-    PCILIB_KMEM_SYNC_TODEVICE = 1,
-    PCILIB_KMEM_SYNC_FROMDEVICE = 2
-} pcilib_kmem_sync_direction_t;
-
-
-#define PCILIB_KMEM_USE(type, subtype) (((type) << 16)|(subtype))
-
-
-//pcilib_alloc_kmem_buffer(pcilib_t *ctx, size_t size, size_t alignment)
-
-
-#endif /* _PCILIB_TYPES_H */

+ 0 - 8
pcitool/CMakeLists.txt

@@ -1,8 +0,0 @@
-include_directories(
-    ${CMAKE_SOURCE_DIR}
-)
-
-set(HEADERS ${HEADERS} sysinfo.h formaters.h)
-
-add_library(pcitool STATIC sysinfo.c formaters.c)
-

+ 0 - 47
pcitool/formaters.c

@@ -1,47 +0,0 @@
-#include <stdio.h>
-
-void PrintTime(size_t duration) {
-    if (duration > 999999999999) printf("%4.1lf""d", 1.*duration/86400000000);
-    else if (duration > 99999999999) printf("%4.1lf""h", 1.*duration/3600000000);
-    else if (duration > 9999999999) printf("%4.2lf""h", 1.*duration/3600000000);
-    else if (duration > 999999999) printf("%4.1lf""m", 1.*duration/60000000);
-    else if (duration > 99999999) printf("%4.2lf""m", 1.*duration/60000000);
-    else if (duration > 9999999) printf("%4.1lf""s", 1.*duration/1000000);
-    else if (duration > 999999) printf("%4.2lf""s", 1.*duration/1000000);
-    else if (duration > 999) printf("%3lu""ms", duration/1000);
-    else printf("%3lu""us", duration);
-}
-
-void PrintNumber(size_t num) {
-    if (num > 999999999999999999) printf("%3lue", num/1000000000000000000);
-    else if (num > 999999999999999) printf("%3lup", num/1000000000000000);
-    else if (num > 999999999999) printf("%3lut", num/1000000000000);
-    else if (num > 999999999) printf("%3lug", num/1000000000);
-    else if (num > 999999) printf("%3lum", num/1000000);
-    else if (num > 9999) printf("%3luk", num/1000);
-    else printf("%4lu", num);
-}
-
-void PrintSize(size_t num) {
-    if (num >= 112589990684263) printf("%4.1lf PB", 1.*num/1125899906842624);
-    else if (num >= 109951162778) printf("%4.1lf TB", 1.*num/1099511627776);
-    else if (num >= 107374183) printf("%4.1lf GB", 1.*num/1073741824);
-    else if (num >= 1048576) printf("%4lu MB", num/1048576);
-    else if (num >= 1024) printf("%4lu KB", num/1024);
-    else printf("%5lu B", num);
-}
-
-void PrintPercent(size_t num, size_t total) {
-    if (num >= total) printf(" 100");
-    else printf("%4.1lf", 100.*num/total);
-    
-}
-
-char *GetPrintSize(char *str, size_t size) {
-    if (size >= 1073741824) sprintf(str, "%.1lf GB", 1.*size / 1073741824);
-    else if (size >= 1048576) sprintf(str, "%.1lf MB", 1.*size / 1048576);
-    else if (size >= 1024) sprintf(str, "%lu KB", size / 1024);
-    else sprintf(str, "%lu B ", size);
-    
-    return str;
-}

+ 0 - 12
pcitool/formaters.h

@@ -1,12 +0,0 @@
-#ifndef _PCITOOL_FORMATERS_H
-#define _PCITOOL_FORMATERS_H
-
-void PrintTime(size_t duration);
-void PrintNumber(size_t num);
-void PrintSize(size_t num);
-void PrintPercent(size_t num, size_t total);
-char *GetPrintSize(char *str, size_t size);
-
-
-#endif /* _PCITOOL_FORMATERS_H */
-

+ 0 - 172
pcitool/sysinfo.c

@@ -1,172 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <strings.h>
-
-#define MEMINFO_FILE "/proc/meminfo"
-#define MTAB_FILE "/etc/mtab"
-
-#define BAD_OPEN_MESSAGE					\
-"Error: /proc must be mounted\n"				\
-"  To mount /proc at boot you need an /etc/fstab line like:\n"	\
-"      /proc   /proc   proc    defaults\n"			\
-"  In the meantime, run \"mount /proc /proc -t proc\"\n"
-
-/* This macro opens filename only if necessary and seeks to 0 so
- * that successive calls to the functions are more efficient.
- * It also reads the current contents of the file into the global buf.
- */
-#define FILE_TO_BUF(filename) do{				\
-    static int fd, local_n;					\
-    if ((fd = open(filename, O_RDONLY)) == -1) {		\
-	fputs(BAD_OPEN_MESSAGE, stderr);			\
-	fflush(NULL);						\
-	_exit(102);						\
-    }								\
-    lseek(fd, 0L, SEEK_SET);					\
-    if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) {	\
-	perror(filename);					\
-	fflush(NULL);						\
-	_exit(103);						\
-    }								\
-    buf[local_n] = '\0';					\
-    close(fd);							\
-}while(0)
-
-
-typedef struct mem_table_struct {
-  const char *name;     /* memory type name */
-  unsigned long *slot; /* slot in return struct */
-} mem_table_struct;
-
-static int compare_mem_table_structs(const void *a, const void *b){
-  return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name);
-}
-
-size_t get_free_memory(void){
-  char buf[4096];
-  unsigned long kb_main_buffers, kb_main_cached, kb_main_free;
-  char namebuf[16]; /* big enough to hold any row name */
-  mem_table_struct findme = { namebuf, NULL};
-  mem_table_struct *found;
-  char *head;
-  char *tail;
-
-  const mem_table_struct mem_table[] = {
-    {"Buffers",      &kb_main_buffers}, // important
-    {"Cached",       &kb_main_cached},  // important
-    {"MemFree",      &kb_main_free},    // important
-  };
-  const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct);
-
-  FILE_TO_BUF(MEMINFO_FILE);
-
-  head = buf;
-  for(;;){
-    tail = strchr(head, ':');
-    if(!tail) break;
-    *tail = '\0';
-    if(strlen(head) >= sizeof(namebuf)){
-      head = tail+1;
-      goto nextline;
-    }
-    strcpy(namebuf,head);
-    found = bsearch(&findme, mem_table, mem_table_count,
-        sizeof(mem_table_struct), compare_mem_table_structs
-    );
-    head = tail+1;
-    if(!found) goto nextline;
-    *(found->slot) = strtoul(head,&tail,10);
-nextline:
-    tail = strchr(head, '\n');
-    if(!tail) break;
-    head = tail+1;
-  }
-  
-  return (kb_main_buffers + kb_main_cached + kb_main_free) * 1024;
-}
-
-
-int get_file_fs(const char *fname, size_t size, char *fs) {
-  int err = 0;
-  char buf[4096];
-  char *fn;
-
-  char *head;
-  char *tail;
-
-  size_t len, max = 0;
-  struct stat st;
-  
-  if ((!fname)||(!fs)||(size < 3)) return -1;
-  
-  if (*fname == '/') {
-    fn = (char*)fname;
-  } else {
-    if (!getcwd(buf, 4095)) return -1;
-    fn = malloc(strlen(fname) + strlen(buf) + 2);
-    if (!fn) return -1;
-    sprintf(fn, "%s/%s", buf, fname);
-  }
-  
-  if (!stat(fn, &st)) {
-    if (S_ISBLK(st.st_mode)) {
-	strcpy(fs, "raw");
-	goto clean;
-    }
-  }
-  
-  FILE_TO_BUF(MTAB_FILE);
-
-  head = buf;
-  for(;;){
-    head = strchr(head, ' ');
-    if(!head) break;
-
-    head += 1;
-    tail = strchr(head, ' ');
-    if(!tail) break;
-    
-    *tail = '\0';
-
-    len = strlen(head);
-    if((len <= max)||(strncmp(head, fn, len))) {
-      head = tail+1;
-      goto nextline;
-    }
-    
-    head = tail + 1;
-    tail = strchr(head, ' ');
-    if(!tail) break;
-
-    *tail = '\0';
-
-    if (!strncasecmp(head,"root",4)) {
-	head = tail+1;
-	goto nextline;
-    }
-    
-    max = len;
-
-    if (strlen(head) >= size) err = -1;
-    else {
-	err = 0;
-	strcpy(fs, head);
-    }
-    
-    head = tail+1;
-nextline:
-    tail = strchr(head, '\n');
-    if(!tail) break;
-    head = tail+1;
-  }
-
-clean:  
-  if (fn != fname) free(fn);
-
-  return err;
-}

+ 0 - 7
pcitool/sysinfo.h

@@ -1,7 +0,0 @@
-#ifndef _PCITOOL_SYSINFO_H
-#define _PCITOOL_SYSINFO_H
-
-size_t get_free_memory();
-int get_file_fs(const char *fname, size_t size, char *fs);
-
-#endif /* _PCITOOL_SYSINFO_H */

+ 12 - 8
ipecamera/private.h → private.h

@@ -1,9 +1,11 @@
 #ifndef _IPECAMERA_PRIVATE_H
 #define _IPECAMERA_PRIVATE_H
 
+#include <pthread.h>
+#include <pcilib/model.h>
 #include "ipecamera.h"
 
-#define IPECAMERA_BUG_EXTRA_DATA
+//#define IPECAMERA_BUG_EXTRA_DATA
 #define IPECAMERA_BUG_MULTIFRAME_PACKETS	//**< this is by design, start of packet comes directly after the end of last one in streaming mode */
 //#define IPECAMERA_BUG_INCOMPLETE_PACKETS
 #define IPECAMERA_BUG_POSTPONED_READ
@@ -12,6 +14,9 @@
 
 //#define IPECAMERA_ANNOUNCE_READY		//**< announce new event only after the reconstruction is done */
 
+#define IPECAMERA_REGISTER_TIMEOUT 10000	//**< us */
+#define IPECAMERA_DMA_TIMEOUT 50000		//**< us */
+
 #define IPECAMERA_DEFAULT_BUFFER_SIZE 64  	//**< should be power of 2 */
 #define IPECAMERA_RESERVE_BUFFERS 2		//**< Return Frame is Lost error, if requested frame will be overwritten after specified number of frames
 #define IPECAMERA_SLEEP_TIME 250000 		//**< Michele thinks 250 should be enough, but reset failing in this case */
@@ -114,18 +119,17 @@ struct ipecamera_s {
     size_t buffer_size;		/**< How many images to store */
     size_t buffer_pos;		/**< Current image offset in the buffer, due to synchronization reasons should not be used outside of reader_thread */
     size_t cur_size;		/**< Already written part of data in bytes */
-    size_t raw_size;		/**< Size of raw data in bytes */
-    size_t full_size;		/**< Size of raw data including the padding */
-    size_t padded_size;		/**< Size of buffer for raw data, including the padding for performance */
-    size_t cur_raw_size;	/**< Size of raw data in bytes */
-    size_t cur_full_size;	/**< Size of raw data including the padding */
-    size_t cur_padded_size;	/**< Size of buffer for raw data, including the padding for performance */
+    size_t raw_size;		/**< Expected maximum size of raw data in bytes */
+    size_t full_size;		/**< Expected maximum size of raw data including the padding */
+    size_t padded_size;		/**< Expected maximum size of buffer for raw data, including additional padding due to the ipecamera bugs */
+    size_t cur_raw_size;	/**< Expected size (for currently configured ROI) of raw data in bytes */
+    size_t cur_full_size;	/**< Expected size (for currently configured ROI) of raw data including the padding */
+    size_t cur_padded_size;	/**< Expected size (for currently configured ROI) of buffer for raw data, including additional padding due to the ipecamera bugs */
     
     size_t image_size;		/**< Size of a single image in bytes */
     
     size_t max_frames;		/**< Maximal number of frames what may be buffered in camera DDR memory */
     int firmware;		/**< Firmware version */
-    int fr_mode;		/**< Fast Reject mode */
     int cmosis_outputs;		/**< Number of active cmosis outputs: 4 or 16 */
     int width, height;
 

+ 12 - 16
ipecamera/reader.c → reader.c

@@ -13,10 +13,10 @@
 
 #include <ufodecode.h>
 
-#include "../tools.h"
-#include "../error.h"
+#include <pcilib.h>
+#include <pcilib/tools.h>
+#include <pcilib/error.h>
 
-#include "pcilib.h"
 #include "model.h"
 #include "private.h"
 #include "reader.h"
@@ -75,7 +75,7 @@ static inline int ipecamera_new_frame(ipecamera_t *ctx) {
 	return 1;
     }
 	
-    if (pcilib_check_deadline(&ctx->autostop.timestamp, PCILIB_DMA_TIMEOUT)) {
+    if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) {
 	ctx->run_reader = 0;
 	return 1;
     }
@@ -119,18 +119,18 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t
     if (!ctx->cur_size) {
 #if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS)
 	size_t startpos;
-	for (startpos = 0; (startpos + sizeof(frame_magic)) < bufsize; startpos += sizeof(uint32_t)) {
+	for (startpos = 0; (startpos + sizeof(frame_magic)) <= bufsize; startpos += sizeof(uint32_t)) {
 	    if (!memcmp(buf + startpos, frame_magic, sizeof(frame_magic))) break;
 	}
 	
-	if ((startpos + sizeof(frame_magic)) >= bufsize) {
+	if ((startpos + sizeof(frame_magic)) > bufsize) {
 #ifdef IPECAMERA_DEBUG_RAW_PACKETS
 	    FILE *f = fopen(fname, "w");
 	    if (f) fclose(f);
 #endif /* IPECAMERA_DEBUG_RAW_PACKETS */
 	    
 	    if (invalid_frame_id != ctx->event_id) {
-//		pcilib_warning("No frame magic in DMA packet of %u bytes, current event %lu (got %lu)", bufsize, ctx->event_id, invalid_frame_id);
+//		pcilib_warning("No frame magic in DMA packet of %u bytes, current event %lu", bufsize, ctx->event_id);
 		invalid_frame_id = ctx->event_id;
 	    }
 
@@ -159,9 +159,6 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t
 
 	    ctx->frame[ctx->buffer_pos].event.info.seqnum = ((uint32_t*)buf)[6] & 0x1FFFFFF;
 	    ctx->frame[ctx->buffer_pos].event.info.offset = (((uint32_t*)buf)[7] & 0xFFFFFF) * 80;
-
-//	    ctx->frame[ctx->buffer_pos].event.info.seqnum = ctx->event_id + 1;
-
 	    gettimeofday(&ctx->frame[ctx->buffer_pos].event.info.timestamp, NULL);
 	} else {
 //	    pcilib_warning("Frame magic is not found, ignoring broken data...");
@@ -186,8 +183,6 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t
 	    eof = 1;
 	}
 
-//	printf("%lu %lu %lu - %u\n", ctx->event_id, ctx->cur_size, ctx->cur_raw_size, eof);
-	
 	    // just rip of padding
 	bufsize = ctx->cur_raw_size - ctx->cur_size;
 
@@ -208,13 +203,14 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t
 	    return -PCILIB_ERROR_TOOBIG;
 	}
 
-        memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size +  ctx->cur_size, buf, bufsize);
+	if (bufsize)
+	    memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size +  ctx->cur_size, buf, bufsize);
     }
 
     ctx->cur_size += bufsize;
 //    printf("%i: %i %i\n", ctx->buffer_pos, ctx->cur_size, bufsize);
 
-    if (ctx->cur_size >= ctx->full_size) {
+    if (ctx->cur_size >= ctx->cur_raw_size) {
 	eof = 1;
     }
 
@@ -246,14 +242,14 @@ void *ipecamera_reader_thread(void *user) {
     ipecamera_t *ctx = (ipecamera_t*)user;
     
     while (ctx->run_reader) {
-	err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, 10 * PCILIB_DMA_TIMEOUT, &ipecamera_data_callback, user);
+	err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, IPECAMERA_DMA_TIMEOUT, &ipecamera_data_callback, user);
 	if (err) {
 	    if (err == PCILIB_ERROR_TIMEOUT) {
 		if (ctx->cur_size >= ctx->cur_raw_size) ipecamera_new_frame(ctx);
 #ifdef IPECAMERA_BUG_INCOMPLETE_PACKETS
 		else if (ctx->cur_size > 0) ipecamera_new_frame(ctx);
 #endif /* IPECAMERA_BUG_INCOMPLETE_PACKETS */
-		if (pcilib_check_deadline(&ctx->autostop.timestamp, 10 * PCILIB_DMA_TIMEOUT)) {
+		if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) {
 		    ctx->run_reader = 0;
 		    break;
 		}

+ 0 - 0
ipecamera/reader.h → reader.h


+ 0 - 362
register.c

@@ -1,362 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "pci.h"
-
-#include "tools.h"
-#include "error.h"
-
-int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers) {
-    pcilib_register_description_t *regs;
-    size_t size, n_present = 0;
-
-    if (!n) {
-	for (n = 0; registers[n].bits; n++);
-    }
-
-    if (ctx->model_info.registers == pcilib_model[ctx->model].registers) {
-        for (n_present = 0; ctx->model_info.registers[n_present].bits; n_present++);
-	for (size = 1024; size < 2 * (n + n_present + 1); size<<=1);
-	regs = (pcilib_register_description_t*)malloc(size * sizeof(pcilib_register_description_t));
-	if (!regs) return PCILIB_ERROR_MEMORY;
-	
-	ctx->model_info.registers = regs;
-	ctx->num_reg = n + n_present;
-	ctx->alloc_reg = size;
-	
-	memcpy(ctx->model_info.registers, pcilib_model[ctx->model].registers, (n_present + 1) * sizeof(pcilib_register_description_t));
-    } else {
-	n_present = ctx->num_reg;
-	if ((n_present + n + 1) > ctx->alloc_reg) {
-	    for (size = ctx->alloc_reg; size < 2 * (n + n_present + 1); size<<=1);
-
-	    regs = (pcilib_register_description_t*)realloc(ctx->model_info.registers, size * sizeof(pcilib_register_description_t));
-	    if (!regs) return PCILIB_ERROR_MEMORY;
-
-	    ctx->model_info.registers = regs;
-	    ctx->alloc_reg = size;
-	}
-	ctx->num_reg += n;
-    }
-
-    memcpy(ctx->model_info.registers + ctx->num_reg, ctx->model_info.registers + n_present, sizeof(pcilib_register_description_t));
-    memcpy(ctx->model_info.registers + n_present, registers, n * sizeof(pcilib_register_description_t));
-
-    return 0;
-}
-
-pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
-    pcilib_register_bank_t i;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_register_bank_description_t *banks = model_info->banks;
-
-    for (i = 0; banks[i].access; i++)
-	if (banks[i].addr == bank) return i;
-
-    return -1;
-}
-
-pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname) {
-    pcilib_register_bank_t i;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_register_bank_description_t *banks = model_info->banks;
-
-    for (i = 0; banks[i].access; i++)
-	if (!strcasecmp(banks[i].name, bankname)) return i;
-
-    return -1;
-}
-
-pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank) {
-    pcilib_register_bank_t res;
-    unsigned long addr;
-    
-    if (!bank) {
-        pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-	pcilib_register_bank_description_t *banks = model_info->banks;
-	if ((banks)&&(banks[0].access)) return (pcilib_register_bank_t)0;
-	return -1;
-    }
-    
-    if (pcilib_isxnumber(bank)&&(sscanf(bank,"%lx", &addr) == 1)) {
-	res = pcilib_find_bank_by_addr(ctx, addr);
-	if (res != PCILIB_REGISTER_BANK_INVALID) return res;
-    }
-    
-    return pcilib_find_bank_by_name(ctx, bank);
-}
-
-    // FIXME create hash during map_register space
-pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg) {
-    pcilib_register_t i;
-    pcilib_register_bank_t bank_id;
-    pcilib_register_bank_addr_t bank_addr = 0;
-
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_register_description_t *registers =  model_info->registers;
-    
-    if (bank) {
-	bank_id = pcilib_find_bank(ctx, bank);
-	if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
-	    pcilib_error("Invalid bank (%s) is specified", bank);
-	    return -1;
-	}
-	
-	bank_addr = model_info->banks[bank_id].addr;
-    }
-    
-    for (i = 0; registers[i].bits; i++) {
-	if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
-    }
-    
-    if ((ctx->model_info.dma_api)&&(!ctx->dma_ctx)&&(pcilib_get_dma_info(ctx))) {
-        registers =  model_info->registers;
-
-	for (; registers[i].bits; i++) {
-	    if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
-	}
-    }
-    
-    return (pcilib_register_t)-1;
-};
-
-static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t *buf) {
-    int err;
-    size_t i;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_register_bank_description_t *b = model_info->banks + bank;
-    
-    int access = b->access / 8;
-
-    assert(bits < 8 * sizeof(pcilib_register_value_t));
-    
-    if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
-	if ((b->format)&&(strchr(b->format, 'x')))
-	    pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
-	else 
-	    pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
-	return PCILIB_ERROR_OUTOFRANGE;
-    }
-
-    err = pcilib_map_register_space(ctx);
-    if (err) {
-	pcilib_error("Failed to map the register space");
-	return err;
-    }
-    
-    //n += bits / b->access;
-    //bits %= b->access; 
-    
-    for (i = 0; i < n; i++) {
-	err = pcilib_protocol[b->protocol].read(ctx, b, addr + i * access, buf + i);
-	if (err) break;
-    }
-    
-    if ((bits > 0)&&(!err)) {
-	pcilib_register_value_t val = 0;
-	err = pcilib_protocol[b->protocol].read(ctx, b, addr + n * access, &val);
-
-	val = (val >> offset)&BIT_MASK(bits);
-	memcpy(buf + n, &val, sizeof(pcilib_register_value_t));
-    }
-    
-    return err;
-}
-
-int pcilib_read_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf) {
-    pcilib_register_bank_t bank_id = pcilib_find_bank(ctx, bank);
-    if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
-	if (bank) pcilib_error("Invalid register bank is specified (%s)", bank);
-	else pcilib_error("Register bank should be specified");
-	return PCILIB_ERROR_INVALID_BANK;
-    }
-    
-    return pcilib_read_register_space_internal(ctx, bank_id, addr, n, 0, 0, buf);
-}
-
-int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t *value) {
-    int err;
-    size_t i, n;
-    pcilib_register_size_t bits;
-    pcilib_register_value_t res;
-    pcilib_register_bank_t bank;
-    pcilib_register_description_t *r;
-    pcilib_register_bank_description_t *b;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    r = model_info->registers + reg;
-    
-    bank = pcilib_find_bank_by_addr(ctx, r->bank);
-    if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK;
-    
-    b = model_info->banks + bank;
-    
-    n = r->bits / b->access;
-    bits = r->bits % b->access; 
-
-    pcilib_register_value_t buf[n + 1];
-    err = pcilib_read_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, buf);
-
-    if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) {
-	pcilib_error("Big-endian byte order support is not implemented");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    } else {
-	res = 0;
-	if (bits) ++n;
-	for (i = 0; i < n; i++) {
-	    res |= buf[i] << (i * b->access);
-	}
-    }
-    
-    *value = res;
-    
-    return err;
-}
-
-
-int pcilib_read_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t *value) {
-    int reg;
-    
-    reg = pcilib_find_register(ctx, bank, regname);
-    if (reg < 0) {
-	pcilib_error("Register (%s) is not found", regname);
-	return PCILIB_ERROR_NOTFOUND;
-    }
-    
-    return pcilib_read_register_by_id(ctx, reg, value);
-}
-
-
-static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t rwmask, pcilib_register_value_t *buf) {
-    int err;
-    size_t i;
-    
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_register_bank_description_t *b = model_info->banks + bank;
-
-    int access = b->access / 8;
-
-    assert(bits < 8 * sizeof(pcilib_register_value_t));
-
-    if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
-	if ((b->format)&&(strchr(b->format, 'x')))
-	    pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
-	else 
-	    pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
-	return PCILIB_ERROR_OUTOFRANGE;
-    }
-
-    err = pcilib_map_register_space(ctx);
-    if (err) {
-	pcilib_error("Failed to map the register space");
-	return err;
-    }
-    
-    //n += bits / b->access;
-    //bits %= b->access; 
-    
-    for (i = 0; i < n; i++) {
-	err = pcilib_protocol[b->protocol].write(ctx, b, addr + i * access, buf[i]);
-	if (err) break;
-    }
-    
-    if ((bits > 0)&&(!err)) {
-	pcilib_register_value_t val = (buf[n]&BIT_MASK(bits))<<offset;
-	pcilib_register_value_t mask = BIT_MASK(bits)<<offset;
-
-	if (~mask&rwmask) {
-	    pcilib_register_value_t rval;
-	    
-	    err = pcilib_protocol[b->protocol].read(ctx, b, addr + n * access, &rval); 
-	    if (err) return err;
-	    
-	    val |= (rval & rwmask & ~mask);
-	}
-	
-	err = pcilib_protocol[b->protocol].write(ctx, b, addr + n * access, val);
-    }
-    
-    return err;
-}
-
-int pcilib_write_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf) {
-    pcilib_register_bank_t bank_id = pcilib_find_bank(ctx, bank);
-    if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
-	if (bank) pcilib_error("Invalid register bank is specified (%s)", bank);
-	else pcilib_error("Register bank should be specified");
-	return PCILIB_ERROR_INVALID_BANK;
-    }
-    
-    return pcilib_write_register_space_internal(ctx, bank_id, addr, n, 0, 0, 0, buf);
-}
-
-
-int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t value) {
-    int err;
-    size_t i, n;
-    pcilib_register_size_t bits;
-    pcilib_register_bank_t bank;
-    pcilib_register_value_t res;
-    pcilib_register_description_t *r;
-    pcilib_register_bank_description_t *b;
-    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-
-    r = model_info->registers + reg;
-
-    bank = pcilib_find_bank_by_addr(ctx, r->bank);
-    if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK;
-
-    b = model_info->banks + bank;
-    
-    n = r->bits / b->access;
-    bits = r->bits % b->access; 
-
-    pcilib_register_value_t buf[n + 1];
-    memset(buf, 0, (n + 1) * sizeof(pcilib_register_value_t));
-    
-    if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) {
-	pcilib_error("Big-endian byte order support is not implemented");
-	return PCILIB_ERROR_NOTSUPPORTED;
-    } else {
-	if (b->access == sizeof(pcilib_register_value_t) * 8) {
-	    buf[0] = value;
-	} else {
-	    for (i = 0, res = value; (res > 0)&&(i <= n); ++i) {
-		buf[i] = res & BIT_MASK(b->access);
-	        res >>= b->access;
-	    }
-	
-	    if (res) {
-		pcilib_error("Value %i is too big to fit in the register %s", value, r->name);
-		return PCILIB_ERROR_OUTOFRANGE;
-	    }
-	}
-    }
-
-    err = pcilib_write_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, r->rwmask, buf);
-    return err;
-}
-
-int pcilib_write_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t value) {
-    int reg;
-    
-    reg = pcilib_find_register(ctx, bank, regname);
-    if (reg < 0) {
-	pcilib_error("Register (%s) is not found", regname);
-	return PCILIB_ERROR_NOTFOUND;
-    }
-
-    return pcilib_write_register_by_id(ctx, reg, value);
-}

+ 0 - 14
register.h

@@ -1,14 +0,0 @@
-#ifndef _PCILIB_REGISTER_H
-#define _PCILIB_REGISTER_H
-
-#include "pcilib.h"
-
-struct pcilib_protocol_description_s {
-    int (*read)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
-    int (*write)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
-};
-
-    // we don't copy strings, they should be statically allocated
-int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers);
-
-#endif /* _PCILIB_REGISTER_H */

+ 3 - 2
tests/ipecamera/autotrigger.sh → tests/autotrigger.sh

@@ -1,8 +1,9 @@
 #! /bin/bash
 
 function pci {
-    PCILIB_PATH="../../"
-    LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $*
+    PCILIB_PATH=`which pci`
+    #LD_LIBRARY_PATH="$PCILIB_PATH" 
+    $PCILIB_PATH/pci $*
 }
 
 echo "Starting the grabber"

+ 3 - 2
tests/ipecamera/debug/incomplete.sh → tests/debug/incomplete.sh

@@ -1,8 +1,9 @@
 #! /bin/bash
 
 function pci {
-    PCILIB_PATH="/root/pcitool"
-    LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $*
+    PCILIB_PATH=`which pci`
+    #LD_LIBRARY_PATH="$PCILIB_PATH" 
+    $PCILIB_PATH/pci $*
 }
 
 rm -f images.raw

+ 0 - 19
tests/dma/debug/test-iommu.sh

@@ -1,19 +0,0 @@
-#! /bin/bash
-
-i=1
-while [ 1 ]; do
-    pci --start-dma dma1r
-    for name in /sys/class/fpga/fpga0/kbuf*; do
-	bus_addr=0x`cat $name | grep "bus addr" | cut -d ':' -f 2 | sed -e 's/\s\+//g'`
-	if [ $((bus_addr % 4096)) -ne 0 ]; then
-	    
-	    echo "Failed at iteration $i, $name"
-	    echo "----------------------"
-	    cat $name
-	    exit
-	fi
-
-    done
-    pci  --stop-dma dma1r
-    i=$((i + 1))
-done

+ 0 - 40
tests/dma/ipe/bench.sh

@@ -1,40 +0,0 @@
-#!/bin/bash
-
-size=65536
-
-function pci {
-    PCILIB_PATH=`pwd`/../../..
-    LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci -m kapture $*
-}
-
-
-rm -f bench.out
-
-echo "Stopping DMA and skipping exiting data..."
-pci --stop-dma dma0r
-echo "Starting DMA..."
-pci --start-dma dma0r
-echo "Enabling data generation..."
-pci -w 0x4 0x1
-
-# Clean DMA buffers
-#while [ $? -eq 0 ]; do
-#    pci -r dma0 -s 65536 &> /dev/null
-#done
-
-echo "Reading the data from DMA..."
-for i in `seq 1 100`; do
-    pci -r dma0 --multipacket -s $size -o bench.out
-    if [ $? -ne 0 ]; then
-	echo "Stopping DMA due to the error..."
-	pci --stop-dma dma0r
-	exit
-    fi
-done
-
-echo "Stopping DMA..."
-pci --stop-dma dma0r
-
-../../../apps/check_counter bench.out
-
-#pci -r 0 -s 32

+ 0 - 30
tests/dma/nwl/bench.sh

@@ -1,30 +0,0 @@
-#!/bin/bash
-
-function pci {
-    PCILIB_PATH="/root/pcitool"
-    LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $*
-}
-
-size=16
-bytes=`expr $size "*" 4`
-
-pci -w xrawdata_packet_length $bytes
-pci -w xrawdata_enable_loopback 0
-pci -w xrawdata_enable_generator 0
-
-pci --start-dma dma1
-
-while [ $? -eq 0 ]; do
-    pci -r dma1 -s 65536 &> /dev/null
-done
-
-pci -w xrawdata_enable_loopback 1
-
-for i in `seq 1 10`; do
-    pci -w dma1 -s $size "*$i"
-    pci -r dma1 -s $size -o bench.out
-done
-
-pci --stop-dma dma1
-
-pci -w xrawdata_enable_loopback 0

+ 0 - 13
tests/dma/nwl/cleanup.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-
-function pci {
-    PCILIB_PATH="/root/pcitool"
-    LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $*
-}
-
-pci --start-dma dma1r
-pci -w dma1r_reset_request 1
-pci -w dma1r_reset 1
-pci -r dma1r_running
-
-pci --free-kernel-memory dma

Some files were not shown because too many files changed in this diff