diff --git a/ChangeLog b/ChangeLog
index 79f4b335..cb8d4738 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-01-17  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* flip2.c (flip2_page_erase): Remove unimplemented function.
+	* dfu.h: Correctly conditionalize <usb.h> vs. <lusb0_usb.h>;
+	add adjustable timeout (struct dfu_dev); add dfu_abort()
+	* dfu.c (dfu_abort): New function; implement adjustable timeout.
+
 2014-01-17  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* configure.ac (libhid): Turn from AC_TRY_RUN into
diff --git a/dfu.c b/dfu.c
index f35cdd3b..cb954978 100644
--- a/dfu.c
+++ b/dfu.c
@@ -70,8 +70,6 @@ int dfu_upload(struct dfu_dev *dfu, void * ptr, int size) {
 
 /* If we DO have LibUSB, we can define the real functions. */
 
-#include <usb.h>
-
 /* DFU data structures and constants.
  */
 
@@ -81,12 +79,14 @@ int dfu_upload(struct dfu_dev *dfu, void * ptr, int size) {
 #define DFU_UPLOAD 2
 #define DFU_GETSTATUS 3
 #define DFU_CLRSTATUS 4
+#define DFU_GETSTATE 5          /* FLIPv1 only; not used */
+#define DFU_ABORT 6             /* FLIPv1 only */
 
 /* Block counter global variable. Incremented each time a DFU_DNLOAD command
  * is sent to the device.
  */
 
-static u_int16_t wIndex = 0;
+static uint16_t wIndex = 0;
 
 /* INTERNAL FUNCTION PROTOTYPES
  */
@@ -118,8 +118,8 @@ struct dfu_dev * dfu_open(char *port_spec)
   if(':' == port_spec[3]) {
       bus_name = strdup(port_spec + 3 + 1);
       if (bus_name == NULL) {
-        perror(progname);
-        exit(1);
+        fprintf(stderr, "%s: Out of memory in strdup\n", progname);
+        return NULL;
       }
 
       dev_name = strchr(bus_name, ':');
@@ -135,12 +135,13 @@ struct dfu_dev * dfu_open(char *port_spec)
 
   if (dfu == NULL)
   {
-    perror(progname);
-    exit(1);
+    fprintf(stderr, "%s: out of memory\n", progname);
+    return 0;
   }
 
   dfu->bus_name = bus_name;
   dfu->dev_name = dev_name;
+  dfu->timeout = DFU_TIMEOUT;
 
   /* LibUSB initialization. */
 
@@ -274,7 +275,7 @@ int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status)
 
   result = usb_control_msg(dfu->dev_handle,
     0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_GETSTATUS, 0, 0,
-    (char*) status, sizeof(struct dfu_status), DFU_TIMEOUT);
+    (char*) status, sizeof(struct dfu_status), dfu->timeout);
 
   if (result < 0) {
     fprintf(stderr, "%s: Error: Failed to get DFU status: %s\n",
@@ -316,7 +317,7 @@ int dfu_clrstatus(struct dfu_dev *dfu)
 
   result = usb_control_msg(dfu->dev_handle,
     USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, 0,
-    NULL, 0, DFU_TIMEOUT);
+    NULL, 0, dfu->timeout);
 
   if (result < 0) {
     fprintf(stderr, "%s: Error: Failed to clear DFU status: %s\n",
@@ -327,6 +328,28 @@ int dfu_clrstatus(struct dfu_dev *dfu)
   return 0;
 }
 
+int dfu_abort(struct dfu_dev *dfu)
+{
+  int result;
+
+  if (verbose > 3)
+    fprintf(stderr, "%s: dfu_abort(): issuing control OUT message\n",
+            progname);
+
+  result = usb_control_msg(dfu->dev_handle,
+    USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_ABORT, 0, 0,
+    NULL, 0, dfu->timeout);
+
+  if (result < 0) {
+    fprintf(stderr, "%s: Error: Failed to reset DFU state: %s\n",
+      progname, usb_strerror());
+    return -1;
+  }
+
+  return 0;
+}
+
+
 int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size)
 {
   int result;
@@ -338,7 +361,7 @@ int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size)
 
   result = usb_control_msg(dfu->dev_handle,
     USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_DNLOAD, wIndex++, 0,
-    ptr, size, DFU_TIMEOUT);
+    ptr, size, dfu->timeout);
 
   if (result < 0) {
     fprintf(stderr, "%s: Error: DFU_DNLOAD failed: %s\n",
@@ -372,7 +395,7 @@ int dfu_upload(struct dfu_dev *dfu, void *ptr, int size)
 
   result = usb_control_msg(dfu->dev_handle,
     0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_UPLOAD, wIndex++, 0,
-    ptr, size, DFU_TIMEOUT);
+    ptr, size, dfu->timeout);
 
   if (result < 0) {
     fprintf(stderr, "%s: Error: DFU_UPLOAD failed: %s\n",
@@ -442,8 +465,8 @@ char * get_usb_string(usb_dev_handle * dev_handle, int index) {
   str = malloc(result+1);
 
   if (str == NULL) {
-    perror(progname);
-    exit(1);
+    fprintf(stderr, "%s: Out of memory allocating a string\n", progname);
+    return 0;
   }
 
   memcpy(str, buffer, result);
diff --git a/dfu.h b/dfu.h
index 5dc6b7f6..020a75f2 100644
--- a/dfu.h
+++ b/dfu.h
@@ -24,7 +24,13 @@
 #include "ac_cfg.h"
 
 #ifdef HAVE_LIBUSB
-#include <usb.h>
+#if defined(HAVE_USB_H)
+#  include <usb.h>
+#elif defined(HAVE_LUSB0_USB_H)
+#  include <lusb0_usb.h>
+#else
+#  error "libusb needs either <usb.h> or <lusb0_usb.h>"
+#endif
 #endif
 
 #include <limits.h>
@@ -49,6 +55,7 @@ struct dfu_dev
   struct usb_interface_descriptor intf_desc;
   struct usb_endpoint_descriptor endp_desc;
   char *manf_str, *prod_str, *serno_str;
+  unsigned int timeout;
 };
 
 #else
@@ -116,6 +123,7 @@ extern int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status);
 extern int dfu_clrstatus(struct dfu_dev *dfu);
 extern int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size);
 extern int dfu_upload(struct dfu_dev *dfu, void *ptr, int size);
+extern int dfu_abort(struct dfu_dev *dfu);
 
 extern void dfu_show_info(struct dfu_dev *dfu);
 
diff --git a/flip2.c b/flip2.c
index 4bbeefe5..fae88554 100644
--- a/flip2.c
+++ b/flip2.c
@@ -142,8 +142,6 @@ static int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   unsigned long addr, unsigned char *value);
 static int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   unsigned long addr, unsigned char value);
-static int flip2_page_erase(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
-  unsigned int base_addr);
 static int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
 static int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
@@ -188,7 +186,6 @@ void flip2_initpgm(PROGRAMMER *pgm)
   pgm->chip_erase       = flip2_chip_erase;
   pgm->open             = flip2_open;
   pgm->close            = flip2_close;
-  pgm->page_erase       = flip2_page_erase;
   pgm->paged_load       = flip2_paged_load;
   pgm->paged_write      = flip2_paged_write;
   pgm->read_byte        = flip2_read_byte;
@@ -428,12 +425,6 @@ int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   return flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, &value, 1);
 }
 
-int flip2_page_erase(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
-  unsigned int base_addr)
-{
-  return 0;
-}
-
 int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
 {
@@ -522,7 +513,8 @@ void flip2_setup(PROGRAMMER * pgm)
   pgm->cookie = calloc(1, sizeof(struct flip2));
 
   if (pgm->cookie == NULL) {
-    perror(progname);
+    fprintf(stderr, "%s: Out of memory allocating private data structure\n",
+            progname);
     exit(1);
   }
 }