aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/x300/x300_impl.cpp')
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp95
1 files changed, 68 insertions, 27 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 50a7f3ded..d6e2a6fdc 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -18,6 +18,7 @@
#include "x300_impl.hpp"
#include "x300_lvbitx.hpp"
#include "x310_lvbitx.hpp"
+#include "x300_mb_eeprom.hpp"
#include "apply_corrections.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
@@ -121,12 +122,16 @@ static device_addrs_t x300_find_with_addr(const device_addr_t &hint)
false /* Suppress timeout errors */
);
- if (x300_impl::is_claimed(zpu_ctrl)) continue; //claimed by another process
new_addr["fpga"] = get_fpga_option(zpu_ctrl);
i2c_core_100_wb32::sptr zpu_i2c = i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE);
- i2c_iface::sptr eeprom16 = zpu_i2c->eeprom16();
- const mboard_eeprom_t mb_eeprom(*eeprom16, "X300");
+ x300_mb_eeprom_iface::sptr eeprom_iface = x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c);
+ const mboard_eeprom_t mb_eeprom(*eeprom_iface, "X300");
+ if (mb_eeprom.size() == 0 or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER)
+ {
+ // Skip device claimed by another process
+ continue;
+ }
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = mb_eeprom["serial"];
switch (x300_impl::get_mb_type_from_eeprom(mb_eeprom)) {
@@ -221,7 +226,6 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu
//We don't put this zpu_ctrl in the registry because we need
//a persistent niriok_proxy associated with the object
}
- if (x300_impl::is_claimed(zpu_ctrl)) continue; //claimed by another process
//Attempt to autodetect the FPGA type
if (not hint.has_key("fpga")) {
@@ -229,8 +233,13 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu
}
i2c_core_100_wb32::sptr zpu_i2c = i2c_core_100_wb32::make(zpu_ctrl, I2C1_BASE);
- i2c_iface::sptr eeprom16 = zpu_i2c->eeprom16();
- const mboard_eeprom_t mb_eeprom(*eeprom16, "X300");
+ x300_mb_eeprom_iface::sptr eeprom_iface = x300_mb_eeprom_iface::make(zpu_ctrl, zpu_i2c);
+ const mboard_eeprom_t mb_eeprom(*eeprom_iface, "X300");
+ if (mb_eeprom.size() == 0 or x300_impl::claim_status(zpu_ctrl) == x300_impl::CLAIMED_BY_OTHER)
+ {
+ // Skip device claimed by another process
+ continue;
+ }
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = mb_eeprom["serial"];
}
@@ -307,12 +316,7 @@ device_addrs_t x300_find(const device_addr_t &hint_)
{
UHD_MSG(error) << "X300 Network discovery unknown error " << std::endl;
}
- BOOST_FOREACH(const device_addr_t &reply_addr, reply_addrs)
- {
- device_addrs_t new_addrs = x300_find_with_addr(reply_addr);
- addrs.insert(addrs.begin(), new_addrs.begin(), new_addrs.end());
- }
- return addrs;
+ return reply_addrs;
}
if (!hint.has_key("resource"))
@@ -671,6 +675,10 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
mb.get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)));
}
+ // Claim device
+ if (not try_to_claim(mb.zpu_ctrl)) {
+ throw uhd::runtime_error("Failed to claim device");
+ }
mb.claimer_task = uhd::task::make(boost::bind(&x300_impl::claimer_loop, this, mb.zpu_ctrl));
//extract the FW path for the X300
@@ -726,7 +734,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
// setup the mboard eeprom
////////////////////////////////////////////////////////////////////
UHD_MSG(status) << "Loading values from EEPROM..." << std::endl;
- i2c_iface::sptr eeprom16 = mb.zpu_i2c->eeprom16();
+ x300_mb_eeprom_iface::sptr eeprom16 = x300_mb_eeprom_iface::make(mb.zpu_ctrl, mb.zpu_i2c);
if (dev_addr.has_key("blank_eeprom"))
{
UHD_MSG(warning) << "Obliterating the motherboard EEPROM..." << std::endl;
@@ -1011,8 +1019,7 @@ x300_impl::~x300_impl(void)
mb.claimer_task.reset();
{ //Critical section
boost::mutex::scoped_lock(pcie_zpu_iface_registry_mutex);
- mb.zpu_ctrl->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_TIME), 0);
- mb.zpu_ctrl->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_SRC), 0);
+ release(mb.zpu_ctrl);
//If the process is killed, the entire registry will disappear so we
//don't need to worry about unclean shutdowns here.
get_pcie_zpu_iface_registry().pop(mb.get_pri_eth().addr);
@@ -1465,24 +1472,58 @@ void x300_impl::set_mb_eeprom(i2c_iface::sptr i2c, const mboard_eeprom_t &mb_eep
void x300_impl::claimer_loop(wb_iface::sptr iface)
{
- { //Critical section
- boost::mutex::scoped_lock(claimer_mutex);
- iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_TIME), uint32_t(time(NULL)));
- iface->poke32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_SRC), get_process_hash());
- }
+ claim(iface);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); //1 second
}
-bool x300_impl::is_claimed(wb_iface::sptr iface)
+x300_impl::claim_status_t x300_impl::claim_status(wb_iface::sptr iface)
{
- boost::mutex::scoped_lock(claimer_mutex);
-
- //If timed out then device is definitely unclaimed
- if (iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_STATUS)) == 0)
- return false;
+ //If timed out, then device is definitely unclaimed
+ if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0)
+ return UNCLAIMED;
//otherwise check claim src to determine if another thread with the same src has claimed the device
- return iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_CLAIM_SRC)) != get_process_hash();
+ uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC));
+ return (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER);
+}
+
+void x300_impl::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 x300_impl::try_to_claim(wb_iface::sptr iface, long timeout)
+{
+ boost::system_time start_time = boost::get_system_time();
+ 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
+ boost::this_thread::sleep(boost::posix_time::milliseconds(20));
+ continue;
+ }
+ if (status == CLAIMED_BY_US)
+ {
+ break;
+ }
+ if (boost::get_system_time() - start_time > boost::posix_time::milliseconds(timeout))
+ {
+ // Another process owns the device - give up
+ return false;
+ }
+ boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+ }
+ return true;
+}
+
+void x300_impl::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);
}
/***********************************************************************