static int __init testfunc(void) { unsigned char buf[6]; unsigned char i, j; unsigned int ret; printk(KERN_INFO "[fifo]byte stream fifo test start\n"); /* put string into the fifo */ kfifo_in(&test, "hello", 5); /* put values into the fifo */ for (i = 0; i != 10; i++) kfifo_put(&test, &i); /* show the number of used elements */ printk(KERN_INFO "[fifo]fifo len: %u\n", kfifo_len(&test)); /* get max of 5 bytes from the fifo */ i = kfifo_out(&test, buf, 5); printk(KERN_INFO "[fifo]buf: %.*s\n", i, buf); /* get max of 2 elements from the fifo */ ret = kfifo_out(&test, buf, 2); printk(KERN_INFO "[fifo]ret: %d\n", ret); /* and put it back to the end of the fifo */ ret = kfifo_in(&test, buf, ret); printk(KERN_INFO "[fifo]ret: %d\n", ret); /* skip first element of the fifo */ printk(KERN_INFO "[fifo]skip 1st element\n"); kfifo_skip(&test); /* put values into the fifo until is full */ for (i = 20; kfifo_put(&test, &i); i++) ; printk(KERN_INFO "[fifo]queue len: %u\n", kfifo_len(&test)); /* show the first value without removing from the fifo */ if (kfifo_peek(&test, &i)) printk(KERN_INFO "[fifo]%d\n", i); /* check the correctness of all values in the fifo */ j = 0; while (kfifo_get(&test, &i)) { printk(KERN_INFO "item = %d\n", i); if (i != expected_result[j++]) { printk(KERN_WARNING "value mismatch: test failed\n"); return -EIO; } } if (j != ARRAY_SIZE(expected_result)) { printk(KERN_WARNING "size mismatch: test failed\n"); return -EIO; } printk(KERN_INFO "[fifo]test passed\n"); return 0; }
static int __init testfunc(void) { int buf[6]; int i, j; unsigned int ret; printk(KERN_INFO "int fifo test start\n"); for (i = 0; i != 10; i++) kfifo_put(&test, &i); printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test)); ret = kfifo_out(&test, buf, 2); printk(KERN_INFO "ret: %d\n", ret); ret = kfifo_in(&test, buf, ret); printk(KERN_INFO "ret: %d\n", ret); printk(KERN_INFO "skip 1st element\n"); kfifo_skip(&test); for (i = 20; kfifo_put(&test, &i); i++) ; printk(KERN_INFO "queue len: %u\n", kfifo_len(&test)); if (kfifo_peek(&test, &i)) printk(KERN_INFO "%d\n", i); j = 0; while (kfifo_get(&test, &i)) { printk(KERN_INFO "item = %d\n", i); if (i != expected_result[j++]) { printk(KERN_WARNING "value mismatch: test failed\n"); return -EIO; } } if (j != ARRAY_SIZE(expected_result)) { printk(KERN_WARNING "size mismatch: test failed\n"); return -EIO; } printk(KERN_INFO "test passed\n"); return 0; }
static int __init example_init(void) { int i; unsigned int ret; unsigned int nents; struct scatterlist sg[10]; printk(KERN_INFO "DMA fifo test start\n"); if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { printk(KERN_WARNING "error kfifo_alloc\n"); return -ENOMEM; } printk(KERN_INFO "queue size: %u\n", kfifo_size(&fifo)); kfifo_in(&fifo, "test", 4); for (i = 0; i != 9; i++) kfifo_put(&fifo, i); /* kick away first byte */ kfifo_skip(&fifo); printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); /* * Configure the kfifo buffer to receive data from DMA input. * * .--------------------------------------. * | 0 | 1 | 2 | ... | 12 | 13 | ... | 31 | * |---|------------------|---------------| * \_/ \________________/ \_____________/ * \ \ \ * \ \_allocated data \ * \_*free space* \_*free space* * * We need two different SG entries: one for the free space area at the * end of the kfifo buffer (19 bytes) and another for the first free * byte at the beginning, after the kfifo_skip(). */ sg_init_table(sg, ARRAY_SIZE(sg)); nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); printk(KERN_INFO "DMA sgl entries: %d\n", nents); if (!nents) { /* fifo is full and no sgl was created */ printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); return -EIO; } /* receive data */ printk(KERN_INFO "scatterlist for receive:\n"); for (i = 0; i < nents; i++) { printk(KERN_INFO "sg[%d] -> " "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", i, sg[i].page_link, sg[i].offset, sg[i].length); if (sg_is_last(&sg[i])) break; } /* put here your code to setup and exectute the dma operation */ /* ... */ /* example: zero bytes received */ ret = 0; /* finish the dma operation and update the received data */ kfifo_dma_in_finish(&fifo, ret); /* Prepare to transmit data, example: 8 bytes */ nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); printk(KERN_INFO "DMA sgl entries: %d\n", nents); if (!nents) { /* no data was available and no sgl was created */ printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); return -EIO; } printk(KERN_INFO "scatterlist for transmit:\n"); for (i = 0; i < nents; i++) { printk(KERN_INFO "sg[%d] -> " "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", i, sg[i].page_link, sg[i].offset, sg[i].length); if (sg_is_last(&sg[i])) break; } /* put here your code to setup and exectute the dma operation */ /* ... */ /* example: 5 bytes transmitted */ ret = 5; /* finish the dma operation and update the transmitted data */ kfifo_dma_out_finish(&fifo, ret); ret = kfifo_len(&fifo); printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); if (ret != 7) { printk(KERN_WARNING "size mismatch: test failed"); return -EIO; } printk(KERN_INFO "test passed\n"); return 0; }