We are updating from an ARM embedded Ubuntu 14.04 (Kernel 3.14) to ARM embedded Ubuntu 16.04. On the first platform we are accessing a chip using SPIDEV without a problem. On the Ubuntu 16.04 (Kernel 4.9.59) platform I am getting an EINVAL error following a ioctl SPI_IOC_MESSAGE. The kernel is from TI's SDK 4.02.00.09.
The code calling ioctl is as follows:Part Number: PROCESSOR-SDK-AM335X
Tool/software: Linux
SpiComm_t::Transfer(int i4Length) {
int ret = -1;
m_tr.len = i4Length;
ret = ioctl(m_fd, SPI_IOC_MESSAGE(1), &m_tr);
if (ret ) {
printf("SPI IOCTL error %s\n", strerror(errno)); }
return ret;
}
SpiComm_t::SpiComm_t( uint32_t w4Bus,
uint32_t w4ChipSelect ) :
m_fd(-1),
m_b0IsInitialized(false),
m_w4Bus(w4Bus),
m_w4ChipSelect(w4ChipSelect)
{
m_tr.tx_buf = (unsigned long)m_c1BufTx;
m_tr.rx_buf = (unsigned long)m_c1BufRx;
m_tr.delay_usecs = SX_1276_SPI_DELAY;
m_tr.speed_hz = SX_1276_SPI_SPEED;
m_tr.bits_per_word = SX_1276_SPI_BITS;
}
m_tr and m_c1BufTx are defined as:
spi_ioc_transfer m_tr;
uint8_t m_c1BufTx[0xff+1];
uint8_t m_c1BufRx[0xff+1];
The code that calls the transfer function is:
// Reset memory (Optional... Helps diagnose failures to read.)
memset(m_c1BufTx, 0xFF, sizeof(m_c1BufTx));
// Put address
m_c1BufTx[0] = address;
// Reset memory (optional...)
memset(m_c1BufRx, 0xFF, sizeof(m_c1BufRx));
// Invoke ioctl transaction
int result = Transfer(size+1);
We are using Kernel 4.9.59 from TI SDK 4.0. I have traced the EINVAL to the spidev.c driver but cannot make sense of why I am getting the error.
spidev.c code is:
tmp = _IOC_SIZE(cmd);
if ((tmp % sizeof(struct spi_ioc_transfer)) != 0)
return ERR_PTR(-EINVAL);
*n_ioc = tmp / sizeof(struct spi_ioc_transfer);
if (*n_ioc == 0)
return NULL;
Any help would be greatly appreciated.