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