xref: /freebsd/sys/contrib/rdma/krping/krping_dev.c (revision e68ff398875b17e19f8a55cd0f2d3d502c45d821)
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>
17e68ff398SKip Macy #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>
25e68ff398SKip Macy 
26e68ff398SKip Macy #include "krping.h"
27e68ff398SKip Macy 
28e68ff398SKip Macy #define BUFFERSIZE 512
29e68ff398SKip Macy 
30e68ff398SKip Macy /* Function prototypes */
31e68ff398SKip Macy static d_open_t      krping_open;
32e68ff398SKip Macy static d_close_t     krping_close;
33e68ff398SKip Macy static d_read_t      krping_read;
34e68ff398SKip Macy static d_write_t     krping_write;
35e68ff398SKip Macy 
36e68ff398SKip Macy /* Character device entry points */
37e68ff398SKip Macy static struct cdevsw krping_cdevsw = {
38e68ff398SKip Macy 	.d_version = D_VERSION,
39e68ff398SKip Macy 	.d_open = krping_open,
40e68ff398SKip Macy 	.d_close = krping_close,
41e68ff398SKip Macy 	.d_read = krping_read,
42e68ff398SKip Macy 	.d_write = krping_write,
43e68ff398SKip Macy 	.d_name = "krping",
44e68ff398SKip Macy };
45e68ff398SKip Macy 
46e68ff398SKip Macy typedef struct s_krping {
47e68ff398SKip Macy 	char msg[BUFFERSIZE];
48e68ff398SKip Macy 	int len;
49e68ff398SKip Macy } krping_t;
50e68ff398SKip Macy 
51e68ff398SKip Macy /* vars */
52e68ff398SKip Macy static struct cdev *krping_dev;
53e68ff398SKip Macy 
54e68ff398SKip Macy static int
55e68ff398SKip Macy krping_loader(struct module *m, int what, void *arg)
56e68ff398SKip Macy {
57e68ff398SKip Macy 	int err = 0;
58e68ff398SKip Macy 
59e68ff398SKip Macy 	switch (what) {
60e68ff398SKip Macy 	case MOD_LOAD:                /* kldload */
61e68ff398SKip Macy 		krping_init();
62e68ff398SKip Macy 		krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
63e68ff398SKip Macy 					0600, "krping");
64e68ff398SKip Macy 		printf("Krping device loaded.\n");
65e68ff398SKip Macy 		break;
66e68ff398SKip Macy 	case MOD_UNLOAD:
67e68ff398SKip Macy 		destroy_dev(krping_dev);
68e68ff398SKip Macy 		printf("Krping device unloaded.\n");
69e68ff398SKip Macy 		break;
70e68ff398SKip Macy 	default:
71e68ff398SKip Macy 		err = EOPNOTSUPP;
72e68ff398SKip Macy 		break;
73e68ff398SKip Macy 	}
74e68ff398SKip Macy 	return err;
75e68ff398SKip Macy }
76e68ff398SKip Macy 
77e68ff398SKip Macy static int
78e68ff398SKip Macy krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
79e68ff398SKip Macy {
80e68ff398SKip Macy 	int err = 0;
81e68ff398SKip Macy 	return err;
82e68ff398SKip Macy }
83e68ff398SKip Macy 
84e68ff398SKip Macy static int
85e68ff398SKip Macy krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
86e68ff398SKip Macy {
87e68ff398SKip Macy 	return 0;
88e68ff398SKip Macy }
89e68ff398SKip Macy 
90e68ff398SKip Macy static int
91e68ff398SKip Macy krping_read(struct cdev *dev, struct uio *uio, int ioflag)
92e68ff398SKip Macy {
93e68ff398SKip Macy 	struct krping_cb *cb, *cb2;
94e68ff398SKip Macy 	int num=1;
95e68ff398SKip Macy 	struct krping_cb_list copy_cbs;
96e68ff398SKip Macy 
97e68ff398SKip Macy 	uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
98e68ff398SKip Macy 		"num", "device", "snd bytes", "snd msgs", "rcv bytes",
99e68ff398SKip Macy 		"rcv msgs", "wr bytes", "wr msgs", "rd bytes", "rd msgs");
100e68ff398SKip Macy 	TAILQ_INIT(&copy_cbs);
101e68ff398SKip Macy 
102e68ff398SKip Macy 	mtx_lock(&krping_mutex);
103e68ff398SKip Macy 	TAILQ_FOREACH(cb, &krping_cbs, list) {
104e68ff398SKip Macy 		cb2 = malloc(sizeof(*cb), M_DEVBUF, M_NOWAIT|M_ZERO);
105e68ff398SKip Macy 		if (!cb2)
106e68ff398SKip Macy 			break;
107e68ff398SKip Macy 		bcopy(cb, cb2, sizeof(*cb));
108e68ff398SKip Macy 		TAILQ_INSERT_TAIL(&copy_cbs, cb2, list);
109e68ff398SKip Macy 	}
110e68ff398SKip Macy 	mtx_unlock(&krping_mutex);
111e68ff398SKip Macy 
112e68ff398SKip Macy 	while (!TAILQ_EMPTY(&copy_cbs)) {
113e68ff398SKip Macy 
114e68ff398SKip Macy 		cb = TAILQ_FIRST(&copy_cbs);
115e68ff398SKip Macy 		TAILQ_REMOVE(&copy_cbs, cb, list);
116e68ff398SKip Macy 		if (cb->pd) {
117e68ff398SKip Macy 			uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n",
118e68ff398SKip Macy 			     num++, cb->pd->device->name, cb->stats.send_bytes,
119e68ff398SKip Macy 			     cb->stats.send_msgs, cb->stats.recv_bytes,
120e68ff398SKip Macy 			     cb->stats.recv_msgs, cb->stats.write_bytes,
121e68ff398SKip Macy 			     cb->stats.write_msgs,
122e68ff398SKip Macy 			     cb->stats.read_bytes,
123e68ff398SKip Macy 			     cb->stats.read_msgs);
124e68ff398SKip Macy 		} else {
125e68ff398SKip Macy 			uprintf("krping: %d listen\n", num++);
126e68ff398SKip Macy 		}
127e68ff398SKip Macy 		free(cb, M_DEVBUF);
128e68ff398SKip Macy 	}
129e68ff398SKip Macy 	return 0;
130e68ff398SKip Macy }
131e68ff398SKip Macy 
132e68ff398SKip Macy static int
133e68ff398SKip Macy krping_write(struct cdev *dev, struct uio *uio, int ioflag)
134e68ff398SKip Macy {
135e68ff398SKip Macy 	int err = 0;
136e68ff398SKip Macy 	int amt;
137e68ff398SKip Macy 	int remain = BUFFERSIZE;
138e68ff398SKip Macy 	char *cp;
139e68ff398SKip Macy 	krping_t *krpingmsg;
140e68ff398SKip Macy 
141e68ff398SKip Macy 	krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO);
142e68ff398SKip Macy 	if (!krpingmsg) {
143e68ff398SKip Macy 		uprintf("Could not malloc mem!\n");
144e68ff398SKip Macy 		return ENOMEM;
145e68ff398SKip Macy 	}
146e68ff398SKip Macy 
147e68ff398SKip Macy 	cp = krpingmsg->msg;
148e68ff398SKip Macy 	while (uio->uio_resid) {
149e68ff398SKip Macy 		amt = MIN(uio->uio_resid, remain);
150e68ff398SKip Macy 		if (amt == 0)
151e68ff398SKip Macy 			break;
152e68ff398SKip Macy 
153e68ff398SKip Macy 		/* Copy the string in from user memory to kernel memory */
154e68ff398SKip Macy 		err = uiomove(cp, amt, uio);
155e68ff398SKip Macy 		if (err) {
156e68ff398SKip Macy 			uprintf("Write failed: bad address!\n");
157e68ff398SKip Macy 			return err;
158e68ff398SKip Macy 		}
159e68ff398SKip Macy 		cp += amt;
160e68ff398SKip Macy 		remain -= amt;
161e68ff398SKip Macy 	}
162e68ff398SKip Macy 
163e68ff398SKip Macy 	if (uio->uio_resid != 0) {
164e68ff398SKip Macy 		uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
165e68ff398SKip Macy 		return EMSGSIZE;
166e68ff398SKip Macy 	}
167e68ff398SKip Macy 
168e68ff398SKip Macy 	/* null terminate and remove the \n */
169e68ff398SKip Macy 	cp--;
170e68ff398SKip Macy 	*cp = 0;
171e68ff398SKip Macy 	krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
172e68ff398SKip Macy 	uprintf("krping: write string = |%s|\n", krpingmsg->msg);
173e68ff398SKip Macy 	err = krping_doit(krpingmsg->msg);
174e68ff398SKip Macy 	free(krpingmsg, M_DEVBUF);
175e68ff398SKip Macy 	return(err);
176e68ff398SKip Macy }
177e68ff398SKip Macy 
178e68ff398SKip Macy MODULE_DEPEND(krping, rdma_core, 1, 1, 1);
179e68ff398SKip Macy MODULE_DEPEND(krping, rdma_cma, 1, 1, 1);
180e68ff398SKip Macy DEV_MODULE(krping,krping_loader,NULL);
181