krping_dev.c revision 237263
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 237263 2012-06-19 07:34:13Z np $"); 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 */ 30static d_open_t krping_open; 31static d_close_t krping_close; 32static d_read_t krping_read; 33static d_write_t krping_write; 34 35/* Character device entry points */ 36static 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 45typedef struct s_krping { 46 char msg[BUFFERSIZE]; 47 int len; 48} krping_t; 49 50/* vars */ 51static struct cdev *krping_dev; 52 53#undef MODULE_VERSION 54#include <sys/module.h> 55 56static int 57krping_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 79static int 80krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p) 81{ 82 int err = 0; 83 return err; 84} 85 86static int 87krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p) 88{ 89 return 0; 90} 91 92static int 93krping_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(©_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(©_cbs, cb2, list); 111 } 112 mtx_unlock(&krping_mutex); 113 114 while (!TAILQ_EMPTY(©_cbs)) { 115 116 cb = TAILQ_FIRST(©_cbs); 117 TAILQ_REMOVE(©_cbs, cb, list); 118 if (cb->pd) { 119 uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n", 120 num++, cb->pd->device->name, cb->stats.send_bytes, 121 cb->stats.send_msgs, cb->stats.recv_bytes, 122 cb->stats.recv_msgs, cb->stats.write_bytes, 123 cb->stats.write_msgs, 124 cb->stats.read_bytes, 125 cb->stats.read_msgs); 126 } else { 127 uprintf("krping: %d listen\n", num++); 128 } 129 free(cb, M_DEVBUF); 130 } 131 return 0; 132} 133 134static int 135krping_write(struct cdev *dev, struct uio *uio, int ioflag) 136{ 137 int err = 0; 138 int amt; 139 int remain = BUFFERSIZE; 140 char *cp; 141 krping_t *krpingmsg; 142 143 krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO); 144 if (!krpingmsg) { 145 uprintf("Could not malloc mem!\n"); 146 return ENOMEM; 147 } 148 149 cp = krpingmsg->msg; 150 while (uio->uio_resid) { 151 amt = MIN(uio->uio_resid, remain); 152 if (amt == 0) 153 break; 154 155 /* Copy the string in from user memory to kernel memory */ 156 err = uiomove(cp, amt, uio); 157 if (err) { 158 uprintf("Write failed: bad address!\n"); 159 return err; 160 } 161 cp += amt; 162 remain -= amt; 163 } 164 165 if (uio->uio_resid != 0) { 166 uprintf("Message too big. max size is %d!\n", BUFFERSIZE); 167 return EMSGSIZE; 168 } 169 170 /* null terminate and remove the \n */ 171 cp--; 172 *cp = 0; 173 krpingmsg->len = (unsigned long)(cp - krpingmsg->msg); 174 uprintf("krping: write string = |%s|\n", krpingmsg->msg); 175 err = krping_doit(krpingmsg->msg); 176 free(krpingmsg, M_DEVBUF); 177 return(err); 178} 179 180DEV_MODULE(krping,krping_loader,NULL); 181