restore large xfer workaround
sadly, it's not possible to gracefully switch from large to blocked xfers, further xfer ioctls fail after the first large xfer fails.
This commit is contained in:
parent
fc7295eb74
commit
89dd515ae5
1 changed files with 41 additions and 5 deletions
|
|
@ -12,6 +12,42 @@
|
|||
|
||||
namespace piomatter {
|
||||
|
||||
static int pio_sm_xfer_data_large(PIO pio, int sm, int direction, size_t size,
|
||||
uint32_t *databuf) {
|
||||
#if 0
|
||||
// it would be NICE to gracefully fall back to blocked transfer, but sadly
|
||||
// once the large xfer ioctl fails, future small xfers fail too.
|
||||
static enum { UNKNOWN, OK, BAD } large_xfer_status = UNKNOWN;
|
||||
printf("large_xfer_status=%d\n", large_xfer_status);
|
||||
if (large_xfer_status != BAD) {
|
||||
int r = pio_sm_xfer_data(pio, sm, direction, size, databuf);
|
||||
if (large_xfer_status == UNKNOWN && r != 0) {
|
||||
large_xfer_status = BAD;
|
||||
fprintf(stderr,
|
||||
"Transmission limit workaround engaged. May reduce quality of "
|
||||
"output.\nSee https://github.com/raspberrypi/utils/issues/123 "
|
||||
"for details.\n");
|
||||
} else {
|
||||
if (large_xfer_status == UNKNOWN && r == 0) {
|
||||
large_xfer_status = OK;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
constexpr size_t MAX_XFER = 65532;
|
||||
while (size) {
|
||||
size_t xfersize = std::min(size_t{MAX_XFER}, size);
|
||||
int r = pio_sm_xfer_data(pio, sm, direction, xfersize, databuf);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
size -= xfersize;
|
||||
databuf += xfersize / sizeof(*databuf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t monotonicns64() {
|
||||
struct timespec tp;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
|
|
@ -181,12 +217,12 @@ struct piomatter : piomatter_base {
|
|||
auto dataptr = const_cast<uint32_t *>(&data[0]);
|
||||
// returns err = rp1_ioctl.... which seems to be a negative
|
||||
// errno value
|
||||
int r =
|
||||
pio_sm_xfer_data(pio, sm, PIO_DIR_TO_SM, datasize, dataptr);
|
||||
int r = pio_sm_xfer_data_large(pio, sm, PIO_DIR_TO_SM, datasize,
|
||||
dataptr);
|
||||
if (r != 0) {
|
||||
pending_error_errno.store(-r);
|
||||
printf("xfer_data() returned error %d (%s)\n", r,
|
||||
strerror(-r));
|
||||
pending_error_errno.store(errno);
|
||||
printf("xfer_data() returned error %d (errno=%s)\n", r,
|
||||
strerror(errno));
|
||||
}
|
||||
t1 = monotonicns64();
|
||||
if (t0 != t1) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue