Struct allocation size breaks spi_sync_transfer

1

I'm playing with the linux spi driver on a raspberry Pi. Using a logic analyzer, I can observe what happens on the bus. My problem is that nothing gets transmitted if I change the memory size allocated for the spi_transfer struct :

To summarize, the code below works fine with kmalloc(sizeof(struct spi_transfer)*1,GFP_KERNEL); but not with kmalloc(sizeof(struct spi_transfer)*2,GFP_KERNEL);

I'm using a Raspberry PI 3 with Raspbian. My kernel version is 4.19.64.

union command_u
{
    uint8_t buf[4];
    uint32_t u32;
};
uint16_t ads8661_read(uint16_t address)
{
    address &= 0x01fc;
    uint32_t ret0;
    union command_u ret;
    union command_u payload = {.buf = {0xc8 | (address >> 8), address, 0x00, 0x00}};

    struct spi_transfer * trans_array= kmalloc(sizeof(struct spi_transfer)*1,GFP_KERNEL);

    if(trans_array){
        printk(KERN_NOTICE "Malloc Worked :)");
        trans_array[0].tx_buf = &payload;
        trans_array[0].rx_buf = &ret;
        trans_array[0].len = sizeof(payload);
        spi_sync_transfer(spi_dev,trans_array,1);
        kfree(trans_array);

    }else{
        printk(KERN_ALERT "Malloc Failed :/");
    }
    return 0;
}

I assume that the memory allocation doesn't fail because i'm seeing the Malloc Worked :) when I'm executing dmesg. I also tried allocating 3*sizeof(spi_transfer), didn't work either.

I tried to allocate 2 spi_transfer and modifying the argument number of spi_transfer of the spi_sync_transfer function to 2 but didnt work either.

Any feedback or suggestion welcome

EDIT: I've also tried to allocate and use 2 spi_transfer

union command_u
{
    uint8_t buf[4];
    uint32_t u32;
};
uint16_t ads8661_read(uint16_t address)
{
    address &= 0x01fc;
    uint32_t ret0;
    union command_u ret;
    union command_u payload = {.buf = {0xc8 | (address >> 8), address, 0x00, 0x00}};
    union command_u payload_nop = {.u32 = 0x00000000};

    struct spi_transfer * trans_array = kmalloc_array(2,sizeof(struct spi_transfer),GFP_KERNEL);

    if(trans_array){
        printk(KERN_NOTICE "Malloc Worked :)");

        trans_array[0].tx_buf = &payload;
        trans_array[0].rx_buf = &ret0;
        trans_array[0].len = sizeof(payload);

        trans_array[1].tx_buf = &payload_nop;
        trans_array[1].rx_buf = &ret;
        trans_array[1].len = sizeof(payload);

        spi_sync_transfer(ads8661_device.spi_dev,trans_array,2);
        kfree(trans_array);

    }else{
        printk(KERN_ALERT "Malloc Failed :/");
    }

    // Invert endianness
    return ((uint16_t)ret.buf[0] << 8) | ret.buf[1];
}
c
linux-kernel
linux-device-driver
raspberry-pi3
spi
asked on Stack Overflow Aug 19, 2019 by Hugo REYMOND • edited Aug 21, 2019 by Hugo REYMOND

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0