projects
/
oweals
/
u-boot.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
common: spl_fit: Default to IH_OS_U_BOOT if FIT_IMAGE_TINY enabled
[oweals/u-boot.git]
/
drivers
/
usb
/
gadget
/
f_dfu.c
diff --git
a/drivers/usb/gadget/f_dfu.c
b/drivers/usb/gadget/f_dfu.c
index ead71eba6b136db95c9cd4b017ef2da6827872a4..30ece524a8e142eb1fd8662eb36bdea0b1d5b842 100644
(file)
--- a/
drivers/usb/gadget/f_dfu.c
+++ b/
drivers/usb/gadget/f_dfu.c
@@
-1,3
+1,4
@@
+// SPDX-License-Identifier: GPL-2.0+
/*
* f_dfu.c -- Device Firmware Update USB function
*
/*
* f_dfu.c -- Device Firmware Update USB function
*
@@
-11,8
+12,6
@@
*
* based on existing SAM7DFU code from OpenPCD:
* (C) Copyright 2006 by Harald Welte <hwelte at hmw-consulting.de>
*
* based on existing SAM7DFU code from OpenPCD:
* (C) Copyright 2006 by Harald Welte <hwelte at hmw-consulting.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <errno.h>
*/
#include <errno.h>
@@
-44,6
+43,8
@@
struct f_dfu {
unsigned int poll_timeout;
};
unsigned int poll_timeout;
};
+struct dfu_entity *dfu_defer_flush;
+
typedef int (*dfu_state_fn) (struct f_dfu *,
const struct usb_ctrlrequest *,
struct usb_gadget *,
typedef int (*dfu_state_fn) (struct f_dfu *,
const struct usb_ctrlrequest *,
struct usb_gadget *,
@@
-157,7
+158,7
@@
static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req)
int ret;
ret = dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf,
int ret;
ret = dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf,
- req->
length
, f_dfu->blk_seq_num);
+ req->
actual
, f_dfu->blk_seq_num);
if (ret) {
f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
f_dfu->dfu_state = DFU_STATE_dfuERROR;
if (ret) {
f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-167,14
+168,7
@@
static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req)
static void dnload_request_flush(struct usb_ep *ep, struct usb_request *req)
{
struct f_dfu *f_dfu = req->context;
static void dnload_request_flush(struct usb_ep *ep, struct usb_request *req)
{
struct f_dfu *f_dfu = req->context;
- int ret;
-
- ret = dfu_flush(dfu_get_entity(f_dfu->altsetting), req->buf,
- req->length, f_dfu->blk_seq_num);
- if (ret) {
- f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
- f_dfu->dfu_state = DFU_STATE_dfuERROR;
- }
+ dfu_set_defer_flush(dfu_get_entity(f_dfu->altsetting));
}
static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu)
}
static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu)
@@
-183,7
+177,7
@@
static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu)
DFU_MANIFEST_POLL_TIMEOUT;
}
DFU_MANIFEST_POLL_TIMEOUT;
}
-static
void
handle_getstatus(struct usb_request *req)
+static
int
handle_getstatus(struct usb_request *req)
{
struct dfu_status *dstat = (struct dfu_status *)req->buf;
struct f_dfu *f_dfu = req->context;
{
struct dfu_status *dstat = (struct dfu_status *)req->buf;
struct f_dfu *f_dfu = req->context;
@@
-215,14
+209,16
@@
static void handle_getstatus(struct usb_request *req)
dstat->bStatus = f_dfu->dfu_status;
dstat->bState = f_dfu->dfu_state;
dstat->iString = 0;
dstat->bStatus = f_dfu->dfu_status;
dstat->bState = f_dfu->dfu_state;
dstat->iString = 0;
+
+ return sizeof(struct dfu_status);
}
}
-static
void
handle_getstate(struct usb_request *req)
+static
int
handle_getstate(struct usb_request *req)
{
struct f_dfu *f_dfu = req->context;
((u8 *)req->buf)[0] = f_dfu->dfu_state;
{
struct f_dfu *f_dfu = req->context;
((u8 *)req->buf)[0] = f_dfu->dfu_state;
- re
q->actual =
sizeof(u8);
+ re
turn
sizeof(u8);
}
static inline void to_dfu_mode(struct f_dfu *f_dfu)
}
static inline void to_dfu_mode(struct f_dfu *f_dfu)
@@
-273,11
+269,10
@@
static int state_app_idle(struct f_dfu *f_dfu,
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
case USB_REQ_DFU_DETACH:
f_dfu->dfu_state = DFU_STATE_appDETACH;
break;
case USB_REQ_DFU_DETACH:
f_dfu->dfu_state = DFU_STATE_appDETACH;
@@
-301,11
+296,10
@@
static int state_app_detach(struct f_dfu *f_dfu,
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_appIDLE;
break;
default:
f_dfu->dfu_state = DFU_STATE_appIDLE;
@@
-346,11
+340,10
@@
static int state_dfu_idle(struct f_dfu *f_dfu,
value = RET_ZLP;
break;
case USB_REQ_DFU_GETSTATUS:
value = RET_ZLP;
break;
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
case USB_REQ_DFU_DETACH:
/*
break;
case USB_REQ_DFU_DETACH:
/*
@@
-386,11
+379,10
@@
static int state_dfu_dnload_sync(struct f_dfu *f_dfu,
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-410,8
+402,7
@@
static int state_dfu_dnbusy(struct f_dfu *f_dfu,
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-442,11
+433,10
@@
static int state_dfu_dnload_idle(struct f_dfu *f_dfu,
value = RET_ZLP;
break;
case USB_REQ_DFU_GETSTATUS:
value = RET_ZLP;
break;
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-468,13
+458,12
@@
static int state_dfu_manifest_sync(struct f_dfu *f_dfu,
case USB_REQ_DFU_GETSTATUS:
/* We're MainfestationTolerant */
f_dfu->dfu_state = DFU_STATE_dfuMANIFEST;
case USB_REQ_DFU_GETSTATUS:
/* We're MainfestationTolerant */
f_dfu->dfu_state = DFU_STATE_dfuMANIFEST;
- handle_getstatus(req);
+
value =
handle_getstatus(req);
f_dfu->blk_seq_num = 0;
f_dfu->blk_seq_num = 0;
- value = RET_STAT_LEN;
req->complete = dnload_request_flush;
break;
case USB_REQ_DFU_GETSTATE:
req->complete = dnload_request_flush;
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-496,13
+485,12
@@
static int state_dfu_manifest(struct f_dfu *f_dfu,
case USB_REQ_DFU_GETSTATUS:
/* We're MainfestationTolerant */
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
case USB_REQ_DFU_GETSTATUS:
/* We're MainfestationTolerant */
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
- handle_getstatus(req);
+
value =
handle_getstatus(req);
f_dfu->blk_seq_num = 0;
f_dfu->blk_seq_num = 0;
- value = RET_STAT_LEN;
puts("DOWNLOAD ... OK\nCtrl+C to exit ...\n");
break;
case USB_REQ_DFU_GETSTATE:
puts("DOWNLOAD ... OK\nCtrl+C to exit ...\n");
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-535,11
+523,10
@@
static int state_dfu_upload_idle(struct f_dfu *f_dfu,
value = RET_ZLP;
break;
case USB_REQ_DFU_GETSTATUS:
value = RET_ZLP;
break;
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
break;
default:
f_dfu->dfu_state = DFU_STATE_dfuERROR;
@@
-559,11
+546,10
@@
static int state_dfu_error(struct f_dfu *f_dfu,
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
switch (ctrl->bRequest) {
case USB_REQ_DFU_GETSTATUS:
- handle_getstatus(req);
- value = RET_STAT_LEN;
+ value = handle_getstatus(req);
break;
case USB_REQ_DFU_GETSTATE:
break;
case USB_REQ_DFU_GETSTATE:
- handle_getstate(req);
+
value =
handle_getstate(req);
break;
case USB_REQ_DFU_CLRSTATUS:
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
break;
case USB_REQ_DFU_CLRSTATUS:
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
@@
-641,7
+627,7
@@
dfu_prepare_strings(struct f_dfu *f_dfu, int n)
f_dfu->strings = calloc(sizeof(struct usb_string), n + 1);
if (!f_dfu->strings)
f_dfu->strings = calloc(sizeof(struct usb_string), n + 1);
if (!f_dfu->strings)
-
goto enomem
;
+
return -ENOMEM
;
for (i = 0; i < n; ++i) {
de = dfu_get_entity(i);
for (i = 0; i < n; ++i) {
de = dfu_get_entity(i);
@@
-652,14
+638,6
@@
dfu_prepare_strings(struct f_dfu *f_dfu, int n)
f_dfu->strings[i].s = NULL;
return 0;
f_dfu->strings[i].s = NULL;
return 0;
-
-enomem:
- while (i)
- f_dfu->strings[--i].s = NULL;
-
- free(f_dfu->strings);
-
- return -ENOMEM;
}
static int dfu_prepare_function(struct f_dfu *f_dfu, int n)
}
static int dfu_prepare_function(struct f_dfu *f_dfu, int n)
@@
-667,7
+645,7
@@
static int dfu_prepare_function(struct f_dfu *f_dfu, int n)
struct usb_interface_descriptor *d;
int i = 0;
struct usb_interface_descriptor *d;
int i = 0;
- f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n +
1
);
+ f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n +
2
);
if (!f_dfu->function)
goto enomem;
if (!f_dfu->function)
goto enomem;
@@
-686,6
+664,14
@@
static int dfu_prepare_function(struct f_dfu *f_dfu, int n)
f_dfu->function[i] = (struct usb_descriptor_header *)d;
}
f_dfu->function[i] = (struct usb_descriptor_header *)d;
}
+
+ /* add DFU Functional Descriptor */
+ f_dfu->function[i] = calloc(sizeof(dfu_func), 1);
+ if (!f_dfu->function[i])
+ goto enomem;
+ memcpy(f_dfu->function[i], &dfu_func, sizeof(dfu_func));
+
+ i++;
f_dfu->function[i] = NULL;
return 0;
f_dfu->function[i] = NULL;
return 0;
@@
-704,6
+690,7
@@
static int dfu_bind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_composite_dev *cdev = c->cdev;
struct f_dfu *f_dfu = func_to_dfu(f);
{
struct usb_composite_dev *cdev = c->cdev;
struct f_dfu *f_dfu = func_to_dfu(f);
+ const char *s;
int alt_num = dfu_get_alt_number();
int rv, id, i;
int alt_num = dfu_get_alt_number();
int rv, id, i;
@@
-737,6
+724,10
@@
static int dfu_bind(struct usb_configuration *c, struct usb_function *f)
cdev->req->context = f_dfu;
cdev->req->context = f_dfu;
+ s = env_get("serial#");
+ if (s)
+ g_dnl_set_serialnumber((char *)s);
+
error:
return rv;
}
error:
return rv;
}
@@
-780,6
+771,13
@@
static int dfu_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
return 0;
}
return 0;
}
+static int __dfu_get_alt(struct usb_function *f, unsigned intf)
+{
+ struct f_dfu *f_dfu = func_to_dfu(f);
+
+ return f_dfu->altsetting;
+}
+
/* TODO: is this really what we need here? */
static void dfu_disable(struct usb_function *f)
{
/* TODO: is this really what we need here? */
static void dfu_disable(struct usb_function *f)
{
@@
-806,6
+804,7
@@
static int dfu_bind_config(struct usb_configuration *c)
f_dfu->usb_function.bind = dfu_bind;
f_dfu->usb_function.unbind = dfu_unbind;
f_dfu->usb_function.set_alt = dfu_set_alt;
f_dfu->usb_function.bind = dfu_bind;
f_dfu->usb_function.unbind = dfu_unbind;
f_dfu->usb_function.set_alt = dfu_set_alt;
+ f_dfu->usb_function.get_alt = __dfu_get_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.disable = dfu_disable;
f_dfu->usb_function.strings = dfu_generic_strings;
f_dfu->usb_function.setup = dfu_handle;