if (ctrlc())
goto exit;
+ if (dfu_get_defer_flush()) {
+ /*
+ * Call to usb_gadget_handle_interrupts() is necessary
+ * to act on ZLP OUT transaction from HOST PC after
+ * transmitting the whole file.
+ *
+ * If this ZLP OUT packet is NAK'ed, the HOST libusb
+ * function fails after timeout (by default it is set to
+ * 5 seconds). In such situation the dfu-util program
+ * exits with error message.
+ */
+ usb_gadget_handle_interrupts(controller_index);
+ ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0);
+ dfu_set_defer_flush(NULL);
+ if (ret) {
+ error("Deferred dfu_flush() failed!");
+ goto exit;
+ }
+ }
+
WATCHDOG_RESET();
usb_gadget_handle_interrupts(controller_index);
}
unsigned int poll_timeout;
};
+struct dfu_entity *dfu_defer_flush;
+
typedef int (*dfu_state_fn) (struct f_dfu *,
const struct usb_ctrlrequest *,
struct usb_gadget *,
static void dnload_request_flush(struct usb_ep *ep, struct usb_request *req)
{
struct f_dfu *f_dfu = req->context;
- int ret;
-
- ret = dfu_flush(dfu_get_entity(f_dfu->altsetting), req->buf,
- req->length, f_dfu->blk_seq_num);
- if (ret) {
- f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
- f_dfu->dfu_state = DFU_STATE_dfuERROR;
- }
+ dfu_set_defer_flush(dfu_get_entity(f_dfu->altsetting));
}
static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu)
int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
+/*
+ * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
+ * It should be NULL when not used.
+ */
+extern struct dfu_entity *dfu_defer_flush;
+/**
+ * dfu_get_defer_flush - get current value of dfu_defer_flush pointer
+ *
+ * @return - value of the dfu_defer_flush pointer
+ */
+static inline struct dfu_entity *dfu_get_defer_flush(void)
+{
+ return dfu_defer_flush;
+}
+
+/**
+ * dfu_set_defer_flush - set the dfu_defer_flush pointer
+ *
+ * @param dfu - pointer to the dfu_entity, which should be written
+ */
+static inline void dfu_set_defer_flush(struct dfu_entity *dfu)
+{
+ dfu_defer_flush = dfu;
+}
+
/**
* dfu_write_from_mem_addr - write data from memory to DFU managed medium
*