switch source package format to 3.0 quilt
[debian/gnuradio] / usrp / host / lib / fusb_linux.cc
index 1eaba4e508e70db5ea0dd7082d3bf272c9644dac..6c484569f36562b148d7d35396705e9e32eb53b7 100644 (file)
@@ -6,7 +6,7 @@
  * 
  * GNU Radio 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 2, or (at your option)
+ * the Free Software Foundation; either version 3, or (at your option)
  * any later version.
  * 
  * GNU Radio is distributed in the hope that it will be useful,
@@ -37,6 +37,7 @@
 #include <algorithm>
 #include <errno.h>
 #include <string.h>
+#include <cstdio>
 
 #define MINIMIZE_TX_BUFFERING 1                // must be defined to 0 or 1
 
@@ -246,7 +247,7 @@ fusb_devhandle_linux::_cancel_urb (usbdevfs_urb *urb)
  * If any transactions are reaped return true.
  *
  * If ok_to_block_p is true, then this will block until at least one
- * transaction completes.
+ * transaction completes or an unrecoverable error occurs.
  */
 bool
 fusb_devhandle_linux::_reap (bool ok_to_block_p)
@@ -290,7 +291,8 @@ void
 fusb_devhandle_linux::_wait_for_completion ()
 {
   while (!d_pending_rqsts.empty ())
-    _reap (true);
+    if (!_reap(true))
+      break;
 }
 \f// ------------------------------------------------------------------------
 //                          end point handle
@@ -386,14 +388,6 @@ fusb_ephandle_linux::stop ()
 {
   if (!d_started)
     return true;
-  
-  d_devhandle->_cancel_pending_rqsts (this);
-  d_devhandle->_reap (false);
-
-
-  usbdevfs_urb *urb;
-  while ((urb = completed_list_get ()) != 0)
-    free_list_add (urb);
 
   if (d_write_work_in_progress){
     free_list_add (d_write_work_in_progress);
@@ -407,11 +401,20 @@ fusb_ephandle_linux::stop ()
     d_read_buffer_end = 0;
   }
 
-  if (d_free_list.size () != (unsigned) d_nblocks)
-    fprintf (stderr, "d_free_list.size () = %d, d_nblocks = %d\n",
-            d_free_list.size (), d_nblocks);
-    
-  assert (d_free_list.size () == (unsigned) d_nblocks);
+  d_devhandle->_cancel_pending_rqsts (this);
+  d_devhandle->_reap (false);
+
+  while (1){
+    usbdevfs_urb *urb;
+    while ((urb = completed_list_get ()) != 0)
+      free_list_add (urb);
+
+    if (d_free_list.size () == (unsigned) d_nblocks)
+      break;
+
+    if (!d_devhandle->_reap(true))
+      break;
+  }
 
   d_started = false;
   return true;
@@ -440,6 +443,8 @@ fusb_ephandle_linux::write(const void *buffer, int nbytes)
   while (n < nbytes){
 
     usbdevfs_urb *urb = get_write_work_in_progress();
+    if (!urb)
+      return -1;
     assert(urb->actual_length == 0);
     int m = std::min(nbytes - n, MAX_BLOCK_SIZE);
     urb->buffer = src;
@@ -474,6 +479,8 @@ fusb_ephandle_linux::write (const void *buffer, int nbytes)
   while (n < nbytes){
 
     usbdevfs_urb *urb = get_write_work_in_progress ();
+    if (!urb)
+      return -1;
     unsigned char *dst = (unsigned char *) urb->buffer;
     int m = std::min (nbytes - n, urb->buffer_length - urb->actual_length);
 
@@ -516,7 +523,8 @@ fusb_ephandle_linux::get_write_work_in_progress ()
     // The free list is empty.  Tell the device handle to reap.
     // Anything it reaps for us will end up on our completed list.
 
-    d_devhandle->_reap (true);
+    if (!d_devhandle->_reap (true))
+      return 0;
   }
 }
 
@@ -606,19 +614,17 @@ fusb_ephandle_linux::reload_read_buffer ()
   while (1){
 
     while ((urb = completed_list_get ()) == 0)
-      d_devhandle->_reap (true);
+      if (!d_devhandle->_reap (true))
+       return false;
 
     // check result of completed read
 
     if (urb->status != 0){
-      // We've got a problem.
-      // Report the problem and resubmit.
+      // We've got a problem. Report it and fail.
       fprintf (stderr, "fusb: (rd status %d) %s\n", urb->status, strerror (-urb->status));
       urb->actual_length = 0;
-      if (!submit_urb (urb))
-       return false;
-
-      continue;
+      free_list_add (urb);
+      return false;
     }
 
     // we've got a happy urb, full of data...