X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fusb%2Fgadget%2Ff_dfu.c;h=30ece524a8e142eb1fd8662eb36bdea0b1d5b842;hb=8c1de5e08b845eb71c9a247d16bc81ebdab0598d;hp=8e7c981657c3b6be4b5ddbad802f5e00b3abb419;hpb=7b4f17bf3653ffff0d5d7b76bb8c2d8c293db4ce;p=oweals%2Fu-boot.git diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 8e7c981657..30ece524a8 100644 --- 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 * @@ -11,8 +12,6 @@ * * based on existing SAM7DFU code from OpenPCD: * (C) Copyright 2006 by Harald Welte - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -159,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, - 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; @@ -178,7 +177,7 @@ static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu) 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; @@ -210,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; + + 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; - req->actual = sizeof(u8); + return sizeof(u8); } static inline void to_dfu_mode(struct f_dfu *f_dfu) @@ -268,11 +269,10 @@ static int state_app_idle(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; case USB_REQ_DFU_DETACH: f_dfu->dfu_state = DFU_STATE_appDETACH; @@ -296,11 +296,10 @@ static int state_app_detach(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; default: f_dfu->dfu_state = DFU_STATE_appIDLE; @@ -341,11 +340,10 @@ static int state_dfu_idle(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; case USB_REQ_DFU_DETACH: /* @@ -381,11 +379,10 @@ static int state_dfu_dnload_sync(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; default: f_dfu->dfu_state = DFU_STATE_dfuERROR; @@ -405,8 +402,7 @@ static int state_dfu_dnbusy(struct f_dfu *f_dfu, 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; @@ -437,11 +433,10 @@ static int state_dfu_dnload_idle(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; default: f_dfu->dfu_state = DFU_STATE_dfuERROR; @@ -463,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; - handle_getstatus(req); + value = handle_getstatus(req); f_dfu->blk_seq_num = 0; - value = RET_STAT_LEN; 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; @@ -491,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; - handle_getstatus(req); + value = handle_getstatus(req); f_dfu->blk_seq_num = 0; - value = RET_STAT_LEN; 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; @@ -530,11 +523,10 @@ static int state_dfu_upload_idle(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; default: f_dfu->dfu_state = DFU_STATE_dfuERROR; @@ -554,11 +546,10 @@ static int state_dfu_error(struct f_dfu *f_dfu, 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: - handle_getstate(req); + value = handle_getstate(req); break; case USB_REQ_DFU_CLRSTATUS: f_dfu->dfu_state = DFU_STATE_dfuIDLE; @@ -654,7 +645,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 + 1); + f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n + 2); if (!f_dfu->function) goto enomem; @@ -673,6 +664,14 @@ static int dfu_prepare_function(struct f_dfu *f_dfu, int n) 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; @@ -691,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); + const char *s; int alt_num = dfu_get_alt_number(); int rv, id, i; @@ -724,6 +724,10 @@ static int dfu_bind(struct usb_configuration *c, struct usb_function *f) cdev->req->context = f_dfu; + s = env_get("serial#"); + if (s) + g_dnl_set_serialnumber((char *)s); + error: return rv; }