Hi there,
I have written a custom SPI protocol driver to transfer data from the AM3517 chip to an Atmel uC. I am looking to transfer data of around 256-300 bytes.
I have read online that once the data exceeds a certain threshold which according to the omap2-mcspi is 160 bytes, the DMA gets invoked automatically.
My module loads perfectly fine onto the kernel, I did a loop-back to check whether the data is being correctly transmitted and received and this worked perfectly as well. I am able to successfully Tx and Rx data upto 159 bytes, but as soon as I EXCEED or SEND 160 bytes of data , I get the following error -
spi_fucntion- the size of tx buff is 160
[ 96.829711] kernel BUG at arch/arm/mm/dma-mapping.c:425!
[ 96.835296] BUG: sleeping function called from invalid context at arch/arm/mm/fault.c:295
[ 96.843841] in_atomic(): 0, irqs_disabled(): 128, pid: 1538, name: cat
[ 96.850677] INFO: lockdep is turned off.
[ 96.854797] irq event stamp: 0
[ 96.857971] hardirqs last enabled at (0): [< (null)>] (null)
[ 96.864288] hardirqs last disabled at (0): [<c0070fe4>] copy_process.part.39+0xb84/0xe50
[ 96.872802] softirqs last enabled at (0): [<c0070fe4>] copy_process.part.39+0xb84/0xe50
[ 96.881286] softirqs last disabled at (0): [< (null)>] (null)
[ 96.887634] [<c004bafc>] (unwind_backtrace+0x0/0xe0) from [<c049b4f4>] (do_page_fault.part.4+0x8
c/0x294)
[ 96.897583] [<c049b4f4>] (do_page_fault.part.4+0x8c/0x294) from [<c049b748>] (do_page_fault+0x4c
/0x58)
[ 96.907348] [<c049b748>] (do_page_fault+0x4c/0x58) from [<c003c1f4>] (do_DataAbort+0x34/0x98)
[ 96.916290] [<c003c1f4>] (do_DataAbort+0x34/0x98) from [<c049986c>] (__dabt_svc+0x4c/0x60)
[ 96.924957] Exception stack(0xcd2d9dd8 to 0xcd2d9e20)
[ 96.930236] 9dc0: 00000042 c0641a35
[ 96.938812] 9de0: cd2d9e14 00000000 bf04ba68 bf04ba3c 000000a0 bf04b4a8 cef6b080 02dc6c00
[ 96.947387] 9e00: cc525c00 000002da c08e70e4 cd2d9e20 c0049a54 c0049a58 60000093 ffffffff
[ 96.955963] [<c049986c>] (__dabt_svc+0x4c/0x60) from [<c0049a58>] (__bug+0x1c/0x28)
[ 96.963989] [<c0049a58>] (__bug+0x1c/0x28) from [<c004d5a0>] (___dma_single_cpu_to_dev+0x34/0x64
)
[ 96.973327] [<c004d5a0>] (___dma_single_cpu_to_dev+0x34/0x64) from [<c029639c>] (omap2_mcspi_tra
nsfer+0x128/0x254)
[ 96.984191] [<c029639c>] (omap2_mcspi_transfer+0x128/0x254) from [<c029473c>] (__spi_async+0xa8/
0xb4)
[ 96.993865] [<c029473c>] (__spi_async+0xa8/0xb4) from [<c02948b4>] (spi_async_locked+0x2c/0x44)
[ 97.002990] [<c02948b4>] (spi_async_locked+0x2c/0x44) from [<c02949c8>] (__spi_sync+0xa4/0xe8)
[ 97.012023] [<c02949c8>] (__spi_sync+0xa4/0xe8) from [<bf04b23c>] (spike_read+0xec/0x224 [spi2])
[ 97.021240] [<bf04b23c>] (spike_read+0xec/0x224 [spi2]) from [<c00f8d7c>] (vfs_read+0xa4/0x12c)
[ 97.030364] [<c00f8d7c>] (vfs_read+0xa4/0x12c) from [<c00f8e38>] (sys_read+0x34/0x68)
[ 97.038574] [<c00f8e38>] (sys_read+0x34/0x68) from [<c0045fe0>] (ret_fast_syscall+0x0/0x3c)
[ 97.047363] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 97.055816] pgd = cef30000
[ 97.058654] [00000000] *pgd=8ef95031, *pte=00000000, *ppte=00000000
[ 97.065246] Internal error: Oops: 817 [#1]
[ 97.069549] last sysfs file: /sys/devices/platform/omap2_mcspi.2/spi2.1/uevent
[ 97.077087] Modules linked in: spi2 bufferclass_ti omaplfb pvrsrvkm
[ 97.083709] CPU: 0 Tainted: G W (2.6.37 #1)
[ 97.089263] PC is at __bug+0x1c/0x28
[ 97.093017] LR is at __bug+0x18/0x28
[ 97.096771] pc : [<c0049a58>] lr : [<c0049a54>] psr: 60000093
[ 97.096771] sp : cd2d9e20 ip : c08e70e4 fp : 000002da
[ 97.108795] r10: cc525c00 r9 : 02dc6c00 r8 : cef6b080
[ 97.114257] r7 : bf04b4a8 r6 : 000000a0 r5 : bf04ba3c r4 : bf04ba68
[ 97.121093] r3 : 00000000 r2 : cd2d9e14 r1 : c0641a35 r0 : 00000042
[ 97.127960] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
[ 97.135498] Control: 10c5387d Table: 8ef30019 DAC: 00000015
[ 97.141540] Process cat (pid: 1538, stack limit = 0xcd2d82f0)
[ 97.147552] Stack: (0xcd2d9e20 to 0xcd2da000)
[ 97.152130] 9e20: 00000000 c004d5a0 00000000 c029639c cef6a0c0 c02948a4 cf4c6a64 cf4c6a74
[ 97.160705] 9e40: 40000013 cf4c6a64 cc525c00 40000013 bf04ba3c cc525c00 cd2d8000 cf4c6800
[ 97.169281] 9e60: 00000001 c029473c cef6a0c0 cf4c6a64 cc525c00 40000013 bf04ba3c c02948b4
[ 97.177825] 9e80: 22222222 cd2d9efc cd2d9e98 bf04ba3c 00000000 c02949c8 00000000 00000001
[ 97.186401] 9ea0: dead4ead ffffffff ffffffff c0e6feb4 00000000 00000000 c066abe4 00000000
[ 97.194976] 9ec0: cef6a0c0 cd2d9ec4 cd2d9ec4 00000000 00000001 dead4ead ffffffff ffffffff
[ 97.203552] 9ee0: c0e6feb4 00000000 00000000 c066abe4 00000000 cef6a0c0 cd2d9ec4 cd2d9ec4
[ 97.212127] 9f00: bf04b549 beb3abdc cd2d9f88 00001000 bf04b988 bf04ba3c 00000000 bf04b23c
[ 97.220703] 9f20: 00000000 00000000 00001000 c00f8994 00000000 cd19cbc0 cd2d9f88 00001000
[ 97.229278] 9f40: 00001000 cd19cbc0 beb3abdc cd2d9f88 00001000 cd2d8000 00000000 c00f8d7c
[ 97.237854] 9f60: cd19cbc0 beb3abdc 00000000 00000000 cd19cbc0 beb3abdc 00001000 c00f8e38
[ 97.246429] 9f80: 00000003 00000000 00000000 00000000 000989ac 00001000 beb3abdc 00000003
[ 97.255004] 9fa0: c00461a8 c0045fe0 000989ac 00001000 00000003 beb3abdc 00001000 00000000
[ 97.263580] 9fc0: 000989ac 00001000 beb3abdc 00000003 00000000 00000000 00000001 00000001
[ 97.272155] 9fe0: 00000003 beb3abb8 00011220 49ddf0cc 60000010 00000003 23020000 30471030
[ 97.280731] [<c0049a58>] (__bug+0x1c/0x28) from [<c004d5a0>] (___dma_single_cpu_to_dev+0x34/0x64
)
[ 97.290039] [<c004d5a0>] (___dma_single_cpu_to_dev+0x34/0x64) from [<c029639c>] (omap2_mcspi_tra
nsfer+0x128/0x254)
[ 97.300872] [<c029639c>] (omap2_mcspi_transfer+0x128/0x254) from [<c029473c>] (__spi_async+0xa8/
0xb4)
[ 97.310546] [<c029473c>] (__spi_async+0xa8/0xb4) from [<c02948b4>] (spi_async_locked+0x2c/0x44)
[ 97.319671] [<c02948b4>] (spi_async_locked+0x2c/0x44) from [<c02949c8>] (__spi_sync+0xa4/0xe8)
[ 97.328704] [<c02949c8>] (__spi_sync+0xa4/0xe8) from [<bf04b23c>] (spike_read+0xec/0x224 [spi2])
[ 97.337921] [<bf04b23c>] (spike_read+0xec/0x224 [spi2]) from [<c00f8d7c>] (vfs_read+0xa4/0x12c)
[ 97.347045] [<c00f8d7c>] (vfs_read+0xa4/0x12c) from [<c00f8e38>] (sys_read+0x34/0x68)
[ 97.355255] [<c00f8e38>] (sys_read+0x34/0x68) from [<c0045fe0>] (ret_fast_syscall+0x0/0x3c)
[ 97.364013] Code: e59f0010 e1a01003 eb11216c e3a03000 (e5833000)
[ 97.372253] ---[ end trace 1b75b31a2719ed1f ]---
Segmentation fault
My code for the SPI transfer is below.
static void spike_prepare_spi_message(void)
{
//static int test_data = 0;
spi_message_init(&spike_ctl.msg);
/* put some changing values in tx_buff for testing */
spike_ctl.tx_buff = "5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555AAB"; //160bytes
printk(KERN_NOTICE "spi_fucntion- the size of tx buff is %u\n", strlen(spike_ctl.tx_buff));
memset(spike_ctl.rx_buff, 0, SPI_BUFF_SIZE);
//printk(KERN_INFO "the rx buffer is %d %d %d %d \n", spike_ctl.rx_buff[0], spike_ctl.rx_buff[1], spike_ctl.rx_buff[2], spike_ctl.rx_buff[3]);
spike_ctl.transfer.tx_buf = spike_ctl.tx_buff;
spike_ctl.transfer.rx_buf = spike_ctl.rx_buff;
spike_ctl.transfer.len = strlen(spike_ctl.tx_buff);
spi_message_add_tail(&spike_ctl.transfer, &spike_ctl.msg);
}
static int spike_do_one_message(void)
{
int status;
if (down_interruptible(&spike_dev.spi_sem))
return -ERESTARTSYS;
if (!spike_dev.spi_device) {
up(&spike_dev.spi_sem);
return -ENODEV;
}
spike_prepare_spi_message();
status = spi_sync(spike_dev.spi_device, &spike_ctl.msg);
up(&spike_dev.spi_sem);
return status;
}
Can someone please tell me as to what is going on? What have I done wrong? How can I solve this issue?