TODO: - Rx block size is limited to < 2048, hardware bug? - Group size is limited to < page size, kernel alloc/mmap API issues - test whether Tx is transmitting data from provided buffers - handle device unplug case - handle temperature above threshold - use bus address instead of physical address for DMA - support for snapshot mode - audit userspace interfaces - get reserved major/minor if needed Sample Code: #include #include #include #include #include #include #include #include #include #include #include #include struct pconsume { uint32_t * offsets; uint32_t nfetch; uint32_t nflush; }; uint32_t offsets[10]; void process_group(unsigned char *buf, uint32_t size) { uint16_t *buf16 = (uint16_t *)buf; printf("RX: %p %u %04x %04x %04x %04x %04x %04x\n", buf, size, buf16[0], buf16[1], buf16[2], buf16[3], buf16[4], buf16[5]); } int main() { struct sysfs_attribute *attr; char *path; int ret; unsigned long mmap_size; int fd; unsigned char *cbuf; uint32_t nflush; struct pollfd poll_fds; int count = 0; int i; path = "/sys/class/pocketchange/poch0/ch0/block_size"; attr = sysfs_open_attribute(path); ret = sysfs_write_attribute(attr, "256", strlen("256")); if (ret == -1) error(1, errno, "error writing attribute %s", path); sysfs_close_attribute(attr); path = "/sys/class/pocketchange/poch0/ch0/group_size"; attr = sysfs_open_attribute(path); ret = sysfs_write_attribute(attr, "4096", strlen("4096")); if (ret == -1) error(1, errno, "error writing attribute %s", path); sysfs_close_attribute(attr); path = "/sys/class/pocketchange/poch0/ch0/group_count"; attr = sysfs_open_attribute(path); ret = sysfs_write_attribute(attr, "64", strlen("64")); if (ret == -1) error(1, errno, "error writing attribute %s", path); sysfs_close_attribute(attr); fd = open("/dev/ch0", O_RDWR); if (fd == -1) error(1, errno, "error opening device node"); path = "/sys/class/pocketchange/poch0/ch0/mmap_size"; attr = sysfs_open_attribute(path); ret = sysfs_read_attribute(attr); if (ret == -1) error(1, errno, "error reading attribute %s", path); printf("%s", attr->value); sscanf(attr->value, "%lu", &mmap_size); sysfs_close_attribute(attr); cbuf = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (cbuf == MAP_FAILED) error(1, errno, "error mapping DMA buffers"); ret = ioctl(fd, POCH_IOC_TRANSFER_START, 0); if (ret == -1) error(1, errno, "error starting transfer"); nflush = 0; while (1) { struct pconsume consume; consume.offsets = offsets; consume.nfetch = 10; consume.nflush = nflush; ret = ioctl(fd, POCH_IOC_CONSUME, &consume); if (ret == -1) error(1, errno, "error consuming groups"); nflush = consume.nfetch; for (i = 0; i < nflush; i++) { process_group(cbuf + consume.offsets[i], 4096); count++; if (count == 1000) break; } if (count == 1000) break; } ret = ioctl(fd, POCH_IOC_TRANSFER_STOP, 0); if (ret == -1) error(1, errno, "error starting transfer"); return 0; } Please send patches to Greg Kroah-Hartman and Vijay Kumar and Jaya Kumar