Skip to content

Commit 1f15c37

Browse files
author
Loic Poulain
committed
usb: increase firehose raw write timeout to 10 seconds
During QRB2210 provisioning, a USB write failure has been observed early in the Firehose phase (first block write). This issue has been traced to a timeout during the USB bulk transfer of the Zero-Length Packet (ZLP). In some conditions, the ZLP transfer may take longer than the current timeout, up to approximately 1.7 seconds. The issue specifically occurs after a prior large eMMC write operation (e.g., during a previous QDL session). It could then be related to internal eMMC I/O operations or timing delays affecting the USB ack. To resolve this issue, we introduce a timeout parameter to the qdl_write function, consistent with the existing qdl_read, and we increase the timeout to 10 seconds for Firehose raw binary write operations to avoid 'false-positive' timeout. Signed-off-by: Loic Poulain <[email protected]>
1 parent f3b4fd4 commit 1f15c37

File tree

8 files changed

+25
-20
lines changed

8 files changed

+25
-20
lines changed

firehose.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "vip.h"
2929
#include "sparse.h"
3030

31+
#define FIREHOSE_WR_TIMEOUT_MS 30000
32+
3133
enum {
3234
FIREHOSE_ACK = 0,
3335
FIREHOSE_NAK,
@@ -228,7 +230,7 @@ static int firehose_write(struct qdl_device *qdl, xmlDoc *doc)
228230
for (;;) {
229231
ux_debug("FIREHOSE WRITE: %s\n", s);
230232
vip_gen_chunk_update(qdl, s, len);
231-
ret = qdl_write(qdl, s, len);
233+
ret = qdl_write(qdl, s, len, 1000);
232234
saved_errno = errno;
233235

234236
/*
@@ -560,7 +562,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int
560562

561563
vip_transfer_clear_status(qdl);
562564
}
563-
n = qdl_write(qdl, buf, chunk_size * sector_size);
565+
n = qdl_write(qdl, buf, chunk_size * sector_size, 10000);
564566
if (n < 0) {
565567
ux_err("USB write failed for data chunk\n");
566568
ret = firehose_read(qdl, 30000, firehose_generic_parser, NULL);

io.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout
5858
* @qdl: device handle
5959
* @buf: buffer with data to be written
6060
* @len: length of data to be written
61+
* @timeout: timeout for write, in milliseconds
6162
*
6263
* Returns: number of bytes read
6364
* negative errno on failure (notably -ETIMEDOUT)
6465
*/
65-
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
66+
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, unsigned int timeout)
6667
{
67-
return qdl->write(qdl, buf, len);
68+
return qdl->write(qdl, buf, len, timeout);
6869
}

ks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout
2929
return read(qdl->fd, buf, len);
3030
}
3131

32-
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
32+
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, unsigned int timeout)
3333
{
3434
return write(qdl->fd, buf, len);
3535
}

qdl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct qdl_device {
4343

4444
int (*open)(struct qdl_device *qdl, const char *serial);
4545
int (*read)(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
46-
int (*write)(struct qdl_device *qdl, const void *buf, size_t nbytes);
46+
int (*write)(struct qdl_device *qdl, const void *buf, size_t nbytes, unsigned int timeout);
4747
void (*close)(struct qdl_device *qdl);
4848
void (*set_out_chunk_size)(struct qdl_device *qdl, long size);
4949
void (*set_vip_transfer)(struct qdl_device *qdl, const char *signed_table,
@@ -61,7 +61,7 @@ void qdl_deinit(struct qdl_device *qdl);
6161
int qdl_open(struct qdl_device *qdl, const char *serial);
6262
void qdl_close(struct qdl_device *qdl);
6363
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
64-
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len);
64+
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, unsigned int timeout);
6565
void qdl_set_out_chunk_size(struct qdl_device *qdl, long size);
6666
int qdl_vip_transfer_enable(struct qdl_device *qdl, const char *vip_table_path);
6767

sahara.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060

6161
#define DEBUG_BLOCK_SIZE (512 * 1024)
6262

63+
#define SAHARA_CMD_TIMEOUT_MS 1000
64+
6365
struct sahara_pkt {
6466
uint32_t cmd;
6567
uint32_t length;
@@ -120,7 +122,7 @@ static void sahara_send_reset(struct qdl_device *qdl)
120122
resp.cmd = SAHARA_RESET_CMD;
121123
resp.length = SAHARA_RESET_LENGTH;
122124

123-
qdl_write(qdl, &resp, resp.length);
125+
qdl_write(qdl, &resp, resp.length, SAHARA_CMD_TIMEOUT_MS);
124126
}
125127

126128
static void sahara_hello(struct qdl_device *qdl, struct sahara_pkt *pkt)
@@ -139,7 +141,7 @@ static void sahara_hello(struct qdl_device *qdl, struct sahara_pkt *pkt)
139141
resp.hello_resp.status = SAHARA_SUCCESS;
140142
resp.hello_resp.mode = pkt->hello_req.mode;
141143

142-
qdl_write(qdl, &resp, resp.length);
144+
qdl_write(qdl, &resp, resp.length, SAHARA_CMD_TIMEOUT_MS);
143145
}
144146

145147
static int sahara_read_common(struct qdl_device *qdl, int progfd, off_t offset, size_t len)
@@ -159,7 +161,7 @@ static int sahara_read_common(struct qdl_device *qdl, int progfd, off_t offset,
159161
goto out;
160162
}
161163

162-
n = qdl_write(qdl, buf, n);
164+
n = qdl_write(qdl, buf, n, SAHARA_CMD_TIMEOUT_MS);
163165
if (n != len)
164166
err(1, "failed to write %zu bytes to sahara", len);
165167

@@ -259,7 +261,7 @@ static void sahara_eoi(struct qdl_device *qdl, struct sahara_pkt *pkt)
259261

260262
done.cmd = SAHARA_DONE_CMD;
261263
done.length = SAHARA_DONE_LENGTH;
262-
qdl_write(qdl, &done, done.length);
264+
qdl_write(qdl, &done, done.length, SAHARA_CMD_TIMEOUT_MS);
263265
}
264266

265267
static int sahara_done(struct qdl_device *qdl, struct sahara_pkt *pkt)
@@ -309,7 +311,7 @@ static ssize_t sahara_debug64_one(struct qdl_device *qdl,
309311
read_req.length = SAHARA_MEM_READ64_LENGTH;
310312
read_req.debug64_req.addr = region.addr + chunk;
311313
read_req.debug64_req.length = remain;
312-
n = qdl_write(qdl, &read_req, read_req.length);
314+
n = qdl_write(qdl, &read_req, read_req.length, SAHARA_CMD_TIMEOUT_MS);
313315
if (n < 0)
314316
break;
315317

@@ -405,13 +407,13 @@ static void sahara_debug64(struct qdl_device *qdl, struct sahara_pkt *pkt,
405407
read_req.debug64_req.addr = pkt->debug64_req.addr;
406408
read_req.debug64_req.length = pkt->debug64_req.length;
407409

408-
n = qdl_write(qdl, &read_req, read_req.length);
410+
n = qdl_write(qdl, &read_req, read_req.length, SAHARA_CMD_TIMEOUT_MS);
409411
if (n < 0)
410412
return;
411413

412414
table = malloc(read_req.debug64_req.length);
413415

414-
n = qdl_read(qdl, table, pkt->debug64_req.length, 1000);
416+
n = qdl_read(qdl, table, pkt->debug64_req.length, SAHARA_CMD_TIMEOUT_MS);
415417
if (n < 0)
416418
return;
417419

@@ -451,7 +453,7 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
451453
return 0;
452454

453455
while (!done) {
454-
n = qdl_read(qdl, buf, sizeof(buf), 1000);
456+
n = qdl_read(qdl, buf, sizeof(buf), SAHARA_CMD_TIMEOUT_MS);
455457
if (n < 0) {
456458
ux_err("failed to read sahara request from device\n");
457459
break;

sim.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ static int sim_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int
2727
return len;
2828
}
2929

30-
static int sim_write(struct qdl_device *qdl, const void *buf, size_t len)
30+
static int sim_write(struct qdl_device *qdl, const void *buf, size_t len, unsigned int timeout)
3131
{
3232
return len;
3333
}

usb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static int usb_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int
247247
return actual;
248248
}
249249

250-
static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
250+
static int usb_write(struct qdl_device *qdl, const void *buf, size_t len, unsigned int timeout)
251251
{
252252
unsigned char *data = (unsigned char *)buf;
253253
struct qdl_device_usb *qdl_usb = container_of(qdl, struct qdl_device_usb, base);
@@ -261,7 +261,7 @@ static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
261261
xfer = (len > qdl_usb->out_chunk_size) ? qdl_usb->out_chunk_size : len;
262262

263263
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, data,
264-
xfer, &actual, 1000);
264+
xfer, &actual, timeout);
265265
if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) {
266266
warnx("bulk write failed: %s", libusb_strerror(ret));
267267
return -EIO;
@@ -276,7 +276,7 @@ static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
276276

277277
if (len_orig % qdl_usb->out_maxpktsize == 0) {
278278
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, NULL,
279-
0, &actual, 1000);
279+
0, &actual, timeout);
280280
if (ret < 0)
281281
return -EIO;
282282
}

vip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ static int vip_transfer_send_raw(struct qdl_device *qdl, int table_fd)
432432
goto out;
433433
}
434434

435-
n = qdl_write(qdl, buf, sb.st_size);
435+
n = qdl_write(qdl, buf, sb.st_size, 1000);
436436
if (n < 0) {
437437
ux_err("USB write failed for data chunk\n");
438438
ret = -1;

0 commit comments

Comments
 (0)