Merge branch 'master' of git://git.denx.de/u-boot-usb
diff --git a/cmd/dfu.c b/cmd/dfu.c
index 6d95ce9..d8aae26 100644
--- a/cmd/dfu.c
+++ b/cmd/dfu.c
@@ -79,6 +79,26 @@
 		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);
 	}
diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
index b9c9a84..36734e2 100644
--- a/drivers/usb/eth/usb_ether.c
+++ b/drivers/usb/eth/usb_ether.c
@@ -73,7 +73,7 @@
 	}
 
 	ueth->rxsize = rxsize;
-	ueth->rxbuf = memalign(rxsize, ARCH_DMA_MINALIGN);
+	ueth->rxbuf = memalign(ARCH_DMA_MINALIGN, rxsize);
 	if (!ueth->rxbuf)
 		return -ENOMEM;
 
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index 77a1567..7d88008 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -44,6 +44,8 @@
 	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 *,
@@ -167,14 +169,7 @@
 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)
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 87e54eb..a54b4ee 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -382,7 +382,7 @@
 
 	strsep(&cmd, ":");
 	if (!cmd) {
-		error("missing variable\n");
+		error("missing variable");
 		fastboot_tx_write_str("FAILmissing var");
 		return;
 	}
@@ -413,7 +413,7 @@
 		else
 			strcpy(response, "FAILValue not set");
 	} else {
-		error("unknown variable: %s\n", cmd);
+		printf("WARNING: unknown variable: %s\n", cmd);
 		strcpy(response, "FAILVariable not implemented");
 	}
 	fastboot_tx_write_str(response);
@@ -561,7 +561,7 @@
 
 	strsep(&cmd, ":");
 	if (!cmd) {
-		error("missing partition name\n");
+		error("missing partition name");
 		fastboot_tx_write_str("FAILmissing partition name");
 		return;
 	}
@@ -683,7 +683,7 @@
 	}
 
 	if (!func_cb) {
-		error("unknown command: %s\n", cmdbuf);
+		error("unknown command: %s", cmdbuf);
 		fastboot_tx_write_str("FAILunknown command");
 	} else {
 		if (req->actual < req->length) {
@@ -691,7 +691,7 @@
 			buf[req->actual] = 0;
 			func_cb(ep, req);
 		} else {
-			error("buffer overflow\n");
+			error("buffer overflow");
 			fastboot_tx_write_str("FAILbuffer overflow");
 		}
 	}
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 84114c5..4444988 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <clk.h>
+#include <asm/io.h>
 #include <dm.h>
 #include "ehci.h"
 
@@ -20,7 +21,7 @@
 
 static int ehci_usb_probe(struct udevice *dev)
 {
-	struct ehci_hccr *hccr = (struct ehci_hccr *)dev_get_addr(dev);
+	struct ehci_hccr *hccr;
 	struct ehci_hcor *hcor;
 	int i;
 
@@ -36,6 +37,7 @@
 			       clk_dev->name, clk_id);
 	}
 
+	hccr = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
 	hcor = (struct ehci_hcor *)((uintptr_t)hccr +
 				    HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c664b16..8f259be 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -134,6 +134,8 @@
 	tmp |= USBMODE_CM_HC;
 #if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
 	tmp |= USBMODE_BE;
+#else
+	tmp &= ~USBMODE_BE;
 #endif
 	ehci_writel(reg_ptr, tmp);
 }
@@ -245,7 +247,7 @@
 
 	idx = 0;
 	while (idx < QT_BUFFER_CNT) {
-		td->qt_buffer[idx] = cpu_to_hc32(addr);
+		td->qt_buffer[idx] = cpu_to_hc32(virt_to_phys((void *)addr));
 		td->qt_buffer_hi[idx] = 0;
 		next = (addr + EHCI_PAGE_SIZE) & ~(EHCI_PAGE_SIZE - 1);
 		delta = next - addr;
@@ -398,7 +400,7 @@
 	 *   qh_overlay.qt_next ...... 13-10 H
 	 * - qh_overlay.qt_altnext
 	 */
-	qh->qh_link = cpu_to_hc32((unsigned long)&ctrl->qh_list | QH_LINK_TYPE_QH);
+	qh->qh_link = cpu_to_hc32(virt_to_phys(&ctrl->qh_list) | QH_LINK_TYPE_QH);
 	c = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe);
 	maxpacket = usb_maxpacket(dev, pipe);
 	endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
@@ -415,7 +417,6 @@
 	qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 
 	tdp = &qh->qh_overlay.qt_next;
-
 	if (req != NULL) {
 		/*
 		 * Setup request qTD (3.5 in ehci-r10.pdf)
@@ -438,7 +439,7 @@
 			goto fail;
 		}
 		/* Update previous qTD! */
-		*tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]);
+		*tdp = cpu_to_hc32(virt_to_phys(&qtd[qtd_counter]));
 		tdp = &qtd[qtd_counter++].qt_next;
 		toggle = 1;
 	}
@@ -497,7 +498,7 @@
 				goto fail;
 			}
 			/* Update previous qTD! */
-			*tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]);
+			*tdp = cpu_to_hc32(virt_to_phys(&qtd[qtd_counter]));
 			tdp = &qtd[qtd_counter++].qt_next;
 			/*
 			 * Data toggle has to be adjusted since the qTD transfer
@@ -528,11 +529,11 @@
 			QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
 		qtd[qtd_counter].qt_token = cpu_to_hc32(token);
 		/* Update previous qTD! */
-		*tdp = cpu_to_hc32((unsigned long)&qtd[qtd_counter]);
+		*tdp = cpu_to_hc32(virt_to_phys(&qtd[qtd_counter]));
 		tdp = &qtd[qtd_counter++].qt_next;
 	}
 
-	ctrl->qh_list.qh_link = cpu_to_hc32((unsigned long)qh | QH_LINK_TYPE_QH);
+	ctrl->qh_list.qh_link = cpu_to_hc32(virt_to_phys(qh) | QH_LINK_TYPE_QH);
 
 	/* Flush dcache */
 	flush_dcache_range((unsigned long)&ctrl->qh_list,
@@ -542,7 +543,7 @@
 			   ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
 
 	/* Set async. queue head pointer. */
-	ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)&ctrl->qh_list);
+	ehci_writel(&ctrl->hcor->or_asynclistaddr, virt_to_phys(&ctrl->qh_list));
 
 	usbsts = ehci_readl(&ctrl->hcor->or_usbsts);
 	ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f));
@@ -989,7 +990,7 @@
 
 	/* Set head of reclaim list */
 	memset(qh_list, 0, sizeof(*qh_list));
-	qh_list->qh_link = cpu_to_hc32((unsigned long)qh_list | QH_LINK_TYPE_QH);
+	qh_list->qh_link = cpu_to_hc32(virt_to_phys(qh_list) | QH_LINK_TYPE_QH);
 	qh_list->qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) |
 						QH_ENDPT1_EPS(USB_SPEED_HIGH));
 	qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -1001,7 +1002,7 @@
 			   ALIGN_END_ADDR(struct QH, qh_list, 1));
 
 	/* Set async. queue head pointer. */
-	ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)qh_list);
+	ehci_writel(&ctrl->hcor->or_asynclistaddr, virt_to_phys(qh_list));
 
 	/*
 	 * Set up periodic list
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index b41c04a..826b3fe 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -102,8 +102,9 @@
 } __attribute__ ((packed));
 
 #if defined CONFIG_EHCI_DESC_BIG_ENDIAN
-#define	ehci_readl(x)		(*((volatile u32 *)(x)))
-#define ehci_writel(a, b)	(*((volatile u32 *)(a)) = ((volatile u32)b))
+#define ehci_readl(x)		cpu_to_be32((*((volatile u32 *)(x))))
+#define ehci_writel(a, b)	(*((volatile u32 *)(a)) = \
+					cpu_to_be32(((volatile u32)b)))
 #else
 #define ehci_readl(x)		cpu_to_le32((*((volatile u32 *)(x))))
 #define ehci_writel(a, b)	(*((volatile u32 *)(a)) = \
diff --git a/include/configs/bcm28155_ap.h b/include/configs/bcm28155_ap.h
index a257084..c9515a8 100644
--- a/include/configs/bcm28155_ap.h
+++ b/include/configs/bcm28155_ap.h
@@ -130,7 +130,6 @@
 #define CONFIG_CMD_BOOTZ
 #define CONFIG_FAT_WRITE
 
-
 /* Fastboot and USB OTG */
 #define CONFIG_USB_FUNCTION_FASTBOOT
 #define CONFIG_CMD_FASTBOOT
@@ -150,23 +149,4 @@
 #define CONFIG_G_DNL_PRODUCT_NUM	0x0d02	/* nexus one */
 #define CONFIG_G_DNL_MANUFACTURER	"Broadcom Corporation"
 
-/* Fastboot and USB OTG */
-#define CONFIG_USB_FUNCTION_FASTBOOT
-#define CONFIG_CMD_FASTBOOT
-#define CONFIG_FASTBOOT_FLASH
-#define CONFIG_FASTBOOT_FLASH_MMC_DEV	0
-#define CONFIG_SYS_CACHELINE_SIZE	64
-#define CONFIG_USB_FASTBOOT_BUF_SIZE	(CONFIG_SYS_SDRAM_SIZE - SZ_1M)
-#define CONFIG_USB_FASTBOOT_BUF_ADDR	CONFIG_SYS_SDRAM_BASE
-#define CONFIG_USB_GADGET
-#define CONFIG_USB_GADGET_DUALSPEED
-#define CONFIG_USB_GADGET_VBUS_DRAW	0
-#define CONFIG_USB_GADGET_S3C_UDC_OTG
-#define CONFIG_USB_GADGET_BCM_UDC_OTG_PHY
-#define CONFIG_USB_GADGET_DOWNLOAD
-#define CONFIG_USBID_ADDR		0x34052c46
-#define CONFIG_G_DNL_VENDOR_NUM		0x18d1	/* google */
-#define CONFIG_G_DNL_PRODUCT_NUM	0x0d02	/* nexus one */
-#define CONFIG_G_DNL_MANUFACTURER	"Broadcom Corporation"
-
 #endif /* __BCM28155_AP_H */
diff --git a/include/configs/odroid_xu3.h b/include/configs/odroid_xu3.h
index 648e48b..500f0f9 100644
--- a/include/configs/odroid_xu3.h
+++ b/include/configs/odroid_xu3.h
@@ -69,6 +69,7 @@
 #define CONFIG_CMD_DFU
 #define CONFIG_SYS_DFU_DATA_BUF_SIZE	SZ_32M
 #define DFU_DEFAULT_POLL_TIMEOUT	300
+#define DFU_MANIFEST_POLL_TIMEOUT       25000
 
 /* THOR */
 #define CONFIG_G_DNL_THOR_VENDOR_NUM	CONFIG_G_DNL_VENDOR_NUM
diff --git a/include/dfu.h b/include/dfu.h
index 6118dc2..f39d3f1 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -163,6 +163,31 @@
 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
  *