Skip to content

Commit 2971c84

Browse files
committed
qdl: decouple transport logic
Decouple the flashing logic from the underlying type of communication. Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
1 parent 30ac3a8 commit 2971c84

File tree

6 files changed

+171
-39
lines changed

6 files changed

+171
-39
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ CFLAGS += -O2 -Wall -g `pkg-config --cflags libxml-2.0 libusb-1.0`
66
LDFLAGS += `pkg-config --libs libxml-2.0 libusb-1.0`
77
prefix := /usr/local
88

9-
QDL_SRCS := firehose.c qdl.c sahara.c util.c patch.c program.c read.c ufs.c usb.c ux.c
9+
QDL_SRCS := firehose.c io.c qdl.c sahara.c util.c patch.c program.c read.c ufs.c usb.c ux.c
1010
QDL_OBJS := $(QDL_SRCS:.c=.o)
1111

12-
RAMDUMP_SRCS := ramdump.c sahara.c usb.c util.c ux.c
12+
RAMDUMP_SRCS := ramdump.c sahara.c io.c usb.c util.c ux.c
1313
RAMDUMP_OBJS := $(RAMDUMP_SRCS:.c=.o)
1414

1515
KS_OUT := ks

io.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are met:
6+
*
7+
* 1. Redistributions of source code must retain the above copyright notice,
8+
* this list of conditions and the following disclaimer.
9+
*
10+
* 2. Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
*
14+
* 3. Neither the name of the copyright holder nor the names of its contributors
15+
* may be used to endorse or promote products derived from this software without
16+
* specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
31+
#include "qdl.h"
32+
33+
struct qdl_device *qdl_init(enum QDL_DEVICE_TYPE type)
34+
{
35+
if (type == QDL_DEVICE_USB)
36+
return usb_init();
37+
38+
return NULL;
39+
}
40+
41+
void qdl_deinit(struct qdl_device *qdl)
42+
{
43+
if (qdl)
44+
free(qdl);
45+
}
46+
47+
void qdl_set_out_chunk_size(struct qdl_device *qdl, long size)
48+
{
49+
qdl->set_out_chunk_size(qdl, size);
50+
}
51+
52+
int qdl_open(struct qdl_device *qdl, const char *serial)
53+
{
54+
return qdl->open(qdl, serial);
55+
}
56+
57+
void qdl_close(struct qdl_device *qdl)
58+
{
59+
qdl->close(qdl);
60+
}
61+
62+
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
63+
{
64+
return qdl->read(qdl, buf, len, timeout);
65+
}
66+
67+
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
68+
{
69+
return qdl->write(qdl, buf, len);
70+
}

qdl.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ enum {
5555
};
5656

5757
bool qdl_debug;
58-
static struct qdl_device qdl;
5958

6059
static int detect_type(const char *xml_file)
6160
{
@@ -121,7 +120,9 @@ int main(int argc, char **argv)
121120
int opt;
122121
bool qdl_finalize_provisioning = false;
123122
bool allow_missing = false;
124-
long out_chunk_size;
123+
long out_chunk_size = 0;
124+
struct qdl_device *qdl = NULL;
125+
enum QDL_DEVICE_TYPE qdl_dev_type = QDL_DEVICE_USB;
125126

126127
static struct option options[] = {
127128
{"debug", no_argument, 0, 'd'},
@@ -154,7 +155,6 @@ int main(int argc, char **argv)
154155
break;
155156
case OPT_OUT_CHUNK_SIZE:
156157
out_chunk_size = strtol(optarg, NULL, 10);
157-
qdl_set_out_chunk_size(&qdl, out_chunk_size);
158158
break;
159159
case 's':
160160
storage = optarg;
@@ -174,6 +174,15 @@ int main(int argc, char **argv)
174174
return 1;
175175
}
176176

177+
qdl = qdl_init(qdl_dev_type);
178+
if (!qdl) {
179+
ret = -1;
180+
goto out_cleanup;
181+
}
182+
183+
if (out_chunk_size)
184+
qdl_set_out_chunk_size(qdl, out_chunk_size);
185+
177186
ux_init();
178187

179188
if (qdl_debug)
@@ -213,23 +222,25 @@ int main(int argc, char **argv)
213222
}
214223
} while (++optind < argc);
215224

216-
ret = qdl_open(&qdl, serial);
225+
ret = qdl_open(qdl, serial);
217226
if (ret)
218227
goto out_cleanup;
219228

220-
qdl.mappings[0] = prog_mbn;
221-
ret = sahara_run(&qdl, qdl.mappings, true, NULL, NULL);
229+
qdl->mappings[0] = prog_mbn;
230+
ret = sahara_run(qdl, qdl->mappings, true, NULL, NULL);
222231
if (ret < 0)
223232
goto out_cleanup;
224233

225-
ret = firehose_run(&qdl, incdir, storage, allow_missing);
234+
ret = firehose_run(qdl, incdir, storage, allow_missing);
226235
if (ret < 0)
227236
goto out_cleanup;
228237

229238
out_cleanup:
230-
qdl_close(&qdl);
239+
qdl_close(qdl);
231240
free_programs();
232241
free_patches();
233242

243+
qdl_deinit(qdl);
244+
234245
return !!ret;
235246
}

qdl.h

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,56 @@
88
#include "read.h"
99
#include <libxml/tree.h>
1010

11+
#define container_of(ptr, typecast, member) ({ \
12+
void *_ptr = (void *)(ptr); \
13+
((typecast *)(_ptr - offsetof(typecast, member))); })
14+
1115
#define MAPPING_SZ 64
1216

13-
struct libusb_device_handle;
17+
enum QDL_DEVICE_TYPE
18+
{
19+
QDL_DEVICE_USB,
20+
};
1421

15-
struct qdl_device {
16-
struct libusb_device_handle *usb_handle;
17-
int fd;
22+
struct qdl_device
23+
{
24+
enum QDL_DEVICE_TYPE dev_type;
25+
int fd;
1826

19-
int in_ep;
20-
int out_ep;
27+
int (*open)(struct qdl_device *qdl, const char *serial);
28+
int (*read)(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
29+
int (*write)(struct qdl_device *qdl, const void *buf, size_t nbytes);
30+
void (*close)(struct qdl_device *qdl);
31+
void (*set_out_chunk_size)(struct qdl_device *qdl, long size);
2132

22-
size_t in_maxpktsize;
23-
size_t out_maxpktsize;
24-
size_t out_chunk_size;
33+
char *mappings[MAPPING_SZ]; // array index is the id from the device
34+
};
2535

26-
char *mappings[MAPPING_SZ]; // array index is the id from the device
36+
struct libusb_device_handle;
37+
38+
struct qdl_device_usb
39+
{
40+
struct qdl_device base;
41+
struct libusb_device_handle *usb_handle;
42+
43+
int in_ep;
44+
int out_ep;
45+
46+
size_t in_maxpktsize;
47+
size_t out_maxpktsize;
48+
size_t out_chunk_size;
2749
};
2850

51+
struct qdl_device *qdl_init(enum QDL_DEVICE_TYPE type);
52+
void qdl_deinit(struct qdl_device *qdl);
2953
int qdl_open(struct qdl_device *qdl, const char *serial);
3054
void qdl_close(struct qdl_device *qdl);
3155
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
3256
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len);
3357
void qdl_set_out_chunk_size(struct qdl_device *qdl, long size);
3458

59+
struct qdl_device *usb_init(void);
60+
3561
int firehose_run(struct qdl_device *qdl, const char *incdir, const char *storage, bool allow_missing);
3662
int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
3763
const char *ramdump_path, const char *ramdump_filter);

ramdump.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ static void print_usage(void)
1818

1919
int main(int argc, char **argv)
2020
{
21-
struct qdl_device qdl;
21+
struct qdl_device_usb qdl;
22+
qdl.base.dev_type = QDL_DEVICE_USB;
23+
2224
char *ramdump_path = ".";
2325
char *filter = NULL;
2426
char *serial = NULL;
@@ -61,11 +63,11 @@ int main(int argc, char **argv)
6163
if (qdl_debug)
6264
print_version();
6365

64-
ret = qdl_open(&qdl, serial);
66+
ret = qdl_open(&qdl.base, serial);
6567
if (ret)
6668
return 1;
6769

68-
ret = sahara_run(&qdl, NULL, true, ramdump_path, filter);
70+
ret = sahara_run(&qdl.base, NULL, true, ramdump_path, filter);
6971
if (ret < 0)
7072
return 1;
7173

usb.c

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#define LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK LIBUSB_TRANSFER_TYPE_BULK
2323
#endif
2424

25-
static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
25+
static bool usb_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
2626
const struct libusb_device_descriptor *desc)
2727
{
2828
char buf[128];
@@ -49,7 +49,7 @@ static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char
4949
return strcmp(p, serial) == 0;
5050
}
5151

52-
static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *serial)
52+
static int usb_try_open(libusb_device *dev, struct qdl_device_usb *qdl, const char *serial)
5353
{
5454
const struct libusb_endpoint_descriptor *endpoint;
5555
const struct libusb_interface_descriptor *ifc;
@@ -123,7 +123,7 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *
123123
continue;
124124
}
125125

126-
if (!qdl_match_usb_serial(handle, serial, &desc)) {
126+
if (!usb_match_usb_serial(handle, serial, &desc)) {
127127
libusb_close(handle);
128128
continue;
129129
}
@@ -161,10 +161,11 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *
161161
return !!qdl->usb_handle;
162162
}
163163

164-
int qdl_open(struct qdl_device *qdl, const char *serial)
164+
static int usb_open(struct qdl_device *qdl, const char *serial)
165165
{
166166
struct libusb_device **devs;
167167
struct libusb_device *dev;
168+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
168169
bool wait_printed = false;
169170
bool found = false;
170171
ssize_t n;
@@ -183,7 +184,7 @@ int qdl_open(struct qdl_device *qdl, const char *serial)
183184
for (i = 0; devs[i]; i++) {
184185
dev = devs[i];
185186

186-
ret = qdl_try_open(dev, qdl, serial);
187+
ret = usb_try_open(dev, qdl_usb, serial);
187188
if (ret == 1) {
188189
found = true;
189190
break;
@@ -206,38 +207,42 @@ int qdl_open(struct qdl_device *qdl, const char *serial)
206207
return -1;
207208
}
208209

209-
void qdl_close(struct qdl_device *qdl)
210+
static void usb_close(struct qdl_device *qdl)
210211
{
211-
libusb_close(qdl->usb_handle);
212+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
213+
214+
libusb_close(qdl_usb->usb_handle);
212215
libusb_exit(NULL);
213216
}
214217

215-
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
218+
static int usb_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
216219
{
220+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
217221
int actual;
218222
int ret;
219223

220-
ret = libusb_bulk_transfer(qdl->usb_handle, qdl->in_ep, buf, len, &actual, timeout);
224+
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->in_ep, buf, len, &actual, timeout);
221225
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
222226
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0))
223227
return -1;
224228

225229
return actual;
226230
}
227231

228-
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
232+
static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
229233
{
230234
unsigned char *data = (unsigned char*) buf;
235+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
231236
unsigned int count = 0;
232237
size_t len_orig = len;
233238
int actual;
234239
int xfer;
235240
int ret;
236241

237242
while (len > 0) {
238-
xfer = (len > qdl->out_chunk_size) ? qdl->out_chunk_size : len;
243+
xfer = (len > qdl_usb->out_chunk_size) ? qdl_usb->out_chunk_size : len;
239244

240-
ret = libusb_bulk_transfer(qdl->usb_handle, qdl->out_ep, data,
245+
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, data,
241246
xfer, &actual, 1000);
242247
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
243248
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0)) {
@@ -250,8 +255,8 @@ int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
250255
data += actual;
251256
}
252257

253-
if (len_orig % qdl->out_maxpktsize == 0) {
254-
ret = libusb_bulk_transfer(qdl->usb_handle, qdl->out_ep, NULL,
258+
if (len_orig % qdl_usb->out_maxpktsize == 0) {
259+
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, NULL,
255260
0, &actual, 1000);
256261
if (ret < 0)
257262
return -1;
@@ -260,7 +265,25 @@ int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
260265
return count;
261266
}
262267

263-
void qdl_set_out_chunk_size(struct qdl_device *qdl, long size)
268+
static void usb_set_out_chunk_size(struct qdl_device *qdl, long size)
264269
{
265-
qdl->out_chunk_size = size;
270+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
271+
272+
qdl_usb->out_chunk_size = size;
266273
}
274+
275+
struct qdl_device *usb_init(void)
276+
{
277+
struct qdl_device *qdl = malloc(sizeof(struct qdl_device_usb));
278+
if (!qdl)
279+
return NULL;
280+
281+
qdl->dev_type = QDL_DEVICE_USB;
282+
qdl->open = usb_open;
283+
qdl->read = usb_read;
284+
qdl->write = usb_write;
285+
qdl->close = usb_close;
286+
qdl->set_out_chunk_size = usb_set_out_chunk_size;
287+
288+
return qdl;
289+
}

0 commit comments

Comments
 (0)