Skip to content

Commit b8468f6

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 <igor.opaniuk@oss.qualcomm.com>
1 parent c856721 commit b8468f6

File tree

6 files changed

+172
-39
lines changed

6 files changed

+172
-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 oscompat.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 oscompat.c
1010
QDL_OBJS := $(QDL_SRCS:.c=.o)
1111

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

1515
KS_OUT := ks

io.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
#include <stdlib.h>
31+
32+
#include "qdl.h"
33+
34+
struct qdl_device *qdl_init(enum QDL_DEVICE_TYPE type)
35+
{
36+
if (type == QDL_DEVICE_USB)
37+
return usb_init();
38+
39+
return NULL;
40+
}
41+
42+
void qdl_deinit(struct qdl_device *qdl)
43+
{
44+
if (qdl)
45+
free(qdl);
46+
}
47+
48+
void qdl_set_out_chunk_size(struct qdl_device *qdl, long size)
49+
{
50+
qdl->set_out_chunk_size(qdl, size);
51+
}
52+
53+
int qdl_open(struct qdl_device *qdl, const char *serial)
54+
{
55+
return qdl->open(qdl, serial);
56+
}
57+
58+
void qdl_close(struct qdl_device *qdl)
59+
{
60+
qdl->close(qdl);
61+
}
62+
63+
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
64+
{
65+
return qdl->read(qdl, buf, len, timeout);
66+
}
67+
68+
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
69+
{
70+
return qdl->write(qdl, buf, len);
71+
}

qdl.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ enum {
6060
};
6161

6262
bool qdl_debug;
63-
static struct qdl_device qdl;
6463

6564
static int detect_type(const char *xml_file)
6665
{
@@ -127,7 +126,9 @@ int main(int argc, char **argv)
127126
bool qdl_finalize_provisioning = false;
128127
bool allow_fusing = false;
129128
bool allow_missing = false;
130-
long out_chunk_size;
129+
long out_chunk_size = 0;
130+
struct qdl_device *qdl = NULL;
131+
enum QDL_DEVICE_TYPE qdl_dev_type = QDL_DEVICE_USB;
131132

132133
static struct option options[] = {
133134
{"debug", no_argument, 0, 'd'},
@@ -164,7 +165,6 @@ int main(int argc, char **argv)
164165
break;
165166
case OPT_OUT_CHUNK_SIZE:
166167
out_chunk_size = strtol(optarg, NULL, 10);
167-
qdl_set_out_chunk_size(&qdl, out_chunk_size);
168168
break;
169169
case 's':
170170
storage = optarg;
@@ -184,6 +184,15 @@ int main(int argc, char **argv)
184184
return 1;
185185
}
186186

187+
qdl = qdl_init(qdl_dev_type);
188+
if (!qdl) {
189+
ret = -1;
190+
goto out_cleanup;
191+
}
192+
193+
if (out_chunk_size)
194+
qdl_set_out_chunk_size(qdl, out_chunk_size);
195+
187196
ux_init();
188197

189198
if (qdl_debug)
@@ -227,23 +236,25 @@ int main(int argc, char **argv)
227236
}
228237
} while (++optind < argc);
229238

230-
ret = qdl_open(&qdl, serial);
239+
ret = qdl_open(qdl, serial);
231240
if (ret)
232241
goto out_cleanup;
233242

234-
qdl.mappings[0] = prog_mbn;
235-
ret = sahara_run(&qdl, qdl.mappings, true, NULL, NULL);
243+
qdl->mappings[0] = prog_mbn;
244+
ret = sahara_run(qdl, qdl->mappings, true, NULL, NULL);
236245
if (ret < 0)
237246
goto out_cleanup;
238247

239-
ret = firehose_run(&qdl, incdir, storage, allow_missing);
248+
ret = firehose_run(qdl, incdir, storage, allow_missing);
240249
if (ret < 0)
241250
goto out_cleanup;
242251

243252
out_cleanup:
244-
qdl_close(&qdl);
253+
qdl_close(qdl);
245254
free_programs();
246255
free_patches();
247256

257+
qdl_deinit(qdl);
258+
248259
return !!ret;
249260
}

qdl.h

Lines changed: 32 additions & 10 deletions
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

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

2424
int main(int argc, char **argv)
2525
{
26-
struct qdl_device qdl;
26+
struct qdl_device_usb qdl;
27+
qdl.base.dev_type = QDL_DEVICE_USB;
28+
2729
char *ramdump_path = ".";
2830
char *filter = NULL;
2931
char *serial = NULL;
@@ -66,11 +68,11 @@ int main(int argc, char **argv)
6668
if (qdl_debug)
6769
print_version();
6870

69-
ret = qdl_open(&qdl, serial);
71+
ret = qdl_open(&qdl.base, serial);
7072
if (ret)
7173
return 1;
7274

73-
ret = sahara_run(&qdl, NULL, true, ramdump_path, filter);
75+
ret = sahara_run(&qdl.base, NULL, true, ramdump_path, filter);
7476
if (ret < 0)
7577
return 1;
7678

usb.c

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
#include "qdl.h"
1111

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

1418
/*
@@ -21,7 +25,7 @@
2125
#define LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK LIBUSB_TRANSFER_TYPE_BULK
2226
#endif
2327

24-
static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
28+
static bool usb_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
2529
const struct libusb_device_descriptor *desc)
2630
{
2731
char buf[128];
@@ -48,7 +52,7 @@ static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char
4852
return strcmp(p, serial) == 0;
4953
}
5054

51-
static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *serial)
55+
static int usb_try_open(libusb_device *dev, struct qdl_device_usb *qdl, const char *serial)
5256
{
5357
const struct libusb_endpoint_descriptor *endpoint;
5458
const struct libusb_interface_descriptor *ifc;
@@ -122,7 +126,7 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *
122126
continue;
123127
}
124128

125-
if (!qdl_match_usb_serial(handle, serial, &desc)) {
129+
if (!usb_match_usb_serial(handle, serial, &desc)) {
126130
libusb_close(handle);
127131
continue;
128132
}
@@ -160,10 +164,11 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *
160164
return !!qdl->usb_handle;
161165
}
162166

163-
int qdl_open(struct qdl_device *qdl, const char *serial)
167+
static int usb_open(struct qdl_device *qdl, const char *serial)
164168
{
165169
struct libusb_device **devs;
166170
struct libusb_device *dev;
171+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
167172
bool wait_printed = false;
168173
bool found = false;
169174
ssize_t n;
@@ -182,7 +187,7 @@ int qdl_open(struct qdl_device *qdl, const char *serial)
182187
for (i = 0; devs[i]; i++) {
183188
dev = devs[i];
184189

185-
ret = qdl_try_open(dev, qdl, serial);
190+
ret = usb_try_open(dev, qdl_usb, serial);
186191
if (ret == 1) {
187192
found = true;
188193
break;
@@ -205,38 +210,42 @@ int qdl_open(struct qdl_device *qdl, const char *serial)
205210
return -1;
206211
}
207212

208-
void qdl_close(struct qdl_device *qdl)
213+
static void usb_close(struct qdl_device *qdl)
209214
{
210-
libusb_close(qdl->usb_handle);
215+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
216+
217+
libusb_close(qdl_usb->usb_handle);
211218
libusb_exit(NULL);
212219
}
213220

214-
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
221+
static int usb_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout)
215222
{
223+
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
216224
int actual;
217225
int ret;
218226

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

224232
return actual;
225233
}
226234

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

236245
while (len > 0) {
237-
xfer = (len > qdl->out_chunk_size) ? qdl->out_chunk_size : len;
246+
xfer = (len > qdl_usb->out_chunk_size) ? qdl_usb->out_chunk_size : len;
238247

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

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

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

0 commit comments

Comments
 (0)