diff options
author | Tom Rini <trini@ti.com> | 2013-12-18 15:06:43 -0500 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-12-18 15:06:43 -0500 |
commit | 2d65256bb0ea105eb11e30c1beb6da121b719f06 (patch) | |
tree | d3c16ff19eb900017d4c7df201df11f8e31f2372 | |
parent | 57270260adc6076facd284107be463f9beebb153 (diff) | |
parent | eb63218b9b95a59baa8b241f3a88e4415dabf833 (diff) | |
download | u-boot-imx-2d65256bb0ea105eb11e30c1beb6da121b719f06.zip u-boot-imx-2d65256bb0ea105eb11e30c1beb6da121b719f06.tar.gz u-boot-imx-2d65256bb0ea105eb11e30c1beb6da121b719f06.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-usb
-rw-r--r-- | drivers/dfu/dfu.c | 5 | ||||
-rw-r--r-- | drivers/usb/gadget/f_dfu.c | 43 | ||||
-rw-r--r-- | drivers/usb/gadget/f_dfu.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 28 | ||||
-rw-r--r-- | include/configs/trats.h | 1 | ||||
-rw-r--r-- | include/dfu.h | 4 |
7 files changed, 79 insertions, 9 deletions
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 1eb92e5..07011e9 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -74,6 +74,11 @@ unsigned char *dfu_free_buf(void) return dfu_buf; } +unsigned long dfu_get_buf_size(void) +{ + return dfu_buf_size; +} + unsigned char *dfu_get_buf(void) { char *s; diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 37d04a1..a045864 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -40,6 +40,7 @@ struct f_dfu { /* Send/received block number is handy for data integrity check */ int blk_seq_num; + unsigned int poll_timeout; }; typedef int (*dfu_state_fn) (struct f_dfu *, @@ -128,6 +129,33 @@ static struct usb_gadget_strings *dfu_strings[] = { NULL, }; +static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms) +{ + /* + * The bwPollTimeout DFU_GETSTATUS request payload provides information + * about minimum time, in milliseconds, that the host should wait before + * sending a subsequent DFU_GETSTATUS request + * + * This permits the device to vary the delay depending on its need to + * erase or program the memory + * + */ + + unsigned char *p = (unsigned char *)&ms; + + if (!ms || (ms & ~DFU_POLL_TIMEOUT_MASK)) { + dstat->bwPollTimeout[0] = 0; + dstat->bwPollTimeout[1] = 0; + dstat->bwPollTimeout[2] = 0; + + return; + } + + dstat->bwPollTimeout[0] = *p++; + dstat->bwPollTimeout[1] = *p++; + dstat->bwPollTimeout[2] = *p; +} + /*-------------------------------------------------------------------------*/ static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req) @@ -157,11 +185,15 @@ static void handle_getstatus(struct usb_request *req) break; } + dfu_set_poll_timeout(dstat, 0); + + if (f_dfu->poll_timeout) + if (!(f_dfu->blk_seq_num % + (dfu_get_buf_size() / DFU_USB_BUFSIZ))) + dfu_set_poll_timeout(dstat, f_dfu->poll_timeout); + /* send status response */ dstat->bStatus = f_dfu->dfu_status; - dstat->bwPollTimeout[0] = 0; - dstat->bwPollTimeout[1] = 0; - dstat->bwPollTimeout[2] = 0; dstat->bState = f_dfu->dfu_state; dstat->iString = 0; } @@ -723,8 +755,9 @@ static int dfu_bind_config(struct usb_configuration *c) f_dfu->usb_function.unbind = dfu_unbind; f_dfu->usb_function.set_alt = dfu_set_alt; f_dfu->usb_function.disable = dfu_disable; - f_dfu->usb_function.strings = dfu_generic_strings, - f_dfu->usb_function.setup = dfu_handle, + f_dfu->usb_function.strings = dfu_generic_strings; + f_dfu->usb_function.setup = dfu_handle; + f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT; status = usb_add_function(c, &f_dfu->usb_function); if (status) diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c455..0c29954 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor { __le16 wTransferSize; __le16 bcdDFUVersion; } __packed; + +#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL) #endif /* __F_DFU_H_ */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8bd1eb8..17187ca 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -201,6 +201,9 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl) int i, ret = 0; uint32_t cmd, reg; + if (!ctrl || !ctrl->hcor) + return -EINVAL; + cmd = ehci_readl(&ctrl->hcor->or_usbcmd); cmd &= ~(CMD_PSE | CMD_ASE); ehci_writel(&ctrl->hcor->or_usbcmd, cmd); @@ -945,7 +948,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) #endif /* Set the high address word (aka segment) for 64-bit controller */ if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1) - ehci_writel(ehcic[index].hcor->or_ctrldssegment, 0); + ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0); qh_list = &ehcic[index].qh_list; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 7a1ffe5..991b199 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -54,9 +54,31 @@ static pci_dev_t ehci_find_class(int index) bdf += PCI_BDF(0, 0, 1)) { pci_read_config_dword(bdf, PCI_CLASS_REVISION, &class); - if ((class >> 8 == PCI_CLASS_SERIAL_USB_EHCI) - && !index--) - return bdf; + class >>= 8; + /* + * Here be dragons! In case we have multiple + * PCI EHCI controllers, this function will + * be called multiple times as well. This + * function will scan the PCI busses, always + * starting from bus 0, device 0, function 0, + * until it finds an USB controller. The USB + * stack gives us an 'index' of a controller + * that is currently being registered, which + * is a number, starting from 0 and growing + * in ascending order as controllers are added. + * To avoid probing the same controller in tne + * subsequent runs of this function, we will + * skip 'index - 1' detected controllers and + * report the index'th controller. + */ + if (class != PCI_CLASS_SERIAL_USB_EHCI) + continue; + if (index) { + index--; + continue; + } + /* Return index'th controller. */ + return bdf; } } } diff --git a/include/configs/trats.h b/include/configs/trats.h index 0877142..6cd15c2 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -99,6 +99,7 @@ #define CONFIG_THOR_FUNCTION #define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M +#define DFU_DEFAULT_POLL_TIMEOUT 300 #define CONFIG_DFU_FUNCTION #define CONFIG_DFU_MMC diff --git a/include/dfu.h b/include/dfu.h index cc14044..f973426 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -77,6 +77,9 @@ static inline unsigned int get_mmc_blk_size(int dev) #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE #endif +#ifndef DFU_DEFAULT_POLL_TIMEOUT +#define DFU_DEFAULT_POLL_TIMEOUT 0 +#endif struct dfu_entity { char name[DFU_NAME_SIZE]; @@ -131,6 +134,7 @@ bool dfu_reset(void); int dfu_init_env_entities(char *interface, int dev); unsigned char *dfu_get_buf(void); unsigned char *dfu_free_buf(void); +unsigned long dfu_get_buf_size(void); 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); |