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];
}
User contributions licensed under CC BY-SA 3.0