Merge branch 'master' of git://git.denx.de/u-boot-usb

This commit is contained in:
Tom Rini 2013-12-18 15:06:43 -05:00
commit 2d65256bb0
7 changed files with 79 additions and 9 deletions

View File

@ -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;

View File

@ -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)

View File

@ -82,4 +82,6 @@ struct dfu_function_descriptor {
__le16 wTransferSize;
__le16 bcdDFUVersion;
} __packed;
#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL)
#endif /* __F_DFU_H_ */

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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);