Dummy commit to test new ssh key
[eleutheria.git] / cdev / mydev.c
blob4f06364277bf52b8c059cafa2fe75f62204ca50b
1 #include <sys/param.h>
2 #include <sys/systm.h> /* for uiomove(9) */
3 #include <sys/proc.h>
4 /*#include <sys/errno.h>*/
5 #include <sys/ioctl.h>
6 #include <sys/device.h>
7 #include <sys/conf.h>
8 #include <sys/malloc.h> /* for free(9) */
9 #include <sys/mydev.h>
10 #include <sys/kauth.h>
11 #include <sys/syslog.h>
12 #include <prop/proplib.h>
14 /* These macros expand to function prototypes needed for autoconf(9) */
15 void mydevattach(struct device *parent, struct device *self, void *aux);
16 static dev_type_open(mydevopen);
17 static dev_type_close(mydevclose);
18 static dev_type_read(mydevread);
19 static dev_type_ioctl(mydevioctl);
21 static struct mydev_softc {
22 struct device sc_mydev; /* generic device info */
24 unsigned int sc_usage; /* number of open devices */
25 } mydev_softc;
28 * Each device driver must present to the system a standard
29 * autoconfiguration interface. See driver(9).
31 CFATTACH_DECL(mydev, /* driver name */
32 sizeof (struct mydev_softc), /* size of instance data */
33 NULL, /* match/probe function */
34 mydevattach, /* attach function */
35 NULL, /* detach function */
36 NULL); /* activate function */
38 /* Define the character dev handlers */
39 const struct cdevsw mydev_cdevsw = {
40 mydevopen,
41 mydevclose,
42 mydevread,
43 nowrite,
44 mydevioctl,
45 nostop,
46 notty,
47 nopoll,
48 nommap,
49 nokqfilter,
50 D_OTHER,
54 * This private buffer is the pool we draw data from
55 * and send them over to userspace upon a read() request.
57 static char mybuffer[] = "This is a test";
60 * Attach for autoconfig to find.
62 void
63 mydevattach(struct device *parent, struct device *self, void *aux)
66 * This is where resources that need to be allocated/initialised
67 * can be set up, prior to xxxopen() call.
69 log(LOG_DEBUG, "mydev: pseudo-device attached\n");
70 mydev_softc.sc_usage = 0;
74 * Handle an open request on the dev.
76 static int
77 mydevopen(dev_t dev, int flags, int fmt, struct lwp *proc)
79 log(LOG_DEBUG, "mydev: pseudo-device open attempt by "
80 "uid=%u, pid=%u. (dev=%u, major=%d, minor=%d)\n",
81 kauth_cred_geteuid(proc->l_cred), proc->l_proc->p_pid,
82 dev, major(dev), minor(dev));
84 if (mydev_softc.sc_usage > 0) {
85 log(LOG_ERR, "mydev: pseudo-device already in use\n");
86 return EBUSY;
89 mydev_softc.sc_usage++;
91 return 0; /* Success */
95 * Handle the close request for the dev.
97 static int
98 mydevclose(dev_t dev, int flags, int fmt, struct lwp *proc)
100 if (mydev_softc.sc_usage > 0)
101 mydev_softc.sc_usage--;
103 log(LOG_DEBUG, "mydev: pseudo-device closed\n");
105 return 0; /* Success */
109 * Handle read request on the dev.
111 static int
112 mydevread(dev_t dev, struct uio *uio, int ioflag)
114 int ret;
115 size_t nbytes;
117 log(LOG_DEBUG, "mydev: uio: iov = %p, iovcnt = %d, resid = %u, vmspace = %p\n",
118 uio->uio_iov, uio->uio_iovcnt, uio->uio_resid, uio->uio_vmspace);
120 while (uio->uio_resid > 0) {
121 nbytes = MIN(uio->uio_resid, sizeof mybuffer);
122 if ((ret = uiomove(mybuffer, nbytes, uio)) != 0)
123 return ret; /* Error */
126 return 0; /* Success */
131 * Handle the ioctl for the dev.
133 static int
134 mydevioctl(dev_t dev, u_long cmd, void *data, int flags,
135 struct lwp *proc)
137 const struct mydev_params *params;
138 const struct plistref *pref;
139 char *val;
140 prop_dictionary_t dict;
141 prop_object_t po;
142 int error = 0;
144 switch (cmd) {
145 case MYDEVOLDIOCTL:
146 /* Pass data from userspace to kernel in the conventional way */
147 params = (const struct mydev_params *)data;
148 log(LOG_DEBUG, "mydev: got number of %d and string of %s\n",
149 params->number, params->string);
150 break;
152 case MYDEVSETPROPS:
153 /* Use proplib(3) for userspace/kernel communication */
154 pref = (const struct plistref *)data;
155 error = prop_dictionary_copyin_ioctl(pref, cmd, &dict);
156 if (error)
157 return error;
159 /* Print dict's count for debugging purposes */
160 log(LOG_DEBUG, "mydev: dict count = %u\n",
161 prop_dictionary_count(dict));
163 /* Retrieve object associated with "key" key */
164 po = prop_dictionary_get(dict, "key");
165 if (po == NULL || prop_object_type(po) != PROP_TYPE_STRING) {
166 log(LOG_DEBUG, "mydev: prop_dictionary_get() failed\n");
167 prop_object_release(dict);
168 return -1;
171 /* Print data */
172 val = prop_string_cstring(po);
173 if (val == NULL) {
174 log(LOG_DEBUG, "mydev: prop_string_cstring() failed\n");
175 prop_object_release(po);
176 prop_object_release(dict);
177 return -1;
179 prop_object_release(po);
180 log(LOG_DEBUG, "mydev: <x, y> = (%s, %s)\n", "key", val);
181 free(val, M_TEMP);
183 /* Done */
184 prop_object_release(dict);
185 break;
187 default:
188 /* Inappropriate ioctl for device */
189 error = ENOTTY;
192 return error;