1*77b2c310Schristos /* $NetBSD: ping.c,v 1.5 2020/04/30 10:55:32 christos Exp $ */
2ad7d712bSpgoyette
3ad7d712bSpgoyette /*-
4ad7d712bSpgoyette * Copyright (c) 2015 The NetBSD Foundation, Inc.
5ad7d712bSpgoyette * All rights reserved.
6ad7d712bSpgoyette *
7ad7d712bSpgoyette * Redistribution and use in source and binary forms, with or without
8ad7d712bSpgoyette * modification, are permitted provided that the following conditions
9ad7d712bSpgoyette * are met:
10ad7d712bSpgoyette * 1. Redistributions of source code must retain the above copyright
11ad7d712bSpgoyette * notice, this list of conditions and the following disclaimer.
12ad7d712bSpgoyette * 2. Redistributions in binary form must reproduce the above copyright
13ad7d712bSpgoyette * notice, this list of conditions and the following disclaimer in the
14ad7d712bSpgoyette * documentation and/or other materials provided with the distribution.
15ad7d712bSpgoyette *
16ad7d712bSpgoyette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17ad7d712bSpgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18ad7d712bSpgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19ad7d712bSpgoyette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20ad7d712bSpgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21ad7d712bSpgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22ad7d712bSpgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23ad7d712bSpgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24ad7d712bSpgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ad7d712bSpgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26ad7d712bSpgoyette * POSSIBILITY OF SUCH DAMAGE.
27ad7d712bSpgoyette */
28ad7d712bSpgoyette
29ad7d712bSpgoyette #include <sys/cdefs.h>
30*77b2c310Schristos __KERNEL_RCSID(0, "$NetBSD: ping.c,v 1.5 2020/04/30 10:55:32 christos Exp $");
31ad7d712bSpgoyette
32ad7d712bSpgoyette #include <sys/param.h>
33ad7d712bSpgoyette #include <sys/conf.h>
34ad7d712bSpgoyette #include <sys/device.h>
35ad7d712bSpgoyette #include <sys/kernel.h>
36ad7d712bSpgoyette #include <sys/module.h>
37ad7d712bSpgoyette
38ad7d712bSpgoyette #include "ping.h"
39ad7d712bSpgoyette
40ad7d712bSpgoyette /*
41ad7d712bSpgoyette * Create a device /dev/ping in order to test this module.
42ad7d712bSpgoyette *
43ad7d712bSpgoyette * To use this device you need to do:
44e56e9450Skamil * mknod /dev/ping c 351 0
45ad7d712bSpgoyette *
46ad7d712bSpgoyette */
47ad7d712bSpgoyette
48ad7d712bSpgoyette dev_type_open(ping_open);
49ad7d712bSpgoyette dev_type_close(ping_close);
50ad7d712bSpgoyette dev_type_ioctl(ping_ioctl);
51ad7d712bSpgoyette
52ad7d712bSpgoyette static struct cdevsw ping_cdevsw = {
53ad7d712bSpgoyette .d_open = ping_open,
54ad7d712bSpgoyette .d_close = ping_close,
55ad7d712bSpgoyette .d_read = noread,
56ad7d712bSpgoyette .d_write = nowrite,
57ad7d712bSpgoyette .d_ioctl = ping_ioctl,
58ad7d712bSpgoyette .d_stop = nostop,
59ad7d712bSpgoyette .d_tty = notty,
60ad7d712bSpgoyette .d_poll = nopoll,
61ad7d712bSpgoyette .d_mmap = nommap,
62ad7d712bSpgoyette .d_kqfilter = nokqfilter,
63ad7d712bSpgoyette .d_discard = nodiscard,
64ad7d712bSpgoyette .d_flag = D_OTHER
65ad7d712bSpgoyette };
66ad7d712bSpgoyette
67ad7d712bSpgoyette
68ad7d712bSpgoyette struct ping_softc {
69ad7d712bSpgoyette int refcnt;
70ad7d712bSpgoyette };
71ad7d712bSpgoyette
72ad7d712bSpgoyette static struct ping_softc sc;
73ad7d712bSpgoyette
74ad7d712bSpgoyette int
ping_open(dev_t self __unused,int flag __unused,int mode __unused,struct lwp * l __unused)75ad7d712bSpgoyette ping_open(dev_t self __unused, int flag __unused, int mode __unused,
76ad7d712bSpgoyette struct lwp *l __unused)
77ad7d712bSpgoyette {
78ad7d712bSpgoyette if (sc.refcnt > 0)
79ad7d712bSpgoyette return EBUSY;
80ad7d712bSpgoyette
81ad7d712bSpgoyette ++sc.refcnt;
82ad7d712bSpgoyette
83ad7d712bSpgoyette return 0;
84ad7d712bSpgoyette }
85ad7d712bSpgoyette
86ad7d712bSpgoyette int
ping_close(dev_t self __unused,int flag __unused,int mode __unused,struct lwp * l __unused)87ad7d712bSpgoyette ping_close(dev_t self __unused, int flag __unused, int mode __unused,
88ad7d712bSpgoyette struct lwp *l __unused)
89ad7d712bSpgoyette {
90ad7d712bSpgoyette --sc.refcnt;
91ad7d712bSpgoyette
92ad7d712bSpgoyette return 0;
93ad7d712bSpgoyette }
94ad7d712bSpgoyette
95ad7d712bSpgoyette int
ping_ioctl(dev_t self __unused,u_long cmd,void * data,int flag,struct lwp * l __unused)96ad7d712bSpgoyette ping_ioctl(dev_t self __unused, u_long cmd, void *data, int flag,
97ad7d712bSpgoyette struct lwp *l __unused)
98ad7d712bSpgoyette {
99ad7d712bSpgoyette switch(cmd) {
100ad7d712bSpgoyette case CMD_PING:
101ad7d712bSpgoyette printf("ping: pong!\n");
102ad7d712bSpgoyette return 0;
103ad7d712bSpgoyette default:
1047aca4c9dSpgoyette return ENOTTY;
105ad7d712bSpgoyette }
106ad7d712bSpgoyette }
107ad7d712bSpgoyette
108ad7d712bSpgoyette MODULE(MODULE_CLASS_MISC, ping, NULL);
109ad7d712bSpgoyette
110ad7d712bSpgoyette static int
ping_modcmd(modcmd_t cmd,void * arg __unused)111ad7d712bSpgoyette ping_modcmd(modcmd_t cmd, void *arg __unused)
112ad7d712bSpgoyette {
113ad7d712bSpgoyette /* The major should be verified and changed if needed to avoid
114ad7d712bSpgoyette * conflicts with other devices. */
115e56e9450Skamil int cmajor = 351, bmajor = -1;
116ad7d712bSpgoyette
117ad7d712bSpgoyette switch (cmd) {
118ad7d712bSpgoyette case MODULE_CMD_INIT:
119ad7d712bSpgoyette if (devsw_attach("ping", NULL, &bmajor, &ping_cdevsw, &cmajor))
120ad7d712bSpgoyette return ENXIO;
121ad7d712bSpgoyette return 0;
122ad7d712bSpgoyette case MODULE_CMD_FINI:
123ad7d712bSpgoyette if (sc.refcnt > 0)
124ad7d712bSpgoyette return EBUSY;
125ad7d712bSpgoyette
126ad7d712bSpgoyette devsw_detach(NULL, &ping_cdevsw);
127ad7d712bSpgoyette return 0;
128ad7d712bSpgoyette default:
129ad7d712bSpgoyette return ENOTTY;
130ad7d712bSpgoyette }
131ad7d712bSpgoyette }
132