From 3e804d4542d7e1e8f34542c71189dbfe6935ae17 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 16 Dec 2024 22:30:21 +0000 Subject: [PATCH] piolib: Increase data_bytes range to 32-bits In many places, the number of bytes in a data transfer is stored as a 32-bit (or greater) value, but the ioctl API to the kernel stores it in a 16-bit field, alongside which is a 16-bit gap due to the alignment requirements of the pointer that follows. Increase the size of data_bytes to a uint32_t, so that it can handle larger transfers. Since using different sizes as either end can lead to unpredictable results, a separate IOCTL is used for larger transfers, allowing the kernel support to be determined and backwards compatibility to be maintained. See: https://github.com/raspberrypi/utils/issues/107 Signed-off-by: Phil Elwell --- piolib/include/rp1_pio_if.h | 12 ++++++++---- piolib/pio_rp1.c | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/piolib/include/rp1_pio_if.h b/piolib/include/rp1_pio_if.h index 84e749e..5581ab8 100644 --- a/piolib/include/rp1_pio_if.h +++ b/piolib/include/rp1_pio_if.h @@ -167,6 +167,13 @@ struct rp1_pio_sm_xfer_data_args { void *data; }; +struct rp1_pio_sm_xfer_data32_args { + uint16_t sm; + uint16_t dir; + uint32_t data_bytes; + void *data; +}; + struct rp1_access_hw_args { uint32_t addr; uint32_t len; @@ -177,10 +184,7 @@ struct rp1_access_hw_args { #define PIO_IOC_SM_CONFIG_XFER _IOW(PIO_IOC_MAGIC, 0, struct rp1_pio_sm_config_xfer_args) #define PIO_IOC_SM_XFER_DATA _IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args) - -#ifdef CONFIG_COMPAT -//XXX #define PIO_IOC_SM_XFER_DATA32 _IOW(PIO_IOC_MAGIC, 2, struct pio_sm_xfer_data_args) -#endif +#define PIO_IOC_SM_XFER_DATA32 _IOW(PIO_IOC_MAGIC, 2, struct rp1_pio_sm_xfer_data32_args) #define PIO_IOC_READ_HW _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args) #define PIO_IOC_WRITE_HW _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args) diff --git a/piolib/pio_rp1.c b/piolib/pio_rp1.c index 41e1f66..0d9d222 100644 --- a/piolib/pio_rp1.c +++ b/piolib/pio_rp1.c @@ -265,9 +265,13 @@ static int rp1_pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size, uin static int rp1_pio_sm_xfer_data(PIO pio, uint sm, uint dir, uint data_bytes, void *data) { struct rp1_pio_sm_xfer_data_args args = { .sm = sm, .dir = dir, .data_bytes = data_bytes, .data = data }; + struct rp1_pio_sm_xfer_data32_args args32 = { .sm = sm, .dir = dir, .data_bytes = data_bytes, .data = data }; int err; check_sm_param(sm); - err = rp1_ioctl(pio, PIO_IOC_SM_XFER_DATA, &args); + if (data_bytes > 0xffff) + err = rp1_ioctl(pio, PIO_IOC_SM_XFER_DATA32, &args32); + else + err = rp1_ioctl(pio, PIO_IOC_SM_XFER_DATA, &args); return (err > 0); }