diff options
author | Tom Rini | 2016-02-24 14:26:20 -0500 |
---|---|---|
committer | Tom Rini | 2016-02-24 18:44:17 -0500 |
commit | fec26e7270ad31e4179d1bd189e5cd8ab93ccba3 (patch) | |
tree | 6a24a5af8d3c40956db407177e945493fd6a1ce3 | |
parent | e1417c7b66f4e0051a3aa242f655e85c1c96eef2 (diff) | |
parent | d7d8c00575c8ae766d387c763395470410427b69 (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-usb
-rw-r--r-- | cmd/dfu.c | 20 | ||||
-rw-r--r-- | drivers/usb/eth/usb_ether.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/f_dfu.c | 11 | ||||
-rw-r--r-- | drivers/usb/gadget/f_fastboot.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/ehci-generic.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 5 | ||||
-rw-r--r-- | include/configs/bcm28155_ap.h | 20 | ||||
-rw-r--r-- | include/configs/odroid_xu3.h | 1 | ||||
-rw-r--r-- | include/dfu.h | 25 |
10 files changed, 72 insertions, 47 deletions
diff --git a/cmd/dfu.c b/cmd/dfu.c index 6d95ce92231..d8aae262232 100644 --- a/cmd/dfu.c +++ b/cmd/dfu.c @@ -79,6 +79,26 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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 b9c9a8402e3..36734e2e51b 100644 --- a/drivers/usb/eth/usb_ether.c +++ b/drivers/usb/eth/usb_ether.c @@ -73,7 +73,7 @@ int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize) } 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 77a1567a944..7d88008f74e 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -44,6 +44,8 @@ struct f_dfu { 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_complete(struct usb_ep *ep, struct usb_request *req) 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 87e54ebec76..a54b4eebcca 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -382,7 +382,7 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) strsep(&cmd, ":"); if (!cmd) { - error("missing variable\n"); + error("missing variable"); fastboot_tx_write_str("FAILmissing var"); return; } @@ -413,7 +413,7 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) 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 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req) 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 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) } 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 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) 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 84114c5df98..4444988e36f 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 @@ struct generic_ehci { 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 @@ static int ehci_usb_probe(struct udevice *dev) 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 c664b1629e0..8f259bee4f0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -134,6 +134,8 @@ static void ehci_set_usbmode(struct ehci_ctrl *ctrl) 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 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) 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 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, * 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 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, 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 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, 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 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, 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 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, 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 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, 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 @@ static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks) /* 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 @@ static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks) 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 b41c04a8b30..826b3fe5808 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -102,8 +102,9 @@ struct usb_linux_config_descriptor { } __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 a257084a03c..c9515a8cb8f 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 648e48bcf4b..500f0f9d4f9 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 6118dc27b95..f39d3f1171a 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -163,6 +163,31 @@ int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); 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 * |