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