summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-01-16 09:18:34 -0600
committerTom Rini <[email protected]>2026-01-16 09:53:57 -0600
commit1da640cc46ad84efb57bb45e02dd6c40265b5488 (patch)
tree29a54e26b2a6e032b9ba5b99a7207a52acd69025 /drivers
parent03893b263a64b06ef06769b5526918fabd7a774f (diff)
parent0efe1d9502a022d5d5c39c73340dd0b7b3f9cbe5 (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.c52
-rw-r--r--drivers/usb/gadget/ci_udc.c57
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;