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

This commit is contained in:
Tom Rini
2013-07-03 08:40:58 -04:00
11 changed files with 72 additions and 18 deletions

6
README
View File

@@ -1392,6 +1392,12 @@ The following options need to be configured:
CONFIG_DFU_NAND CONFIG_DFU_NAND
This enables support for exposing NAND devices via DFU. This enables support for exposing NAND devices via DFU.
CONFIG_SYS_DFU_DATA_BUF_SIZE
Dfu transfer uses a buffer before writing data to the
raw storage device. Make the size (in bytes) of this buffer
configurable. The size of this buffer is also configurable
through the "dfu_bufsiz" environment variable.
CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_MAX_FILE_SIZE
When updating files rather than the raw storage device, When updating files rather than the raw storage device,
we use a static buffer to copy the file into and then write we use a static buffer to copy the file into and then write

View File

@@ -20,6 +20,7 @@
*/ */
#include <common.h> #include <common.h>
#include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <mmc.h> #include <mmc.h>
#include <fat.h> #include <fat.h>
@@ -41,8 +42,34 @@ static int dfu_find_alt_num(const char *s)
return ++i; return ++i;
} }
static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) static unsigned char *dfu_buf;
dfu_buf[DFU_DATA_BUF_SIZE]; static unsigned long dfu_buf_size = CONFIG_SYS_DFU_DATA_BUF_SIZE;
static unsigned char *dfu_free_buf(void)
{
free(dfu_buf);
dfu_buf = NULL;
return dfu_buf;
}
static unsigned char *dfu_get_buf(void)
{
char *s;
if (dfu_buf != NULL)
return dfu_buf;
s = getenv("dfu_bufsiz");
dfu_buf_size = s ? (unsigned long)simple_strtol(s, NULL, 16) :
CONFIG_SYS_DFU_DATA_BUF_SIZE;
dfu_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, dfu_buf_size);
if (dfu_buf == NULL)
printf("%s: Could not memalign 0x%lx bytes\n",
__func__, dfu_buf_size);
return dfu_buf;
}
static int dfu_write_buffer_drain(struct dfu_entity *dfu) static int dfu_write_buffer_drain(struct dfu_entity *dfu)
{ {
@@ -87,8 +114,10 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
dfu->offset = 0; dfu->offset = 0;
dfu->bad_skip = 0; dfu->bad_skip = 0;
dfu->i_blk_seq_num = 0; dfu->i_blk_seq_num = 0;
dfu->i_buf_start = dfu_buf; dfu->i_buf_start = dfu_get_buf();
dfu->i_buf_end = dfu_buf + sizeof(dfu_buf); if (dfu->i_buf_start == NULL)
return -ENOMEM;
dfu->i_buf_end = dfu_get_buf() + dfu_buf_size;
dfu->i_buf = dfu->i_buf_start; dfu->i_buf = dfu->i_buf_start;
dfu->inited = 1; dfu->inited = 1;
@@ -148,11 +177,12 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
printf("\nDFU complete CRC32: 0x%08x\n", dfu->crc); printf("\nDFU complete CRC32: 0x%08x\n", dfu->crc);
/* clear everything */ /* clear everything */
dfu_free_buf();
dfu->crc = 0; dfu->crc = 0;
dfu->offset = 0; dfu->offset = 0;
dfu->i_blk_seq_num = 0; dfu->i_blk_seq_num = 0;
dfu->i_buf_start = dfu_buf; dfu->i_buf_start = dfu_buf;
dfu->i_buf_end = dfu_buf + sizeof(dfu_buf); dfu->i_buf_end = dfu_buf;
dfu->i_buf = dfu->i_buf_start; dfu->i_buf = dfu->i_buf_start;
dfu->inited = 0; dfu->inited = 0;
@@ -229,8 +259,10 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
dfu->i_blk_seq_num = 0; dfu->i_blk_seq_num = 0;
dfu->crc = 0; dfu->crc = 0;
dfu->offset = 0; dfu->offset = 0;
dfu->i_buf_start = dfu_buf; dfu->i_buf_start = dfu_get_buf();
dfu->i_buf_end = dfu_buf + sizeof(dfu_buf); if (dfu->i_buf_start == NULL)
return -ENOMEM;
dfu->i_buf_end = dfu_get_buf() + dfu_buf_size;
dfu->i_buf = dfu->i_buf_start; dfu->i_buf = dfu->i_buf_start;
dfu->b_left = 0; dfu->b_left = 0;
@@ -257,11 +289,12 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
debug("%s: %s CRC32: 0x%x\n", __func__, dfu->name, dfu->crc); debug("%s: %s CRC32: 0x%x\n", __func__, dfu->name, dfu->crc);
puts("\nUPLOAD ... done\nCtrl+C to exit ...\n"); puts("\nUPLOAD ... done\nCtrl+C to exit ...\n");
dfu_free_buf();
dfu->i_blk_seq_num = 0; dfu->i_blk_seq_num = 0;
dfu->crc = 0; dfu->crc = 0;
dfu->offset = 0; dfu->offset = 0;
dfu->i_buf_start = dfu_buf; dfu->i_buf_start = dfu_buf;
dfu->i_buf_end = dfu_buf + sizeof(dfu_buf); dfu->i_buf_end = dfu_buf;
dfu->i_buf = dfu->i_buf_start; dfu->i_buf = dfu->i_buf_start;
dfu->b_left = 0; dfu->b_left = 0;

View File

@@ -585,6 +585,7 @@ struct asix_dongle {
static const struct asix_dongle const asix_dongles[] = { static const struct asix_dongle const asix_dongles[] = {
{ 0x05ac, 0x1402, FLAG_TYPE_AX88772 }, /* Apple USB Ethernet Adapter */ { 0x05ac, 0x1402, FLAG_TYPE_AX88772 }, /* Apple USB Ethernet Adapter */
{ 0x07d1, 0x3c05, FLAG_TYPE_AX88772 }, /* D-Link DUB-E100 H/W Ver B1 */ { 0x07d1, 0x3c05, FLAG_TYPE_AX88772 }, /* D-Link DUB-E100 H/W Ver B1 */
{ 0x2001, 0x1a02, FLAG_TYPE_AX88772 }, /* D-Link DUB-E100 H/W Ver C1 */
/* Cables-to-Go USB Ethernet Adapter */ /* Cables-to-Go USB Ethernet Adapter */
{ 0x0b95, 0x772a, FLAG_TYPE_AX88772 }, { 0x0b95, 0x772a, FLAG_TYPE_AX88772 },
{ 0x0b95, 0x7720, FLAG_TYPE_AX88772 }, /* Trendnet TU2-ET100 V3.0R */ { 0x0b95, 0x7720, FLAG_TYPE_AX88772 }, /* Trendnet TU2-ET100 V3.0R */

View File

@@ -997,7 +997,8 @@ static int composite_bind(struct usb_gadget *gadget)
if (status < 0) if (status < 0)
goto fail; goto fail;
cdev->desc = *composite->dev; memcpy(&cdev->desc, composite->dev,
sizeof(struct usb_device_descriptor));
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
debug("%s: ready\n", composite->name); debug("%s: ready\n", composite->name);

View File

@@ -183,6 +183,7 @@ static inline void to_dfu_mode(struct f_dfu *f_dfu)
{ {
f_dfu->usb_function.strings = dfu_strings; f_dfu->usb_function.strings = dfu_strings;
f_dfu->usb_function.hs_descriptors = f_dfu->function; f_dfu->usb_function.hs_descriptors = f_dfu->function;
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
} }
static inline void to_runtime_mode(struct f_dfu *f_dfu) static inline void to_runtime_mode(struct f_dfu *f_dfu)
@@ -233,7 +234,6 @@ static int state_app_idle(struct f_dfu *f_dfu,
case USB_REQ_DFU_DETACH: case USB_REQ_DFU_DETACH:
f_dfu->dfu_state = DFU_STATE_appDETACH; f_dfu->dfu_state = DFU_STATE_appDETACH;
to_dfu_mode(f_dfu); to_dfu_mode(f_dfu);
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
value = RET_ZLP; value = RET_ZLP;
break; break;
default: default:
@@ -589,7 +589,7 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n)
struct usb_interface_descriptor *d; struct usb_interface_descriptor *d;
int i = 0; int i = 0;
f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n); f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 1);
if (!f_dfu->function) if (!f_dfu->function)
goto enomem; goto enomem;
@@ -653,6 +653,8 @@ static int dfu_bind(struct usb_configuration *c, struct usb_function *f)
->iInterface = id; ->iInterface = id;
} }
to_dfu_mode(f_dfu);
stringtab_dfu.strings = f_dfu->strings; stringtab_dfu.strings = f_dfu->strings;
cdev->req->context = f_dfu; cdev->req->context = f_dfu;

View File

@@ -577,9 +577,9 @@ static int fsg_setup(struct usb_function *f,
{ {
struct fsg_dev *fsg = fsg_from_func(f); struct fsg_dev *fsg = fsg_from_func(f);
struct usb_request *req = fsg->common->ep0req; struct usb_request *req = fsg->common->ep0req;
u16 w_index = le16_to_cpu(ctrl->wIndex); u16 w_index = get_unaligned_le16(&ctrl->wIndex);
u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_value = get_unaligned_le16(&ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength); u16 w_length = get_unaligned_le16(&ctrl->wLength);
if (!fsg_is_set(fsg->common)) if (!fsg_is_set(fsg->common))
return -EOPNOTSUPP; return -EOPNOTSUPP;
@@ -617,7 +617,7 @@ static int fsg_setup(struct usb_function *f,
"unknown class-specific control req " "unknown class-specific control req "
"%02x.%02x v%04x i%04x l%u\n", "%02x.%02x v%04x i%04x l%u\n",
ctrl->bRequestType, ctrl->bRequest, ctrl->bRequestType, ctrl->bRequest,
le16_to_cpu(ctrl->wValue), w_index, w_length); get_unaligned_le16(&ctrl->wValue), w_index, w_length);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }

View File

@@ -125,6 +125,12 @@ static int g_dnl_config_register(struct usb_composite_dev *cdev)
return usb_add_config(cdev, &config); return usb_add_config(cdev, &config);
} }
__weak
int g_dnl_bind_fixup(struct usb_device_descriptor *dev)
{
return 0;
}
static int g_dnl_bind(struct usb_composite_dev *cdev) static int g_dnl_bind(struct usb_composite_dev *cdev)
{ {
struct usb_gadget *gadget = cdev->gadget; struct usb_gadget *gadget = cdev->gadget;
@@ -147,6 +153,7 @@ static int g_dnl_bind(struct usb_composite_dev *cdev)
g_dnl_string_defs[1].id = id; g_dnl_string_defs[1].id = id;
device_desc.iProduct = id; device_desc.iProduct = id;
g_dnl_bind_fixup(&device_desc);
ret = g_dnl_config_register(cdev); ret = g_dnl_config_register(cdev);
if (ret) if (ret)
goto error; goto error;

View File

@@ -1,4 +1,5 @@
#include <common.h> #include <common.h>
#include <watchdog.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
#include <linux/usb/gadget.h> #include <linux/usb/gadget.h>
@@ -164,6 +165,7 @@ static struct musb *gadget;
int usb_gadget_handle_interrupts(void) int usb_gadget_handle_interrupts(void)
{ {
WATCHDOG_RESET();
if (!gadget || !gadget->isr) if (!gadget || !gadget->isr)
return -EINVAL; return -EINVAL;

View File

@@ -68,7 +68,9 @@ static inline unsigned int get_mmc_blk_size(int dev)
#define DFU_NAME_SIZE 32 #define DFU_NAME_SIZE 32
#define DFU_CMD_BUF_SIZE 128 #define DFU_CMD_BUF_SIZE 128
#define DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */ #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */
#endif
#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
#define CONFIG_SYS_DFU_MAX_FILE_SIZE (4 << 20) /* 4 MiB */ #define CONFIG_SYS_DFU_MAX_FILE_SIZE (4 << 20) /* 4 MiB */
#endif #endif

View File

@@ -23,7 +23,7 @@
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
#include <linux/usb/gadget.h> #include <linux/usb/gadget.h>
int g_dnl_bind_fixup(struct usb_device_descriptor *);
int g_dnl_register(const char *s); int g_dnl_register(const char *s);
void g_dnl_unregister(void); void g_dnl_unregister(void);

View File

@@ -331,7 +331,7 @@ struct usb_composite_dev {
/* private: */ /* private: */
/* internals */ /* internals */
unsigned int suspended:1; unsigned int suspended:1;
struct usb_device_descriptor desc; struct usb_device_descriptor __aligned(CONFIG_SYS_CACHELINE_SIZE) desc;
struct list_head configs; struct list_head configs;
struct usb_composite_driver *driver; struct usb_composite_driver *driver;
u8 next_string_id; u8 next_string_id;