mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-18 05:07:00 +02:00
Merge branch 'master' of git://git.denx.de/u-boot-usb
This commit is contained in:
commit
2d65256bb0
@ -74,6 +74,11 @@ unsigned char *dfu_free_buf(void)
|
|||||||
return dfu_buf;
|
return dfu_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long dfu_get_buf_size(void)
|
||||||
|
{
|
||||||
|
return dfu_buf_size;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char *dfu_get_buf(void)
|
unsigned char *dfu_get_buf(void)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -40,6 +40,7 @@ struct f_dfu {
|
|||||||
|
|
||||||
/* Send/received block number is handy for data integrity check */
|
/* Send/received block number is handy for data integrity check */
|
||||||
int blk_seq_num;
|
int blk_seq_num;
|
||||||
|
unsigned int poll_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*dfu_state_fn) (struct f_dfu *,
|
typedef int (*dfu_state_fn) (struct f_dfu *,
|
||||||
@ -128,6 +129,33 @@ static struct usb_gadget_strings *dfu_strings[] = {
|
|||||||
NULL,
|
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)
|
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;
|
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 */
|
/* send status response */
|
||||||
dstat->bStatus = f_dfu->dfu_status;
|
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->bState = f_dfu->dfu_state;
|
||||||
dstat->iString = 0;
|
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.unbind = dfu_unbind;
|
||||||
f_dfu->usb_function.set_alt = dfu_set_alt;
|
f_dfu->usb_function.set_alt = dfu_set_alt;
|
||||||
f_dfu->usb_function.disable = dfu_disable;
|
f_dfu->usb_function.disable = dfu_disable;
|
||||||
f_dfu->usb_function.strings = dfu_generic_strings,
|
f_dfu->usb_function.strings = dfu_generic_strings;
|
||||||
f_dfu->usb_function.setup = dfu_handle,
|
f_dfu->usb_function.setup = dfu_handle;
|
||||||
|
f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;
|
||||||
|
|
||||||
status = usb_add_function(c, &f_dfu->usb_function);
|
status = usb_add_function(c, &f_dfu->usb_function);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -82,4 +82,6 @@ struct dfu_function_descriptor {
|
|||||||
__le16 wTransferSize;
|
__le16 wTransferSize;
|
||||||
__le16 bcdDFUVersion;
|
__le16 bcdDFUVersion;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL)
|
||||||
#endif /* __F_DFU_H_ */
|
#endif /* __F_DFU_H_ */
|
||||||
|
@ -201,6 +201,9 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl)
|
|||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
uint32_t cmd, reg;
|
uint32_t cmd, reg;
|
||||||
|
|
||||||
|
if (!ctrl || !ctrl->hcor)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
|
cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
|
||||||
cmd &= ~(CMD_PSE | CMD_ASE);
|
cmd &= ~(CMD_PSE | CMD_ASE);
|
||||||
ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
|
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
|
#endif
|
||||||
/* Set the high address word (aka segment) for 64-bit controller */
|
/* Set the high address word (aka segment) for 64-bit controller */
|
||||||
if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
|
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;
|
qh_list = &ehcic[index].qh_list;
|
||||||
|
|
||||||
|
@ -54,9 +54,31 @@ static pci_dev_t ehci_find_class(int index)
|
|||||||
bdf += PCI_BDF(0, 0, 1)) {
|
bdf += PCI_BDF(0, 0, 1)) {
|
||||||
pci_read_config_dword(bdf, PCI_CLASS_REVISION,
|
pci_read_config_dword(bdf, PCI_CLASS_REVISION,
|
||||||
&class);
|
&class);
|
||||||
if ((class >> 8 == PCI_CLASS_SERIAL_USB_EHCI)
|
class >>= 8;
|
||||||
&& !index--)
|
/*
|
||||||
return bdf;
|
* 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
#define CONFIG_THOR_FUNCTION
|
#define CONFIG_THOR_FUNCTION
|
||||||
|
|
||||||
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
|
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
|
||||||
|
#define DFU_DEFAULT_POLL_TIMEOUT 300
|
||||||
#define CONFIG_DFU_FUNCTION
|
#define CONFIG_DFU_FUNCTION
|
||||||
#define CONFIG_DFU_MMC
|
#define CONFIG_DFU_MMC
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@ static inline unsigned int get_mmc_blk_size(int dev)
|
|||||||
#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
|
#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
|
||||||
#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
|
#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DFU_DEFAULT_POLL_TIMEOUT
|
||||||
|
#define DFU_DEFAULT_POLL_TIMEOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
struct dfu_entity {
|
struct dfu_entity {
|
||||||
char name[DFU_NAME_SIZE];
|
char name[DFU_NAME_SIZE];
|
||||||
@ -131,6 +134,7 @@ bool dfu_reset(void);
|
|||||||
int dfu_init_env_entities(char *interface, int dev);
|
int dfu_init_env_entities(char *interface, int dev);
|
||||||
unsigned char *dfu_get_buf(void);
|
unsigned char *dfu_get_buf(void);
|
||||||
unsigned char *dfu_free_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_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_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
|
||||||
|
Loading…
Reference in New Issue
Block a user