aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorBalint Seeber <balint.seeber@ettus.com>2015-07-27 15:16:49 -0700
committerMartin Braun <martin.braun@ettus.com>2015-08-03 10:11:44 -0700
commit4ed2b26d512ed8c8e78fbbfcf25a3560fd8c7102 (patch)
tree940764e665d503f50a293ac8d50ca1fb0b605544 /host/lib/usrp
parente1672fa7eedb00a977c39b7e80bb18521493b524 (diff)
downloaduhd-4ed2b26d512ed8c8e78fbbfcf25a3560fd8c7102.tar.gz
uhd-4ed2b26d512ed8c8e78fbbfcf25a3560fd8c7102.tar.bz2
uhd-4ed2b26d512ed8c8e78fbbfcf25a3560fd8c7102.zip
b200: Change init sequence to catch bad USB states
- Fixes USB hang issues on OS X - Uses usb_errors
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp34
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp12
2 files changed, 38 insertions, 8 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index 3445f125b..f5129bc24 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -37,6 +37,8 @@
#include <ctime>
#include <cmath>
+#include "../../transport/libusb1_base.hpp"
+
using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
@@ -194,7 +196,24 @@ static device_addrs_t b200_find(const device_addr_t &hint)
**********************************************************************/
static device::sptr b200_make(const device_addr_t &device_addr)
{
- return device::sptr(new b200_impl(device_addr));
+ uhd::transport::usb_device_handle::sptr handle;
+
+ // We try twice, because the first time, the link might be in a bad state
+ // and we might need to reset the link, but if that didn't help, trying
+ // a third time is pointless.
+ try {
+ return device::sptr(new b200_impl(device_addr, handle));
+ }
+ catch (const uhd::usb_error &e) {
+ libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle(
+ boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()
+ ));
+ dev_handle->clear_endpoints(B200_USB_CTRL_RECV_ENDPOINT, B200_USB_CTRL_SEND_ENDPOINT);
+ dev_handle->clear_endpoints(B200_USB_DATA_RECV_ENDPOINT, B200_USB_DATA_SEND_ENDPOINT);
+ dev_handle->reset_device();
+ }
+
+ return device::sptr(new b200_impl(device_addr, handle));
}
UHD_STATIC_BLOCK(register_b200_device)
@@ -205,7 +224,7 @@ UHD_STATIC_BLOCK(register_b200_device)
/***********************************************************************
* Structors
**********************************************************************/
-b200_impl::b200_impl(const device_addr_t &device_addr) :
+b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::sptr &handle) :
_revision(0),
_tick_rate(0.0) // Forces a clock initialization at startup
{
@@ -262,7 +281,6 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
std::vector<usb_device_handle::sptr> device_list = usb_device_handle::get_device_list(vid_pid_pair_list);
//locate the matching handle in the device list
- usb_device_handle::sptr handle;
BOOST_FOREACH(usb_device_handle::sptr dev_handle, device_list) {
if (dev_handle->get_serial() == device_addr["serial"]){
handle = dev_handle;
@@ -360,10 +378,11 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
ctrl_xport_args["send_frame_size"] = min_frame_size;
ctrl_xport_args["num_send_frames"] = "16";
+ // This may throw a uhd::usb_error, which will be caught by b200_make().
_ctrl_transport = usb_zero_copy::make(
handle,
- 4, 8, //interface, endpoint
- 3, 4, //interface, endpoint
+ B200_USB_CTRL_RECV_INTERFACE, B200_USB_CTRL_RECV_ENDPOINT, //interface, endpoint
+ B200_USB_CTRL_SEND_INTERFACE, B200_USB_CTRL_SEND_ENDPOINT, //interface, endpoint
ctrl_xport_args
);
while (_ctrl_transport->get_recv_buff(0.0)){} //flush ctrl xport
@@ -442,10 +461,11 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", "8192");
data_xport_args["num_send_frames"] = device_addr.get("num_send_frames", "16");
+ // This may throw a uhd::usb_error, which will be caught by b200_make().
_data_transport = usb_zero_copy::make(
handle, // identifier
- 2, 6, // IN interface, endpoint
- 1, 2, // OUT interface, endpoint
+ B200_USB_DATA_RECV_INTERFACE, B200_USB_DATA_RECV_ENDPOINT, //interface, endpoint
+ B200_USB_DATA_SEND_INTERFACE, B200_USB_DATA_SEND_ENDPOINT, //interface, endpoint
data_xport_args // param hints
);
while (_data_transport->get_recv_buff(0.0)){} //flush ctrl xport
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index 52ecb98f2..cbd51426d 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -78,6 +78,16 @@ static const boost::uint32_t B200_RX_GPS_UART_SID = FLIP_SID(B200_TX_GPS_UART_SI
static const boost::uint32_t B200_LOCAL_CTRL_SID = 0x00000040;
static const boost::uint32_t B200_LOCAL_RESP_SID = FLIP_SID(B200_LOCAL_CTRL_SID);
+static const unsigned char B200_USB_CTRL_RECV_INTERFACE = 4;
+static const unsigned char B200_USB_CTRL_RECV_ENDPOINT = 8;
+static const unsigned char B200_USB_CTRL_SEND_INTERFACE = 3;
+static const unsigned char B200_USB_CTRL_SEND_ENDPOINT = 4;
+
+static const unsigned char B200_USB_DATA_RECV_INTERFACE = 2;
+static const unsigned char B200_USB_DATA_RECV_ENDPOINT = 6;
+static const unsigned char B200_USB_DATA_SEND_INTERFACE = 1;
+static const unsigned char B200_USB_DATA_SEND_ENDPOINT = 2;
+
/*
* VID/PID pairs for all B2xx products
*/
@@ -96,7 +106,7 @@ class b200_impl : public uhd::device
{
public:
//structors
- b200_impl(const uhd::device_addr_t &);
+ b200_impl(const uhd::device_addr_t &, uhd::transport::usb_device_handle::sptr &handle);
~b200_impl(void);
//the io interface