Commit 760b3dff authored by John Stultz's avatar John Stultz Committed by Bjorn Andersson
Browse files

qdl: Rework qdl_write to limit write sizes to out_maxpktsize



On a number of machines, qdl could cause crashes on the host
system it ran on, due to swiotlb exaustion.

This seems to be due to 1M buffers being used during the writes.

In order to avoid this, rework qdl_write to break up the writes
into out_maxpktsize chunks.

With this patch, I no longer see host crashes when running qdl

Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Amit Pundir <amit.pundir@linaro.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: dragonboard-aosp@lists.96boards.org
Tested-by: default avatarNicolas Dechesne <nicolas.dechesne@linaro.org>
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
[bjorn: Dropped change of max_payload_size]
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 7623ff5e
......@@ -354,20 +354,49 @@ int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, bool eot)
{
unsigned char *data = (unsigned char*) buf;
struct usbdevfs_bulktransfer bulk = {};
int ret;
unsigned count = 0;
size_t len_orig = len;
int n;
bulk.ep = qdl->out_ep;
bulk.len = len;
bulk.data = (void *)buf;
bulk.timeout = 10000;
if(len == 0) {
bulk.ep = qdl->out_ep;
bulk.len = 0;
bulk.data = data;
bulk.timeout = 1000;
ret = ioctl(qdl->fd, USBDEVFS_BULK, &bulk);
if (ret < 0)
return ret;
n = ioctl(qdl->fd, USBDEVFS_BULK, &bulk);
if(n != 0) {
fprintf(stderr,"ERROR: n = %d, errno = %d (%s)\n",
n, errno, strerror(errno));
return -1;
}
return 0;
}
while(len > 0) {
int xfer;
xfer = (len > qdl->out_maxpktsize) ? qdl->out_maxpktsize : len;
bulk.ep = qdl->out_ep;
bulk.len = xfer;
bulk.data = data;
bulk.timeout = 1000;
n = ioctl(qdl->fd, USBDEVFS_BULK, &bulk);
if(n != xfer) {
fprintf(stderr, "ERROR: n = %d, errno = %d (%s)\n",
n, errno, strerror(errno));
return -1;
}
count += xfer;
len -= xfer;
data += xfer;
}
if (eot && (len % qdl->out_maxpktsize) == 0) {
if (eot && (len_orig % qdl->out_maxpktsize) == 0) {
bulk.ep = qdl->out_ep;
bulk.len = 0;
bulk.data = NULL;
......@@ -378,7 +407,7 @@ int qdl_write(struct qdl_device *qdl, const void *buf, size_t len, bool eot)
return n;
}
return ret;
return count;
}
static void print_usage(void)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment