Hi, isn't it possible that your hal_frame_read be called again prior rf_rx_completion_handler is called, and because of this calling spi_message_init on a spi_message that is in spi queue yet? 2016-07-06 10:25 GMT-03:00 Moti Cohen <motic.mail@xxxxxxxxx>: > Hi all, > > > > I'm trying to write a kernel device driver for a Freescale imx6 processor > based board. > > This driver is using spi to communicate with a radio module (using linux > spi.c). > > I managed to wr/rd from the module, however once I'm trying to read more > than 64 bytes I'm getting coruppted data. here are some details: > > > > > The SPI reading process goes as follows: > > 1. Interrupt function is invoked from SPI device via dedicated GPIO > line. > > 2. The interrupt function performs asynchronous SPI read in the > following order: > > 2.1 radio_trx_end_callback is called, as it is the registered call back > function. > > 2.2 radio_trx_end_callback calls hal_frame_read function which prepares > spi_message and spi_transfer structures and fill them with relevant data: > spi_device , data tx, transfer len , complete handler , … > > 3. The read itself is done by calling to function spi_async > > 4. The completion handler function is called and prints the read > message, but trying to read more than 64 bytes in one transaction causes the > read data to be corrupted. > > Any idea why am I seeing this behavior ? > > Is there (in Linux) any definition for the size to be read via the SPI ? > > The relevant variables and functions can be seen below: > > Thanks in advance for helping.. > > __________________________ > > uint8_t rx_buf[200]; > > uint8_t reg[200] = {HAL_TRX_CMD_FR, 0xff, 0xff}; > > struct spi_transfer transfer; > > struct spi_message spi_msg; > > > > // interrupt function > > //----------------------------------------------------------------------------------------------------------------------- > > static irq_handler_t radio_trx_end_callback(unsigned int irq, void *dev_id, > struct pt_regs *regs) > > { > > hal_frame_read(irq, dev_id); > > return (irq_handler_t) IRQ_HANDLED; // Announce that the IRQ has > been handled correctly > > } > > > > //read function > > //----------------------------------------------------------------------------------------------------------------------- > > void hal_frame_read(unsigned int irq, void *dev_id) > > { > > int status; > > spi_device->irq = irq; > > spi_message_init(&spi_msg); > > spi_msg.spi = spi_device; > > spi_msg.complete = rf_rx_completion_handler; > > spi_msg.context = NULL; > > memset((uint8_t*)&transfer, 0, sizeof(transfer)); > > > > memset(rx_buf, 0xFF, sizeof(rx_buf)); > > memset(reg, 0xFF, sizeof(reg)); > > reg[0] = HAL_TRX_CMD_FR; > > transfer.tx_buf = reg; > > transfer.len =64; > > transfer.rx_buf = rx_buf; > > spi_message_add_tail(&transfer, &spi_msg); > > > > memset(rx_buf, 0x0, sizeof(rx_buf)); > > status = spi_async(spi_device, &spi_msg); > > return; > > } > > > > //read completion handler > > //----------------------------------------------------------------------------------------------------------------------- > > static void rf_rx_completion_handler(void *arg) > > { > > int ii; > > > > //print the received message > > printk("\npure message: rx_buf [1]-2=%02X\n ", rx_buf [1]-2); > > for (ii=0; ii< rx_buf [1]-2; ii++) > > printk("%02X ", rx_buf [2+ii]); > > > > > > printk("\nframe len=%X actual len=%X > status=%i\n",spi_msg.frame_length, spi_msg.actual_length, spi_msg.status); > > > > send_up_rf_event_to_workque(TRX_END_EVENT); > > } > > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies@xxxxxxxxxxxxxxxxx > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies > -- "Do or do not. There is no try" Yoda Master _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies