xref: /netbsd/sys/modules/examples/ping/ping.c (revision 77b2c310)
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