Skip to content

Commit 6050e51

Browse files
committed
qdl: decouple transport logic
Decouple the flashing logic from the underlying type of communication. This is needed for introducing simulation mode, where no real flashing is performed, but firehose packets are used for other tasks, like VIP table generation. Signed-off-by: Igor Opaniuk <[email protected]>
1 parent 30ac3a8 commit 6050e51

File tree

6 files changed

+171
-39
lines changed

6 files changed

+171
-39
lines changed

Makefile

+2-2
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

+70
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

+19-8
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

+32-10
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,50 @@
1010

1111
#define MAPPING_SZ 64
1212

13-
struct libusb_device_handle;
13+
enum QDL_DEVICE_TYPE
14+
{
15+
QDL_DEVICE_USB,
16+
};
17+
18+
struct qdl_device
19+
{
20+
enum QDL_DEVICE_TYPE dev_type;
21+
int fd;
22+
23+
int (*open)(struct qdl_device *qdl, const char *serial);
24+
int (*read)(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
25+
int (*write)(struct qdl_device *qdl, const void *buf, size_t nbytes);
26+
void (*close)(struct qdl_device *qdl);
27+
void (*set_out_chunk_size)(struct qdl_device *qdl, long size);
1428

15-
struct qdl_device {
16-
struct libusb_device_handle *usb_handle;
17-
int fd;
29+
char *mappings[MAPPING_SZ]; // array index is the id from the device
30+
};
31+
32+
struct libusb_device_handle;
1833

19-
int in_ep;
20-
int out_ep;
34+
struct qdl_device_usb
35+
{
36+
struct qdl_device base;
37+
struct libusb_device_handle *usb_handle;
2138

22-
size_t in_maxpktsize;
23-
size_t out_maxpktsize;
24-
size_t out_chunk_size;
39+
int in_ep;
40+
int out_ep;
2541

26-
char *mappings[MAPPING_SZ]; // array index is the id from the device
42+
size_t in_maxpktsize;
43+
size_t out_maxpktsize;
44+
size_t out_chunk_size;
2745
};
2846

47+
struct qdl_device *qdl_init(enum QDL_DEVICE_TYPE type);
48+
void qdl_deinit(struct qdl_device *qdl);
2949
int qdl_open(struct qdl_device *qdl, const char *serial);
3050
void qdl_close(struct qdl_device *qdl);
3151
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
3252
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len);
3353
void qdl_set_out_chunk_size(struct qdl_device *qdl, long size);
3454

55+
struct qdl_device *usb_init(void);
56+
3557
int firehose_run(struct qdl_device *qdl, const char *incdir, const char *storage, bool allow_missing);
3658
int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
3759
const char *ramdump_path, const char *ramdump_filter);

ramdump.c

+5-3
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

+43-16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
#include "qdl.h"
1212

13+
#define container_of(ptr, typecast, member) ({ \
14+
void *_ptr = (void *)(ptr); \
15+
((typecast *)(_ptr - offsetof(typecast, member))); })
16+
1317
#define DEFAULT_OUT_CHUNK_SIZE (1024 * 1024)
1418

1519
/*
@@ -22,7 +26,7 @@
2226
#define LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK LIBUSB_TRANSFER_TYPE_BULK
2327
#endif
2428

25-
static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
29+
static bool usb_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
2630
const struct libusb_device_descriptor *desc)
2731
{
2832
char buf[128];
@@ -49,7 +53,7 @@ static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char
4953
return strcmp(p, serial) == 0;
5054
}
5155

52-
static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *serial)
56+
static int usb_try_open(libusb_device *dev, struct qdl_device_usb *qdl, const char *serial)
5357
{
5458
const struct libusb_endpoint_descriptor *endpoint;
5559
const struct libusb_interface_descriptor *ifc;
@@ -123,7 +127,7 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *
123127
continue;
124128
}
125129

126-
if (!qdl_match_usb_serial(handle, serial, &desc)) {
130+
if (!usb_match_usb_serial(handle, serial, &desc)) {
127131
libusb_close(handle);
128132
continue;
129133
}
@@ -161,10 +165,11 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *
161165
return !!qdl->usb_handle;
162166
}
163167

164-
int qdl_open(struct qdl_device *qdl, const char *serial)
168+
static int usb_open(struct qdl_device *qdl, const char *serial)
165169
{
166170
struct libusb_device **devs;
167171
struct libusb_device *dev;
172+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
168173
bool wait_printed = false;
169174
bool found = false;
170175
ssize_t n;
@@ -183,7 +188,7 @@ int qdl_open(struct qdl_device *qdl, const char *serial)
183188
for (i = 0; devs[i]; i++) {
184189
dev = devs[i];
185190

186-
ret = qdl_try_open(dev, qdl, serial);
191+
ret = usb_try_open(dev, qdl_usb, serial);
187192
if (ret == 1) {
188193
found = true;
189194
break;
@@ -206,38 +211,42 @@ int qdl_open(struct qdl_device *qdl, const char *serial)
206211
return -1;
207212
}
208213

209-
void qdl_close(struct qdl_device *qdl)
214+
static void usb_close(struct qdl_device *qdl)
210215
{
211-
libusb_close(qdl->usb_handle);
216+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
217+
218+
libusb_close(qdl_usb->usb_handle);
212219
libusb_exit(NULL);
213220
}
214221

215-
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
222+
static int usb_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
216223
{
224+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
217225
int actual;
218226
int ret;
219227

220-
ret = libusb_bulk_transfer(qdl->usb_handle, qdl->in_ep, buf, len, &actual, timeout);
228+
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->in_ep, buf, len, &actual, timeout);
221229
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
222230
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0))
223231
return -1;
224232

225233
return actual;
226234
}
227235

228-
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
236+
static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
229237
{
230238
unsigned char *data = (unsigned char*) buf;
239+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
231240
unsigned int count = 0;
232241
size_t len_orig = len;
233242
int actual;
234243
int xfer;
235244
int ret;
236245

237246
while (len > 0) {
238-
xfer = (len > qdl->out_chunk_size) ? qdl->out_chunk_size : len;
247+
xfer = (len > qdl_usb->out_chunk_size) ? qdl_usb->out_chunk_size : len;
239248

240-
ret = libusb_bulk_transfer(qdl->usb_handle, qdl->out_ep, data,
249+
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, data,
241250
xfer, &actual, 1000);
242251
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
243252
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0)) {
@@ -250,8 +259,8 @@ int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
250259
data += actual;
251260
}
252261

253-
if (len_orig % qdl->out_maxpktsize == 0) {
254-
ret = libusb_bulk_transfer(qdl->usb_handle, qdl->out_ep, NULL,
262+
if (len_orig % qdl_usb->out_maxpktsize == 0) {
263+
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, NULL,
255264
0, &actual, 1000);
256265
if (ret < 0)
257266
return -1;
@@ -260,7 +269,25 @@ int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
260269
return count;
261270
}
262271

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

0 commit comments

Comments
 (0)