mirror of
https://github.com/linux-msm/qdl.git
synced 2026-02-25 13:12:25 -08:00
firehose: Negotiate max payload size
When the host propose a larger payload size than the device accepts the device will respond with a NACK, containing the maximum payload size. Similarily the ACK will contain the supported max if the host requests a lower value than the device supports. In both cases we pick the largest possible value and send a second configure message to select this payload size. Reported-by: Kirill Kapranov <c_kkapra@qti.qualcomm.com> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
58
firehose.c
58
firehose.c
@@ -229,22 +229,41 @@ static int firehose_nop(int fd)
|
||||
|
||||
static size_t max_payload_size = 1048576;
|
||||
|
||||
/**
|
||||
* firehose_configure_response_parser() - parse a configure response
|
||||
* @node: response xmlNode
|
||||
*
|
||||
* Return: max size supported by the remote, or negative errno on failure
|
||||
*/
|
||||
static int firehose_configure_response_parser(xmlNode *node)
|
||||
{
|
||||
xmlChar *payload;
|
||||
xmlChar *value;
|
||||
size_t max_size;
|
||||
|
||||
value = xmlGetProp(node, (xmlChar*)"value");
|
||||
if (xmlStrcmp(value, (xmlChar*)"ACK"))
|
||||
payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytes");
|
||||
if (!value || !payload)
|
||||
return -EINVAL;
|
||||
|
||||
value = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytes");
|
||||
if (value)
|
||||
max_payload_size = strtoul((char*)value, NULL, 10);
|
||||
max_size = strtoul((char*)payload, NULL, 10);
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* When receiving an ACK the remote may indicate that we should attempt
|
||||
* a larger payload size
|
||||
*/
|
||||
if (!xmlStrcmp(value, (xmlChar*)"ACK")) {
|
||||
payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytesSupported");
|
||||
if (!payload)
|
||||
return -EINVAL;
|
||||
|
||||
max_size = strtoul((char*)payload, NULL, 10);
|
||||
}
|
||||
|
||||
return max_size;
|
||||
}
|
||||
|
||||
static int firehose_configure(int fd)
|
||||
static int firehose_send_configure(int fd, size_t payload_size)
|
||||
{
|
||||
xmlNode *root;
|
||||
xmlNode *node;
|
||||
@@ -257,7 +276,7 @@ static int firehose_configure(int fd)
|
||||
|
||||
node = xmlNewChild(root, NULL, (xmlChar*)"configure", NULL);
|
||||
xml_setpropf(node, "MemoryName", "ufs");
|
||||
xml_setpropf(node, "MaxPayloadSizeToTargetInBytes", "%d", max_payload_size);
|
||||
xml_setpropf(node, "MaxPayloadSizeToTargetInBytes", "%d", payload_size);
|
||||
xml_setpropf(node, "verbose", "%d", 0);
|
||||
xml_setpropf(node, "ZLPAwareHost", "%d", 0);
|
||||
|
||||
@@ -268,6 +287,31 @@ static int firehose_configure(int fd)
|
||||
return firehose_read(fd, -1, firehose_configure_response_parser);
|
||||
}
|
||||
|
||||
static int firehose_configure(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = firehose_send_configure(fd, max_payload_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Retry if remote proposed different size */
|
||||
if (ret != max_payload_size) {
|
||||
ret = firehose_send_configure(fd, ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
max_payload_size = ret;
|
||||
}
|
||||
|
||||
if (qdl_debug) {
|
||||
fprintf(stderr, "[CONFIGURE] max payload size: %ld\n",
|
||||
max_payload_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user