From 760b3dffb03d2b7dfb82c6eac652a092f51c572d Mon Sep 17 00:00:00 2001 From: John Stultz <john.stultz@linaro.org> Date: Tue, 30 Apr 2019 16:55:56 -0700 Subject: [PATCH] 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: Nicolas Dechesne <nicolas.dechesne@linaro.org> Signed-off-by: John Stultz <john.stultz@linaro.org> [bjorn: Dropped change of max_payload_size] Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> --- qdl.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/qdl.c b/qdl.c index 2b523d2..47debd9 100644 --- a/qdl.c +++ b/qdl.c @@ -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) -- GitLab