+static int noct_error_handler(struct main_hook *h)
+{
+ DBG("Noct: Entered error handling hook");
+ hook_del(h);
+
+ if (usb_dev)
+ {
+ if (noct_read_xfer)
+ {
+ if (noct_read_pending)
+ {
+ DBG("Noct: Cancelling pending read");
+ libusb_cancel_transfer(noct_read_xfer);
+ noct_read_pending = 0;
+ }
+ DBG("Noct: Tearing down read xfer");
+ libusb_free_transfer(noct_read_xfer);
+ noct_read_xfer = NULL;
+ }
+ if (noct_write_xfer)
+ {
+ if (noct_write_pending)
+ {
+ DBG("Noct: Cancelling pending write");
+ libusb_cancel_transfer(noct_write_xfer);
+ noct_write_pending = 0;
+ }
+ DBG("Noct: Tearing down write xfer");
+ libusb_free_transfer(noct_write_xfer);
+ noct_write_xfer = NULL;
+ }
+ if (usb_iface_claimed)
+ {
+ DBG("Noct: Unclaiming interface");
+ libusb_release_interface(usb_dev, 0);
+ usb_iface_claimed = 0;
+ }
+ DBG("Noct: Resetting device");
+ libusb_reset_device(usb_dev);
+ libusb_close(usb_dev);
+ usb_dev = NULL;
+ }
+
+ DBG("Noct: Scheduling rescan after error");
+ timer_add_rel(&noct_connect_timer, 3000);
+
+ return HOOK_IDLE;
+}
+
+static void noct_error(int usb_err, char *text)
+{
+ if (usb_err)
+ msg(L_ERROR, "Nocturn: %s: error %d (%s)", text, usb_err, libusb_error_name(usb_err));
+ else
+ msg(L_ERROR, "Nocturn: %s", text);
+
+ DBG("Noct: Scheduling error handling hook");
+ hook_add(&noct_error_hook);
+}
+