xref: /freebsd/sys/contrib/rdma/krping/krping_dev.c (revision 0082e6a570e30f0482ba4c94decdcc5bde85fc06)
1e68ff398SKip Macy /*
2e68ff398SKip Macy  * This code lifted from:
3e68ff398SKip Macy  * 	Simple `echo' pseudo-device KLD
4e68ff398SKip Macy  * 	Murray Stokely
5e68ff398SKip Macy  * 	Converted to 5.X by Søren (Xride) Straarup
6e68ff398SKip Macy  */
7e68ff398SKip Macy 
8e68ff398SKip Macy /*
9e68ff398SKip Macy  * /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping
10e68ff398SKip Macy  * /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping
11e68ff398SKip Macy  */
12e68ff398SKip Macy 
13e68ff398SKip Macy #include <sys/cdefs.h>
14e68ff398SKip Macy __FBSDID("$FreeBSD$");
15e68ff398SKip Macy 
16e68ff398SKip Macy #include <sys/types.h>
17*0082e6a5SNavdeep Parhar #include <sys/module.h>
18e68ff398SKip Macy #include <sys/systm.h>  /* uprintf */
19e68ff398SKip Macy #include <sys/errno.h>
20e68ff398SKip Macy #include <sys/param.h>  /* defines used in kernel.h */
21e68ff398SKip Macy #include <sys/kernel.h> /* types used in module initialization */
22e68ff398SKip Macy #include <sys/conf.h>   /* cdevsw struct */
23e68ff398SKip Macy #include <sys/uio.h>    /* uio struct */
24e68ff398SKip Macy #include <sys/malloc.h>
25*0082e6a5SNavdeep Parhar #include <sys/proc.h>
26*0082e6a5SNavdeep Parhar #include <sys/sysctl.h>
27*0082e6a5SNavdeep Parhar #include <machine/stdarg.h>
28e68ff398SKip Macy 
29e68ff398SKip Macy #include "krping.h"
30e68ff398SKip Macy 
31e68ff398SKip Macy #define BUFFERSIZE 512
32e68ff398SKip Macy 
33*0082e6a5SNavdeep Parhar SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW, 0, "kernel rping module");
34*0082e6a5SNavdeep Parhar 
35*0082e6a5SNavdeep Parhar int krping_debug = 0;
36*0082e6a5SNavdeep Parhar SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , "");
37*0082e6a5SNavdeep Parhar 
38e68ff398SKip Macy /* Function prototypes */
39e68ff398SKip Macy static d_open_t      krping_open;
40e68ff398SKip Macy static d_close_t     krping_close;
41e68ff398SKip Macy static d_read_t      krping_read;
42e68ff398SKip Macy static d_write_t     krping_write;
43e68ff398SKip Macy 
44e68ff398SKip Macy /* Character device entry points */
45e68ff398SKip Macy static struct cdevsw krping_cdevsw = {
46e68ff398SKip Macy 	.d_version = D_VERSION,
47e68ff398SKip Macy 	.d_open = krping_open,
48e68ff398SKip Macy 	.d_close = krping_close,
49e68ff398SKip Macy 	.d_read = krping_read,
50e68ff398SKip Macy 	.d_write = krping_write,
51e68ff398SKip Macy 	.d_name = "krping",
52e68ff398SKip Macy };
53e68ff398SKip Macy 
54e68ff398SKip Macy typedef struct s_krping {
55e68ff398SKip Macy 	char msg[BUFFERSIZE];
56e68ff398SKip Macy 	int len;
57e68ff398SKip Macy } krping_t;
58e68ff398SKip Macy 
59*0082e6a5SNavdeep Parhar struct stats_list_entry {
60*0082e6a5SNavdeep Parhar 	STAILQ_ENTRY(stats_list_entry) link;
61*0082e6a5SNavdeep Parhar 	struct krping_stats *stats;
62*0082e6a5SNavdeep Parhar };
63*0082e6a5SNavdeep Parhar STAILQ_HEAD(stats_list, stats_list_entry);
64*0082e6a5SNavdeep Parhar 
65e68ff398SKip Macy /* vars */
66e68ff398SKip Macy static struct cdev *krping_dev;
67e68ff398SKip Macy 
68e68ff398SKip Macy static int
69e68ff398SKip Macy krping_loader(struct module *m, int what, void *arg)
70e68ff398SKip Macy {
71e68ff398SKip Macy 	int err = 0;
72e68ff398SKip Macy 
73e68ff398SKip Macy 	switch (what) {
74e68ff398SKip Macy 	case MOD_LOAD:                /* kldload */
75e68ff398SKip Macy 		krping_init();
76e68ff398SKip Macy 		krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
77e68ff398SKip Macy 					0600, "krping");
78e68ff398SKip Macy 		printf("Krping device loaded.\n");
79e68ff398SKip Macy 		break;
80e68ff398SKip Macy 	case MOD_UNLOAD:
81e68ff398SKip Macy 		destroy_dev(krping_dev);
82e68ff398SKip Macy 		printf("Krping device unloaded.\n");
83e68ff398SKip Macy 		break;
84e68ff398SKip Macy 	default:
85e68ff398SKip Macy 		err = EOPNOTSUPP;
86e68ff398SKip Macy 		break;
87e68ff398SKip Macy 	}
88*0082e6a5SNavdeep Parhar 
89*0082e6a5SNavdeep Parhar 	return (err);
90e68ff398SKip Macy }
91e68ff398SKip Macy 
92e68ff398SKip Macy static int
93e68ff398SKip Macy krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
94e68ff398SKip Macy {
95*0082e6a5SNavdeep Parhar 
96*0082e6a5SNavdeep Parhar 	return (0);
97e68ff398SKip Macy }
98e68ff398SKip Macy 
99e68ff398SKip Macy static int
100e68ff398SKip Macy krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
101e68ff398SKip Macy {
102*0082e6a5SNavdeep Parhar 
103e68ff398SKip Macy 	return 0;
104e68ff398SKip Macy }
105e68ff398SKip Macy 
106*0082e6a5SNavdeep Parhar static void
107*0082e6a5SNavdeep Parhar krping_copy_stats(struct krping_stats *stats, void *arg)
108*0082e6a5SNavdeep Parhar {
109*0082e6a5SNavdeep Parhar 	struct stats_list_entry *s;
110*0082e6a5SNavdeep Parhar 	struct stats_list *list = arg;
111*0082e6a5SNavdeep Parhar 
112*0082e6a5SNavdeep Parhar 	s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO);
113*0082e6a5SNavdeep Parhar 	if (s == NULL)
114*0082e6a5SNavdeep Parhar 		return;
115*0082e6a5SNavdeep Parhar 	if (stats != NULL) {
116*0082e6a5SNavdeep Parhar 		s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO);
117*0082e6a5SNavdeep Parhar 		if (s->stats == NULL) {
118*0082e6a5SNavdeep Parhar 			free(s, M_DEVBUF);
119*0082e6a5SNavdeep Parhar 			return;
120*0082e6a5SNavdeep Parhar 		}
121*0082e6a5SNavdeep Parhar 		*s->stats = *stats;
122*0082e6a5SNavdeep Parhar 	}
123*0082e6a5SNavdeep Parhar 	STAILQ_INSERT_TAIL(list, s, link);
124*0082e6a5SNavdeep Parhar }
125*0082e6a5SNavdeep Parhar 
126e68ff398SKip Macy static int
127e68ff398SKip Macy krping_read(struct cdev *dev, struct uio *uio, int ioflag)
128e68ff398SKip Macy {
129e68ff398SKip Macy 	int num = 1;
130*0082e6a5SNavdeep Parhar 	struct stats_list list;
131*0082e6a5SNavdeep Parhar 	struct stats_list_entry *e;
132*0082e6a5SNavdeep Parhar 
133*0082e6a5SNavdeep Parhar 	STAILQ_INIT(&list);
134*0082e6a5SNavdeep Parhar 	krping_walk_cb_list(krping_copy_stats, &list);
135*0082e6a5SNavdeep Parhar 
136*0082e6a5SNavdeep Parhar 	if (STAILQ_EMPTY(&list))
137*0082e6a5SNavdeep Parhar 		return (0);
138e68ff398SKip Macy 
139e68ff398SKip Macy 	uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
140*0082e6a5SNavdeep Parhar 	    "num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs",
141*0082e6a5SNavdeep Parhar 	    "wr bytes", "wr msgs", "rd bytes", "rd msgs");
142e68ff398SKip Macy 
143*0082e6a5SNavdeep Parhar 	while (!STAILQ_EMPTY(&list)) {
144*0082e6a5SNavdeep Parhar 		e = STAILQ_FIRST(&list);
145*0082e6a5SNavdeep Parhar 		STAILQ_REMOVE_HEAD(&list, link);
146*0082e6a5SNavdeep Parhar 		if (e->stats == NULL)
147*0082e6a5SNavdeep Parhar 			uprintf("krping: %d listen\n", num);
148*0082e6a5SNavdeep Parhar 		else {
149*0082e6a5SNavdeep Parhar 			struct krping_stats *stats = e->stats;
150e68ff398SKip Macy 
151*0082e6a5SNavdeep Parhar 			uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu "
152*0082e6a5SNavdeep Parhar 			    "%10llu %10llu %10llu %10llu\n", num, stats->name,
153*0082e6a5SNavdeep Parhar 			    stats->send_bytes, stats->send_msgs,
154*0082e6a5SNavdeep Parhar 			    stats->recv_bytes, stats->recv_msgs,
155*0082e6a5SNavdeep Parhar 			    stats->write_bytes, stats->write_msgs,
156*0082e6a5SNavdeep Parhar 			    stats->read_bytes, stats->read_msgs);
157*0082e6a5SNavdeep Parhar 			free(stats, M_DEVBUF);
158e68ff398SKip Macy 		}
159*0082e6a5SNavdeep Parhar 		num++;
160*0082e6a5SNavdeep Parhar 		free(e, M_DEVBUF);
161e68ff398SKip Macy 	}
162*0082e6a5SNavdeep Parhar 
163*0082e6a5SNavdeep Parhar 	return (0);
164e68ff398SKip Macy }
165e68ff398SKip Macy 
166e68ff398SKip Macy static int
167e68ff398SKip Macy krping_write(struct cdev *dev, struct uio *uio, int ioflag)
168e68ff398SKip Macy {
169e68ff398SKip Macy 	int err = 0;
170e68ff398SKip Macy 	int amt;
171e68ff398SKip Macy 	int remain = BUFFERSIZE;
172e68ff398SKip Macy 	char *cp;
173e68ff398SKip Macy 	krping_t *krpingmsg;
174e68ff398SKip Macy 
175e68ff398SKip Macy 	krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO);
176e68ff398SKip Macy 	if (!krpingmsg) {
177e68ff398SKip Macy 		uprintf("Could not malloc mem!\n");
178e68ff398SKip Macy 		return ENOMEM;
179e68ff398SKip Macy 	}
180e68ff398SKip Macy 
181e68ff398SKip Macy 	cp = krpingmsg->msg;
182e68ff398SKip Macy 	while (uio->uio_resid) {
183e68ff398SKip Macy 		amt = MIN(uio->uio_resid, remain);
184e68ff398SKip Macy 		if (amt == 0)
185e68ff398SKip Macy 			break;
186e68ff398SKip Macy 
187e68ff398SKip Macy 		/* Copy the string in from user memory to kernel memory */
188e68ff398SKip Macy 		err = uiomove(cp, amt, uio);
189e68ff398SKip Macy 		if (err) {
190e68ff398SKip Macy 			uprintf("Write failed: bad address!\n");
191e68ff398SKip Macy 			return err;
192e68ff398SKip Macy 		}
193e68ff398SKip Macy 		cp += amt;
194e68ff398SKip Macy 		remain -= amt;
195e68ff398SKip Macy 	}
196e68ff398SKip Macy 
197e68ff398SKip Macy 	if (uio->uio_resid != 0) {
198e68ff398SKip Macy 		uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
199e68ff398SKip Macy 		return EMSGSIZE;
200e68ff398SKip Macy 	}
201e68ff398SKip Macy 
202e68ff398SKip Macy 	/* null terminate and remove the \n */
203e68ff398SKip Macy 	cp--;
204e68ff398SKip Macy 	*cp = 0;
205e68ff398SKip Macy 	krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
206e68ff398SKip Macy 	uprintf("krping: write string = |%s|\n", krpingmsg->msg);
207*0082e6a5SNavdeep Parhar 	err = krping_doit(krpingmsg->msg, curproc);
208e68ff398SKip Macy 	free(krpingmsg, M_DEVBUF);
209e68ff398SKip Macy 	return(err);
210e68ff398SKip Macy }
211e68ff398SKip Macy 
212*0082e6a5SNavdeep Parhar void
213*0082e6a5SNavdeep Parhar krping_printf(void *cookie, const char *fmt, ...)
214*0082e6a5SNavdeep Parhar {
215*0082e6a5SNavdeep Parhar 	va_list ap;
216*0082e6a5SNavdeep Parhar 
217*0082e6a5SNavdeep Parhar 	va_start(ap, fmt);
218*0082e6a5SNavdeep Parhar 	vtprintf(cookie, -1, fmt, ap);
219*0082e6a5SNavdeep Parhar 	va_end(ap);
220*0082e6a5SNavdeep Parhar }
221*0082e6a5SNavdeep Parhar 
222*0082e6a5SNavdeep Parhar int
223*0082e6a5SNavdeep Parhar krping_sigpending(void)
224*0082e6a5SNavdeep Parhar {
225*0082e6a5SNavdeep Parhar 
226*0082e6a5SNavdeep Parhar 	return (SIGPENDING(curthread));
227*0082e6a5SNavdeep Parhar }
228*0082e6a5SNavdeep Parhar 
229e68ff398SKip Macy DEV_MODULE(krping, krping_loader, NULL);
230*0082e6a5SNavdeep Parhar MODULE_DEPEND(krping, ibcore, 1, 1, 1);
231