Skip to content

Commit 9b2e935

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 3ed79be commit 9b2e935

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
@@ -59,7 +59,6 @@ enum {
5959
};
6060

6161
bool qdl_debug;
62-
static struct qdl_device qdl;
6362

6463
static int detect_type(const char *xml_file)
6564
{
@@ -125,7 +124,9 @@ int main(int argc, char **argv)
125124
int opt;
126125
bool qdl_finalize_provisioning = false;
127126
bool allow_missing = false;
128-
long out_chunk_size;
127+
long out_chunk_size = 0;
128+
struct qdl_device *qdl = NULL;
129+
enum QDL_DEVICE_TYPE qdl_dev_type = QDL_DEVICE_USB;
129130

130131
static struct option options[] = {
131132
{"debug", no_argument, 0, 'd'},
@@ -158,7 +159,6 @@ int main(int argc, char **argv)
158159
break;
159160
case OPT_OUT_CHUNK_SIZE:
160161
out_chunk_size = strtol(optarg, NULL, 10);
161-
qdl_set_out_chunk_size(&qdl, out_chunk_size);
162162
break;
163163
case 's':
164164
storage = optarg;
@@ -178,6 +178,15 @@ int main(int argc, char **argv)
178178
return 1;
179179
}
180180

181+
qdl = qdl_init(qdl_dev_type);
182+
if (!qdl) {
183+
ret = -1;
184+
goto out_cleanup;
185+
}
186+
187+
if (out_chunk_size)
188+
qdl_set_out_chunk_size(qdl, out_chunk_size);
189+
181190
ux_init();
182191

183192
if (qdl_debug)
@@ -217,23 +226,25 @@ int main(int argc, char **argv)
217226
}
218227
} while (++optind < argc);
219228

220-
ret = qdl_open(&qdl, serial);
229+
ret = qdl_open(qdl, serial);
221230
if (ret)
222231
goto out_cleanup;
223232

224-
qdl.mappings[0] = prog_mbn;
225-
ret = sahara_run(&qdl, qdl.mappings, true, NULL, NULL);
233+
qdl->mappings[0] = prog_mbn;
234+
ret = sahara_run(qdl, qdl->mappings, true, NULL, NULL);
226235
if (ret < 0)
227236
goto out_cleanup;
228237

229-
ret = firehose_run(&qdl, incdir, storage, allow_missing);
238+
ret = firehose_run(qdl, incdir, storage, allow_missing);
230239
if (ret < 0)
231240
goto out_cleanup;
232241

233242
out_cleanup:
234-
qdl_close(&qdl);
243+
qdl_close(qdl);
235244
free_programs();
236245
free_patches();
237246

247+
qdl_deinit(qdl);
248+
238249
return !!ret;
239250
}

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)