Загрузка данных


static int sysconfig_i2c_bitstream_burst_write(struct sysconfig_priv *priv, const char *buf, size_t len)
{
    struct i2c_client *client = to_i2c_client(priv->dev);
    struct i2c_msg msg;
    const u8 lsc_bitstream_burst[] = { 0x7A, 0x00, 0x00, 0x00 };
    int ret;

    if (len == 0)
        return 0;

    /* 
     * ВНИМАНИЕ: Считаем выравнивание ТАК, чтобы ОБЩИЙ РАЗМЕР БУФЕРА (Команда + Файл + Паддинг)
     * был строго кратен 32 байтам! 
     * Текущий размер без паддинга = 4 (команда) + 808325 (файл) = 808329.
     * Ближайшее число, кратное 32 — это 808352.
     */
    size_t current_total = sizeof(lsc_bitstream_burst) + len;
    size_t total_alloc_size = (current_total + 31) & ~31; // Округляем весь буфер до кратности 32
    size_t total_padding = total_alloc_size - current_total;
    
    /* Выделяем монолитный буфер, который идеально делится на 32 */
    u8 *tx_buf = kmalloc(total_alloc_size, GFP_KERNEL);
    if (!tx_buf)
        return -ENOMEM;

    /* Копируем команду 0x7A 00 00 00 в самое начало */
    memcpy(tx_buf, lsc_bitstream_burst, sizeof(lsc_bitstream_burst));
    
    /* Копируем весь ваш файл */
    memcpy(tx_buf + sizeof(lsc_bitstream_burst), buf, len);
    
    /* Забиваем оставшийся хвост до кратности 32 безопасными байтами NOP (0xFF) */
    if (total_padding > 0) {
        memset(tx_buf + sizeof(lsc_bitstream_burst) + len, 0xFF, total_padding);
    }

    printk("%s: Launching strict 32-byte aligned DMA transfer. Total size = %zu bytes (Padding: %zu)\n", 
            __FUNCTION__, total_alloc_size, total_padding);

    msg.addr = client->addr;
    msg.flags = 0; 
    msg.len = total_alloc_size;
    msg.buf = tx_buf;

    /* Передаем в lpi2c. Теперь find_max_burst_num вернет ровно 32! */
    ret = i2c_transfer(client->adapter, &msg, 1);
    
    kfree(tx_buf);

    if (ret != 1) {
        dev_err(priv->dev, "Monolithic strict DMA transfer failed: %d\n", ret);
        return (ret < 0) ? ret : -EIO;
    }

    return 0;
}