Skip to content

Commit 841a0a8

Browse files
quic-bjorandeandersson
authored andcommitted
firehose: Improve startup time significantly
The firehose_read() at the start of firehose_run() serves the purpose of waiting for the programmer to show up and to consume any <log/> messages spat out, so that we're ready to invoke the <configure/>. On MSM8916 there are no <log/> entries, so this is a 5 second loop hitting -ETIMEDOUTs in firehose_read(). On other tested targets, it does drain the <log/> entries and then hits -ETIMEDOUTs for the remainder of 5 seconds. On the newer targets, we could perhaps determine when the programmer is up by looking for <log/> entries, but this doesn't help the MSM8916 model and it doesn't fit with the current implementation. If we instead tweak the timeouts and error handling of firehose_configure(), we can speculatively attempt to configure the programmer until success. This meets both the observed models, and shows savings between 4 and 4.5 seconds in startup time across the tested devices. Signed-off-by: Bjorn Andersson <[email protected]>
1 parent 5449037 commit 841a0a8

File tree

3 files changed

+53
-21
lines changed

3 files changed

+53
-21
lines changed

firehose.c

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ static int firehose_send_configure(struct qdl_device *qdl, size_t payload_size,
305305
xmlNode *root;
306306
xmlNode *node;
307307
xmlDoc *doc;
308-
int ret;
309308

310309
doc = xmlNewDoc((xmlChar *)"1.0");
311310
root = xmlNewNode(NULL, (xmlChar *)"data");
@@ -318,16 +317,14 @@ static int firehose_send_configure(struct qdl_device *qdl, size_t payload_size,
318317
xml_setpropf(node, "ZLPAwareHost", "%d", 1);
319318
xml_setpropf(node, "SkipStorageInit", "%d", skip_storage_init);
320319

321-
ret = firehose_write(qdl, doc);
320+
firehose_write(qdl, doc);
322321
xmlFreeDoc(doc);
323-
if (ret < 0)
324-
return ret;
325322

326-
return firehose_read(qdl, 5000, firehose_configure_response_parser, max_payload_size);
323+
return firehose_read(qdl, 100, firehose_configure_response_parser, max_payload_size);
327324
}
328325

329-
static int firehose_configure(struct qdl_device *qdl, bool skip_storage_init,
330-
const char *storage)
326+
static int firehose_try_configure(struct qdl_device *qdl, bool skip_storage_init,
327+
const char *storage)
331328
{
332329
size_t max_sector_size;
333330
size_t sector_sizes[] = { 512, 4096 };
@@ -339,10 +336,8 @@ static int firehose_configure(struct qdl_device *qdl, bool skip_storage_init,
339336

340337
ret = firehose_send_configure(qdl, qdl->max_payload_size, skip_storage_init,
341338
storage, &size);
342-
if (ret < 0) {
343-
ux_err("configure request failed\n");
344-
return -1;
345-
}
339+
if (ret < 0)
340+
return ret;
346341

347342
/*
348343
* In simulateion mode "remote" target can't propose different size, so
@@ -932,13 +927,42 @@ static int firehose_reset(struct qdl_device *qdl)
932927
return ret == FIREHOSE_ACK ? 0 : -1;
933928
}
934929

935-
int firehose_provision(struct qdl_device *qdl)
930+
static int firehose_detect_and_configure(struct qdl_device *qdl,
931+
bool skip_storage_init,
932+
const char *storage,
933+
unsigned int timeout_s)
936934
{
935+
struct timeval timeout = { .tv_sec = timeout_s };
936+
struct timeval now;
937937
int ret;
938938

939-
firehose_read(qdl, 5000, firehose_generic_parser, NULL);
939+
gettimeofday(&now, NULL);
940+
timeradd(&now, &timeout, &timeout);
941+
for (;;) {
942+
ret = firehose_try_configure(qdl, false, storage);
940943

941-
ret = firehose_configure(qdl, true, "ufs");
944+
if (ret == FIREHOSE_ACK) {
945+
break;
946+
} else if (ret != -ETIMEDOUT) {
947+
ux_err("configure request failed\n");
948+
return -1;
949+
}
950+
951+
gettimeofday(&now, NULL);
952+
if (timercmp(&now, &timeout, >)) {
953+
ux_err("failed to detect firehose programmer\n");
954+
return -1;
955+
}
956+
}
957+
958+
return 0;
959+
}
960+
961+
int firehose_provision(struct qdl_device *qdl)
962+
{
963+
int ret;
964+
965+
ret = firehose_detect_and_configure(qdl, true, "ufs", 5);
942966
if (ret)
943967
return ret;
944968

@@ -964,9 +988,7 @@ int firehose_run(struct qdl_device *qdl, const char *storage)
964988

965989
ux_info("waiting for programmer...\n");
966990

967-
firehose_read(qdl, 5000, firehose_generic_parser, NULL);
968-
969-
ret = firehose_configure(qdl, false, storage);
991+
ret = firehose_detect_and_configure(qdl, true, storage, 5);
970992
if (ret)
971993
return ret;
972994

io.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout
5353
return qdl->read(qdl, buf, len, timeout);
5454
}
5555

56+
/**
57+
* qdl_write() - Write a message from the device
58+
* @qdl: device handle
59+
* @buf: buffer with data to be written
60+
* @len: length of data to be written
61+
*
62+
* Returns: number of bytes read
63+
* negative errno on failure (notably -ETIMEDOUT)
64+
*/
5665
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)
5766
{
5867
return qdl->write(qdl, buf, len);

usb.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,12 @@ static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
262262

263263
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, data,
264264
xfer, &actual, 1000);
265-
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
266-
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0)) {
265+
if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) {
267266
warnx("bulk write failed: %s", libusb_strerror(ret));
268-
return -1;
267+
return -EIO;
269268
}
269+
if (ret == LIBUSB_ERROR_TIMEOUT && actual == 0)
270+
return -ETIMEDOUT;
270271

271272
count += actual;
272273
len -= actual;
@@ -277,7 +278,7 @@ static int usb_write(struct qdl_device *qdl, const void *buf, size_t len)
277278
ret = libusb_bulk_transfer(qdl_usb->usb_handle, qdl_usb->out_ep, NULL,
278279
0, &actual, 1000);
279280
if (ret < 0)
280-
return -1;
281+
return -EIO;
281282
}
282283

283284
return count;

0 commit comments

Comments
 (0)