blob: e9132936a90b9daced72b246c0f805f675e6fdf2 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Lukasz Majewski507375c2015-08-24 00:21:45 +02002/*
3 * (C) Copyright 2015
4 * Lukasz Majewski <l.majewski@majess.pl>
Lukasz Majewski507375c2015-08-24 00:21:45 +02005 */
6
Simon Glass0f2af882020-05-10 11:40:05 -06007#include <log.h>
Lukasz Majewski507375c2015-08-24 00:21:45 +02008#include <malloc.h>
9#include <errno.h>
10#include <dfu.h>
11
AKASHI Takahirofb6732f2020-10-29 13:47:41 +090012/**
13 * dfu_write_by_name() - write data to DFU medium
14 * @dfu_entity_name: Name of DFU entity to write
15 * @addr: Address of data buffer to write
16 * @len: Number of bytes
17 * @interface: Destination DFU medium (e.g. "mmc")
18 * @devstring: Instance number of destination DFU medium (e.g. "1")
19 *
20 * This function is storing data received on DFU supported medium which
21 * is specified by @dfu_entity_name.
22 *
23 * Return: 0 - on success, error code - otherwise
24 */
AKASHI Takahirobd4dc182020-10-29 13:47:42 +090025int dfu_write_by_name(char *dfu_entity_name, void *addr,
AKASHI Takahirofb6732f2020-10-29 13:47:41 +090026 unsigned int len, char *interface, char *devstring)
Lukasz Majewski507375c2015-08-24 00:21:45 +020027{
28 char *s, *sb;
29 int alt_setting_num, ret;
30 struct dfu_entity *dfu;
31
AKASHI Takahirobd4dc182020-10-29 13:47:42 +090032 debug("%s: name: %s addr: 0x%p len: %d device: %s:%s\n", __func__,
Lukasz Majewski507375c2015-08-24 00:21:45 +020033 dfu_entity_name, addr, len, interface, devstring);
34
35 ret = dfu_init_env_entities(interface, devstring);
36 if (ret)
37 goto done;
38
39 /*
40 * We need to copy name pointed by *dfu_entity_name since this text
41 * is the integral part of the FDT image.
42 * Any implicit modification (i.e. done by strsep()) will corrupt
43 * the FDT image and prevent other images to be stored.
44 */
45 s = strdup(dfu_entity_name);
46 sb = s;
47 if (!s) {
48 ret = -ENOMEM;
49 goto done;
50 }
51
52 strsep(&s, "@");
Marek Vasut70c0b442018-02-16 16:41:19 +010053 debug("%s: image name: %s strlen: %zd\n", __func__, sb, strlen(sb));
Lukasz Majewski507375c2015-08-24 00:21:45 +020054
55 alt_setting_num = dfu_get_alt(sb);
56 free(sb);
57 if (alt_setting_num < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +090058 pr_err("Alt setting [%d] to write not found!",
AKASHI Takahirofb6732f2020-10-29 13:47:41 +090059 alt_setting_num);
Lukasz Majewski507375c2015-08-24 00:21:45 +020060 ret = -ENODEV;
61 goto done;
62 }
63
64 dfu = dfu_get_entity(alt_setting_num);
65 if (!dfu) {
Masahiro Yamada81e10422017-09-16 14:10:41 +090066 pr_err("DFU entity for alt: %d not found!", alt_setting_num);
Lukasz Majewski507375c2015-08-24 00:21:45 +020067 ret = -ENODEV;
68 goto done;
69 }
70
AKASHI Takahirobd4dc182020-10-29 13:47:42 +090071 ret = dfu_write_from_mem_addr(dfu, (void *)addr, len);
Lukasz Majewski507375c2015-08-24 00:21:45 +020072
73done:
74 dfu_free_entities();
75
76 return ret;
77}
AKASHI Takahiro0e84a042020-10-29 13:47:52 +090078
79/**
80 * dfu_write_by_alt() - write data to DFU medium
81 * @dfu_alt_num: DFU alt setting number
82 * @addr: Address of data buffer to write
83 * @len: Number of bytes
84 * @interface: Destination DFU medium (e.g. "mmc")
85 * @devstring: Instance number of destination DFU medium (e.g. "1")
86 *
87 * This function is storing data received on DFU supported medium which
88 * is specified by @dfu_alt_name.
89 *
90 * Return: 0 - on success, error code - otherwise
91 */
92int dfu_write_by_alt(int dfu_alt_num, void *addr, unsigned int len,
93 char *interface, char *devstring)
94{
95 struct dfu_entity *dfu;
96 int ret;
97
98 debug("%s: alt: %d addr: 0x%p len: %d device: %s:%s\n", __func__,
99 dfu_alt_num, addr, len, interface, devstring);
100
101 ret = dfu_init_env_entities(interface, devstring);
102 if (ret)
103 goto done;
104
105 if (dfu_alt_num < 0) {
106 pr_err("Invalid alt number: %d", dfu_alt_num);
107 ret = -ENODEV;
108 goto done;
109 }
110
111 dfu = dfu_get_entity(dfu_alt_num);
112 if (!dfu) {
113 pr_err("DFU entity for alt: %d not found!", dfu_alt_num);
114 ret = -ENODEV;
115 goto done;
116 }
117
118 ret = dfu_write_from_mem_addr(dfu, (void *)(uintptr_t)addr, len);
119
120done:
121 dfu_free_entities();
122
123 return ret;
124}