From 173531521970ed823b2f300180b8cacda94ec841 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 25 Jul 2019 10:41:25 -0700 Subject: x300: Refactor heavily This pulls out a lot of code from x300_impl and puts it into its own compilation units: - EEPROM code goes to x300_mb_eeprom.* - Claim code goes to x300_claim.* - PCIe code goes to uhd::usrp::x300::pcie_manager - Ethernet code goes to uhd::usrp::x300::eth_manager --- host/lib/usrp/x300/x300_claim.cpp | 89 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 host/lib/usrp/x300/x300_claim.cpp (limited to 'host/lib/usrp/x300/x300_claim.cpp') diff --git a/host/lib/usrp/x300/x300_claim.cpp b/host/lib/usrp/x300/x300_claim.cpp new file mode 100644 index 000000000..8a8de037d --- /dev/null +++ b/host/lib/usrp/x300/x300_claim.cpp @@ -0,0 +1,89 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include "x300_claim.hpp" +#include "x300_fw_common.h" +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp::x300; + +/*********************************************************************** + * claimer logic + **********************************************************************/ + +void uhd::usrp::x300::claimer_loop(wb_iface::sptr iface) +{ + claim(iface); + std::this_thread::sleep_for(std::chrono::seconds(1)); +} + +claim_status_t uhd::usrp::x300::claim_status(wb_iface::sptr iface) +{ + claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive + auto timeout_time = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < timeout_time) { + // If timed out, then device is definitely unclaimed + if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) { + claim_status = UNCLAIMED; + break; + } + + // otherwise check claim src to determine if another thread with the same src has + // claimed the device + uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); + if (hash == 0) { + // A non-zero claim status and an empty hash means the claim might + // be in the process of being released. This is possible because + // older firmware takes a long time to update the status. Wait and + // check status again. + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + continue; + } + claim_status = (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER); + break; + } + return claim_status; +} + +void uhd::usrp::x300::claim(wb_iface::sptr iface) +{ + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_TIME), uint32_t(time(NULL))); + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC), get_process_hash()); +} + +bool uhd::usrp::x300::try_to_claim(wb_iface::sptr iface, long timeout_ms) +{ + const auto timeout_time = + std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms); + while (1) { + claim_status_t status = claim_status(iface); + if (status == UNCLAIMED) { + claim(iface); + // It takes the claimer 10ms to update status, so wait 20ms before verifying + // claim + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + continue; + } + if (status == CLAIMED_BY_US) { + break; + } + if (std::chrono::steady_clock::now() > timeout_time) { + // Another process owns the device - give up + return false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + return true; +} + +void uhd::usrp::x300::release(wb_iface::sptr iface) +{ + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_TIME), 0); + iface->poke32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC), 0); +} -- cgit v1.2.3