diff options
| author | Tom Rini <[email protected]> | 2026-01-16 09:18:34 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-01-16 09:53:57 -0600 |
| commit | 1da640cc46ad84efb57bb45e02dd6c40265b5488 (patch) | |
| tree | 29a54e26b2a6e032b9ba5b99a7207a52acd69025 /drivers | |
| parent | 03893b263a64b06ef06769b5526918fabd7a774f (diff) | |
| parent | 0efe1d9502a022d5d5c39c73340dd0b7b3f9cbe5 (diff) | |
Merge tag 'u-boot-dfu-20260116' of https://source.denx.de/u-boot/custodians/u-boot-dfu
u-boot-dfu-20260116
CI: https://source.denx.de/u-boot/custodians/u-boot-dfu/-/pipelines/29018
Android:
* Fix missing dependency for BOOTMETH_ANDROID
* Add bootconfig support
* Add 'get ramdisk' command to abootimg
DFU:
* Improve error handling in dfu_fill_entity()
USB Gadget:
* ci_udc: Ensure ci_ep->desc is valid before using it
* ci_udc: Add additional debug prints
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/dfu/dfu.c | 52 | ||||
| -rw-r--r-- | drivers/usb/gadget/ci_udc.c | 57 |
2 files changed, 83 insertions, 26 deletions
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index eefdf44ec87..90d8b45ce8a 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -185,7 +185,7 @@ int dfu_init_env_entities(char *interface, char *devstr) ret = dfu_config_entities(env_bkp, interface, devstr); if (ret) { - pr_err("DFU entities configuration failed!\n"); + pr_err("DFU entities configuration failed: %d\n", ret); pr_err("(partition table does not match dfu_alt_info?)\n"); goto done; } @@ -518,7 +518,7 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, char *interface, char *devstr) { char *argv[DFU_MAX_ENTITY_ARGS]; - int argc; + int argc, ret; char *st; debug("%s: %s interface: %s dev: %s\n", __func__, s, interface, devstr); @@ -547,30 +547,37 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, /* Specific for mmc device */ if (strcmp(interface, "mmc") == 0) { - if (dfu_fill_entity_mmc(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_mmc(dfu, devstr, argv, argc); + if (ret) + return ret; } else if (strcmp(interface, "mtd") == 0) { - if (dfu_fill_entity_mtd(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_mtd(dfu, devstr, argv, argc); + if (ret) + return ret; } else if (strcmp(interface, "nand") == 0) { - if (dfu_fill_entity_nand(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_nand(dfu, devstr, argv, argc); + if (ret) + return ret; } else if (strcmp(interface, "ram") == 0) { - if (dfu_fill_entity_ram(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_ram(dfu, devstr, argv, argc); + if (ret) + return ret; } else if (strcmp(interface, "sf") == 0) { - if (dfu_fill_entity_sf(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_sf(dfu, devstr, argv, argc); + if (ret) + return ret; } else if (strcmp(interface, "virt") == 0) { - if (dfu_fill_entity_virt(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_virt(dfu, devstr, argv, argc); + if (ret) + return ret; } else if (strcmp(interface, "scsi") == 0) { - if (dfu_fill_entity_scsi(dfu, devstr, argv, argc)) - return -1; + ret = dfu_fill_entity_scsi(dfu, devstr, argv, argc); + if (ret) + return ret; } else { printf("%s: Device %s not (yet) supported!\n", __func__, interface); - return -1; + return -EOPNOTSUPP; } dfu_get_buf(dfu); @@ -624,12 +631,12 @@ int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s) int ret; if (alt_num_cnt >= dfu_alt_num) - return -1; + return -EINVAL; p_dfu = &dfu[alt_num_cnt]; ret = dfu_fill_entity(p_dfu, s, alt_num_cnt, interface, devstr); if (ret) - return -1; + return ret; list_add_tail(&p_dfu->list, &dfu_list); alt_num_cnt++; @@ -645,16 +652,15 @@ int dfu_config_entities(char *env, char *interface, char *devstr) ret = dfu_alt_init(dfu_find_alt_num(env), &dfu); if (ret) - return -1; + return ret; for (i = 0; i < dfu_alt_num; i++) { s = strsep(&env, ";"); s = skip_spaces(s); ret = dfu_alt_add(dfu, interface, devstr, s); - if (ret) { + if (ret) /* We will free "dfu" in dfu_free_entities() */ - return -1; - } + return ret; } return 0; diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 4bff75da759..046bb335ecb 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -273,8 +273,10 @@ ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags) if (ci_ep->desc) num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - if (num == 0 && controller.ep0_req) + if (num == 0 && controller.ep0_req) { + DBG("%s: already got controller.ep0_req = %p\n", __func__, controller.ep0_req); return &controller.ep0_req->req; + } ci_req = calloc(1, sizeof(*ci_req)); if (!ci_req) @@ -296,6 +298,8 @@ static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *req) if (ci_ep->desc) num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + else + DBG("%s: no endpoint %p descriptor\n", __func__, ci_ep); if (num == 0) { if (!controller.ep0_req) @@ -308,6 +312,27 @@ static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *req) free(ci_req); } +static void request_complete(struct usb_ep *ep, struct ci_req *req, int status) +{ + if (req->req.status == -EINPROGRESS) + req->req.status = status; + + DBG("%s: req %p complete: status %d, actual %u\n", + ep->name, req, req->req.status, req->req.actual); + + req->req.complete(ep, &req->req); +} + +static void request_complete_list(struct usb_ep *ep, struct list_head *list, int status) +{ + struct ci_req *req, *tmp_req; + + list_for_each_entry_safe(req, tmp_req, list, queue) { + list_del_init(&req->queue); + request_complete(ep, req, status); + } +} + static void ep_enable(int num, int in, int maxpacket) { struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; @@ -335,6 +360,12 @@ static int ci_ep_enable(struct usb_ep *ep, int num, in; num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; in = (desc->bEndpointAddress & USB_DIR_IN) != 0; + + if (ci_ep->desc) { + DBG("%s: endpoint num %d in %d already enabled\n", __func__, num, in); + return -EBUSY; + } + ci_ep->desc = desc; ep->desc = desc; @@ -385,19 +416,32 @@ static int ep_disable(int num, int in) static int ci_ep_disable(struct usb_ep *ep) { struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep); + LIST_HEAD(req_list); int num, in, err; + if (!ci_ep->desc) { + DBG("%s: attempt to disable a not enabled yet endpoint\n", __func__); + err = -EBUSY; + goto nodesc; + } + num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; in = (ci_ep->desc->bEndpointAddress & USB_DIR_IN) != 0; + list_splice_init(&ci_ep->queue, &req_list); + request_complete_list(ep, &req_list, -ESHUTDOWN); + err = ep_disable(num, in); if (err) return err; ci_ep->desc = NULL; + err = 0; + +nodesc: ep->desc = NULL; ci_ep->req_primed = false; - return 0; + return err; } static int ci_bounce(struct ci_req *ci_req, int in) @@ -584,8 +628,10 @@ static int ci_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) break; } - if (&ci_req->req != _req) + if (&ci_req->req != _req) { + DBG("%s: ci_req not found in the queue\n", __func__); return -EINVAL; + } list_del_init(&ci_req->queue); @@ -606,6 +652,11 @@ static int ci_ep_queue(struct usb_ep *ep, int in, ret; int __maybe_unused num; + if (!ci_ep->desc) { + DBG("%s: ci_ep->desc == NULL, nothing to do!\n", __func__); + return -EINVAL; + } + num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; in = (ci_ep->desc->bEndpointAddress & USB_DIR_IN) != 0; |
