diff --git a/src/libosmo-fl2k.c b/src/libosmo-fl2k.c index 1112539..7748238 100644 --- a/src/libosmo-fl2k.c +++ b/src/libosmo-fl2k.c @@ -591,11 +591,26 @@ static int fl2k_alloc_submit_transfers(fl2k_dev_t *dev) for (i = 0; i < dev->xfer_buf_num; ++i) { dev->xfer_buf[i] = libusb_dev_mem_alloc(dev->devh, dev->xfer_buf_len); - if (!dev->xfer_buf[i]) { + if (dev->xfer_buf[i]) { + /* Check if Kernel usbfs mmap() bug is present: if the + * mapping is correct, the buffers point to memory that + * was memset to 0 by the Kernel, otherwise, they point + * to random memory. We check if the buffers are zeroed + * and otherwise fall back to buffers in userspace. + */ + if (dev->xfer_buf[i][0] || memcmp(dev->xfer_buf[i], + dev->xfer_buf[i] + 1, + dev->xfer_buf_len - 1)) { + fprintf(stderr, "Detected Kernel usbfs mmap() " + "bug, falling back to buffers " + "in userspace\n"); + dev->use_zerocopy = 0; + break; + } + } else { fprintf(stderr, "Failed to allocate zero-copy " "buffer for transfer %d\nFalling " "back to buffers in userspace\n", i); - dev->use_zerocopy = 0; break; }