summaryrefslogtreecommitdiff
path: root/drivers/staging/poch/README
blob: ac76ff969a2ff22efe515373a51cda90ee72ed74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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 <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <stdio.h>
#include <error.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>

#include <sysfs/libsysfs.h>

#include <poch.h>

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 <greg@kroah.com> and
Vijay Kumar <vijaykumar@bravegnu.org> and Jaya Kumar <jayakumar.lkml@gmail.com>