diff options
author | michael-west <michael.west@ettus.com> | 2014-03-25 15:59:03 -0700 |
---|---|---|
committer | michael-west <michael.west@ettus.com> | 2014-03-25 15:59:03 -0700 |
commit | 04292f9b109479b639add31f83fd240a6387f488 (patch) | |
tree | 4b8723a4ae63626029704f901ee0083bb23bc1e9 /host/lib/transport/nirio/nirio_driver_iface_linux.cpp | |
parent | 09915aa57bc88099cbcbbe925946ae65bc0ad8f0 (diff) | |
parent | ff8a1252f3a51369abe0a165d963b781089ec66c (diff) | |
download | uhd-04292f9b109479b639add31f83fd240a6387f488.tar.gz uhd-04292f9b109479b639add31f83fd240a6387f488.tar.bz2 uhd-04292f9b109479b639add31f83fd240a6387f488.zip |
Merge branch 'master' into mwest/b200_docs
Diffstat (limited to 'host/lib/transport/nirio/nirio_driver_iface_linux.cpp')
-rw-r--r-- | host/lib/transport/nirio/nirio_driver_iface_linux.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp new file mode 100644 index 000000000..b1f4bb49f --- /dev/null +++ b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp @@ -0,0 +1,111 @@ +// +// Copyright 2013 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/transport/nirio/nirio_driver_iface.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/mman.h> + +namespace nirio_driver_iface { + +nirio_status rio_open( + const std::string& device_path, + rio_dev_handle_t& device_handle) +{ + device_handle = ::open(device_path.c_str(), O_RDWR | O_CLOEXEC); + return (device_handle < 0) ? NiRio_Status_InvalidParameter : NiRio_Status_Success; +} + +void rio_close(rio_dev_handle_t& device_handle) +{ + ::close(device_handle); + device_handle = -1; +} + +bool rio_isopen(rio_dev_handle_t device_handle) +{ + return (device_handle >= 0); +} + +nirio_status rio_ioctl( + rio_dev_handle_t device_handle, + uint32_t ioctl_code, + const void *write_buf, + size_t write_buf_len, + void *read_buf, + size_t read_buf_len) +{ + nirio_ioctl_block_t ioctl_block = {0,0,0,0,0,0}; + + // two-casts necessary to prevent pointer sign-extension + ioctl_block.inBuf = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(write_buf)); + ioctl_block.inBufLength = write_buf_len; + ioctl_block.outBuf = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(read_buf)); + ioctl_block.outBufLength = read_buf_len; + + int status = ::ioctl(device_handle, ioctl_code, &ioctl_block); + if (status == -1) { + switch (errno) { + case EINVAL: return NiRio_Status_InvalidParameter; + case EFAULT: return NiRio_Status_MemoryFull; + default: return NiRio_Status_SoftwareFault; + } + } else { + return NiRio_Status_Success; + } +} + +nirio_status rio_mmap( + rio_dev_handle_t device_handle, + uint16_t memory_type, + size_t size, + bool writable, + rio_mmap_t &map) +{ + int access_mode = PROT_READ; //Write-only mode not supported + if (writable) access_mode |= PROT_WRITE; + map.addr = ::mmap(NULL, size, access_mode, MAP_SHARED, device_handle, (off_t) memory_type * sysconf(_SC_PAGESIZE)); + map.size = size; + + if (map.addr == MAP_FAILED) { + map.addr = NULL; + map.size = 0; + switch (errno) { + case EINVAL: return NiRio_Status_InvalidParameter; + case EFAULT: return NiRio_Status_MemoryFull; + default: return NiRio_Status_SoftwareFault; + } + } + return NiRio_Status_Success; +} + +nirio_status rio_munmap(rio_mmap_t &map) +{ + nirio_status status = 0; + if (map.addr != NULL) { + status = ::munmap(map.addr, map.size); + + map.addr = NULL; + map.size = 0; + } + return status; +} + +} |