From e7e75c70c5d5d3365606c4a76adb7ff4822d2f75 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 12 Jun 2013 06:05:51 +0200 Subject: dfu: make data buffer size configurable Dfu transfer uses a buffer before writing data to the raw storage device. Make the size (in bytes) of this buffer configurable through environment variable "dfu_bufsiz". Defaut value is configurable through CONFIG_SYS_DFU_DATA_BUF_SIZE Signed-off-by: Heiko Schocher Cc: Pantelis Antoniou Cc: Tom Rini Cc: Lukasz Majewski Cc: Kyungmin Park Cc: Marek Vasut Cc: Wolfgang Denk Acked-by: Tom Rini diff --git a/README b/README index 5c343da..85e5a8d 100644 --- a/README +++ b/README @@ -1392,6 +1392,12 @@ The following options need to be configured: CONFIG_DFU_NAND 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 When updating files rather than the raw storage device, we use a static buffer to copy the file into and then write diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 6af6890..e429d74 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -41,8 +42,34 @@ static int dfu_find_alt_num(const char *s) return ++i; } -static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) - dfu_buf[DFU_DATA_BUF_SIZE]; +static unsigned char *dfu_buf; +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) { @@ -87,8 +114,10 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) dfu->offset = 0; dfu->bad_skip = 0; dfu->i_blk_seq_num = 0; - dfu->i_buf_start = dfu_buf; - dfu->i_buf_end = dfu_buf + sizeof(dfu_buf); + dfu->i_buf_start = dfu_get_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->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); /* clear everything */ + dfu_free_buf(); dfu->crc = 0; dfu->offset = 0; dfu->i_blk_seq_num = 0; 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->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->crc = 0; dfu->offset = 0; - dfu->i_buf_start = dfu_buf; - dfu->i_buf_end = dfu_buf + sizeof(dfu_buf); + dfu->i_buf_start = dfu_get_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->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); puts("\nUPLOAD ... done\nCtrl+C to exit ...\n"); + dfu_free_buf(); dfu->i_blk_seq_num = 0; dfu->crc = 0; dfu->offset = 0; 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->b_left = 0; diff --git a/include/dfu.h b/include/dfu.h index a107f4b..124653c 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -68,7 +68,9 @@ static inline unsigned int get_mmc_blk_size(int dev) #define DFU_NAME_SIZE 32 #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 #define CONFIG_SYS_DFU_MAX_FILE_SIZE (4 << 20) /* 4 MiB */ #endif -- cgit v0.10.2 From 7f3cf4060fe8e93d785581ea2047929c1cb15a18 Mon Sep 17 00:00:00 2001 From: Piotr Wilczek Date: Wed, 26 Jun 2013 08:22:05 +0200 Subject: drivers:usb: use get|put_unaligned_le16 This patch use get|put_unaligned_le16 to access structure data to avoid data abort on some ARM platforms. Signed-off-by: Piotr Wilczek Signed-off-by: Kyungmin Park CC: Marek Vasut diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 45bc132..5b348d7 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -577,9 +577,9 @@ static int fsg_setup(struct usb_function *f, { struct fsg_dev *fsg = fsg_from_func(f); struct usb_request *req = fsg->common->ep0req; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); + u16 w_index = get_unaligned_le16(&ctrl->wIndex); + u16 w_value = get_unaligned_le16(&ctrl->wValue); + u16 w_length = get_unaligned_le16(&ctrl->wLength); if (!fsg_is_set(fsg->common)) return -EOPNOTSUPP; @@ -617,7 +617,7 @@ static int fsg_setup(struct usb_function *f, "unknown class-specific control req " "%02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, - le16_to_cpu(ctrl->wValue), w_index, w_length); + get_unaligned_le16(&ctrl->wValue), w_index, w_length); return -EOPNOTSUPP; } -- cgit v0.10.2 From 12595e99e40ba4d0a08744e375f4e2144dc5acb6 Mon Sep 17 00:00:00 2001 From: Piotr Wilczek Date: Wed, 10 Apr 2013 14:07:51 +0200 Subject: usb:composite: use memcpy to avoid unaligned access This patch memcpy is used instead of an assignment to avoid unaligned access execption on some ARM platforms. Signed-off-by: Piotr Wilczek Signed-off-by: Kyungmin Park CC: Lukasz Majewski Tested-by: Heiko Schocher Acked-by: Heiko Schocher diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f30778a..f867793 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -997,7 +997,8 @@ static int composite_bind(struct usb_gadget *gadget) if (status < 0) goto fail; - cdev->desc = *composite->dev; + memcpy(&cdev->desc, composite->dev, + sizeof(struct usb_device_descriptor)); cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; debug("%s: ready\n", composite->name); -- cgit v0.10.2 From ad5f9778896534d9eae0c7499bcf5386e675257e Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 25 Jun 2013 13:59:29 +0200 Subject: usb, dfu gadget: switch to dfu mode in dfu_bind - set in to_dfu_mode() f_dfu->dfu_state = DFU_STATE_dfuIDLE as after every to_dfu_mode call this is done, so move this into to_dfu_mode - switch in dfu_bind() into dfu mode: This fixes wrong "dfu-util -l" output, when calling "dfu-util -l" after a board reset, without doing a download before. See also discussion here: http://lists.denx.de/pipermail/u-boot/2013-June/157272.html Signed-off-by: Heiko Schocher Cc: Lukasz Majewski Cc: Pantelis Antoniou Cc: Tom Rini Cc: Kyungmin Park Cc: Marek Vasut Cc: Wolfgang Denk Cc: Samuel Egli Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index a322ae5..178a004 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -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.hs_descriptors = f_dfu->function; + f_dfu->dfu_state = DFU_STATE_dfuIDLE; } 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: f_dfu->dfu_state = DFU_STATE_appDETACH; to_dfu_mode(f_dfu); - f_dfu->dfu_state = DFU_STATE_dfuIDLE; value = RET_ZLP; break; default: @@ -653,6 +653,8 @@ static int dfu_bind(struct usb_configuration *c, struct usb_function *f) ->iInterface = id; } + to_dfu_mode(f_dfu); + stringtab_dfu.strings = f_dfu->strings; cdev->req->context = f_dfu; -- cgit v0.10.2 From c5398cc968793cb73752d98e69f2e8d3cc9d9e59 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 4 Jun 2013 11:19:50 +0200 Subject: usb, g_dnl: make possibility to fixup the device_desc board specific add a weak dummy function g_dnl_fixup to add the possibility to update the device_desc board specific. Used on the upcoming siemens board support, where idVendor and idProduct is stored in an eeprom. Signed-off-by: Heiko Schocher Cc: Marek Vasut Cc: Lukasz Majewski Cc: Kyungmin Park Reviewed-by: Lukasz Majewski diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c index cc3f344..8a3777b 100644 --- a/drivers/usb/gadget/g_dnl.c +++ b/drivers/usb/gadget/g_dnl.c @@ -125,6 +125,12 @@ static int g_dnl_config_register(struct usb_composite_dev *cdev) 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) { 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; device_desc.iProduct = id; + g_dnl_bind_fixup(&device_desc); ret = g_dnl_config_register(cdev); if (ret) goto error; diff --git a/include/g_dnl.h b/include/g_dnl.h index f47395f..f8affd8 100644 --- a/include/g_dnl.h +++ b/include/g_dnl.h @@ -23,7 +23,7 @@ #include #include - +int g_dnl_bind_fixup(struct usb_device_descriptor *); int g_dnl_register(const char *s); void g_dnl_unregister(void); -- cgit v0.10.2 From 7a3427854243f0e28c102926d203709b3e3cee62 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 4 Jun 2013 11:10:01 +0200 Subject: usb, musb-new: add wdt trigger Signed-off-by: Heiko Schocher Cc: Marek Vasut Cc: Ilya Yanok diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index 15d2ec0..c240032 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -164,6 +165,7 @@ static struct musb *gadget; int usb_gadget_handle_interrupts(void) { + WATCHDOG_RESET(); if (!gadget || !gadget->isr) return -EINVAL; -- cgit v0.10.2 From e059a400ad780328cd5ad22c396298cac520c856 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Wed, 26 Jun 2013 11:46:13 +0200 Subject: dfu:function: Fix number of allocated DFU function pointers This subtle change fix problem with too small amount of allocated memory to store DFU function pointers. One needs to allocate extra space for sentinel NULL pointer in this array of function pointers. With the previous code, the NULL value overwrites malloc internal data and afterwards free(f_dfu->function) crashes. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 178a004..e3fa0e3 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -589,7 +589,7 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n) struct usb_interface_descriptor *d; 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) goto enomem; -- cgit v0.10.2 From b37c4a2baabc61450bb9f8bd16b233a25315c816 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Thu, 27 Jun 2013 10:04:57 +0200 Subject: usb: fix unaligned access in device_qual() while playing with dfu, I tapped in an unaligned access when doing on the host side a "lsusb -d [vendornr]: -v" I get on the board: GADGET DRIVER: usb_dnl_dfu data abort MAYBE you should read doc/README.arm-unaligned-accesses pc : [<8ff71db8>] lr : [<8ff75aec>] sp : 8ef40d18 ip : 00000005 fp : 00000000 r10: 00000000 r9 : 47401410 r8 : 8ef40f38 r7 : 8ef4aae8 r6 : 0000000a r5 : 8ef4ab28 r4 : 8ef4ab80 r3 : 0000000a r2 : 00000006 r1 : 00000006 r0 : 8ef4aae8 Flags: Nzcv IRQs off FIQs on Mode SVC_32 Resetting CPU ... reason is that in the "struct usb_composite_dev" the "struct usb_device_descriptor desc;" is on an odd address, and this struct gets accessed in drivers/usb/gadget/composite.c device_qual() Fix it, by align this var "struct desc" fix to an aligned address. Signed-off-by: Heiko Schocher Cc: Marek Vasut Cc: Samuel Egli diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 53cb095..4f76f88 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -331,7 +331,7 @@ struct usb_composite_dev { /* private: */ /* internals */ unsigned int suspended:1; - struct usb_device_descriptor desc; + struct usb_device_descriptor __aligned(CONFIG_SYS_CACHELINE_SIZE) desc; struct list_head configs; struct usb_composite_driver *driver; u8 next_string_id; -- cgit v0.10.2 From befd387242143ba0f7e298cfef6baf26c4260ec0 Mon Sep 17 00:00:00 2001 From: Pierre Aubert Date: Thu, 27 Jun 2013 09:01:54 +0200 Subject: usb: add support for the USB Ethernet adapter D-Link DUB-E100 H/W Ver C1 This trivial patch adds the definition of the vid/pid for the Ver C1 of the USB Ethernet adapter D-Link DUB-E100. Signed-off-by: Pierre Aubert CC: Marek Vasut diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 76624b9..db39bd8 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -585,6 +585,7 @@ struct asix_dongle { static const struct asix_dongle const asix_dongles[] = { { 0x05ac, 0x1402, FLAG_TYPE_AX88772 }, /* Apple USB Ethernet Adapter */ { 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 */ { 0x0b95, 0x772a, FLAG_TYPE_AX88772 }, { 0x0b95, 0x7720, FLAG_TYPE_AX88772 }, /* Trendnet TU2-ET100 V3.0R */ -- cgit v0.10.2