xref: /illumos-gate/usr/src/uts/common/io/ksensor/ksensor_test.c (revision e0721d5ae1542c80097f6fcd487736fdfe601233)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2020 Oxide Computer Company
14  */
15 
16 /*
17  * This driver is used to implement parts of the ksensor test suite.
18  */
19 
20 #include <sys/ddi.h>
21 #include <sys/sunddi.h>
22 #include <sys/modctl.h>
23 #include <sys/conf.h>
24 #include <sys/devops.h>
25 #include <sys/zone.h>
26 #include <sys/sensors.h>
27 
28 typedef struct ksensor_test {
29 	dev_info_t *kt_dip;
30 	id_t kt_sensor1;
31 	id_t kt_sensor2;
32 	id_t kt_sensor3;
33 	id_t kt_sensor4;
34 	id_t kt_sensor5;
35 } ksensor_test_t;
36 
37 static int
38 ksensor_test_temperature(void *arg, sensor_ioctl_temperature_t *temp)
39 {
40 	temp->sit_unit = SENSOR_UNIT_CELSIUS;
41 	temp->sit_gran = 4;
42 	temp->sit_prec = -2;
43 	temp->sit_temp = 23;
44 	return (0);
45 }
46 
47 static const ksensor_ops_t ksensor_test_temp_ops = {
48 	ksensor_kind_temperature,
49 	ksensor_test_temperature
50 };
51 
52 static int
53 ksensor_test_kind_eio(void *arg, sensor_ioctl_kind_t *kindp)
54 {
55 	return (EIO);
56 }
57 
58 static int
59 ksensor_test_temp_eio(void *arg, sensor_ioctl_temperature_t *tempp)
60 {
61 	return (EIO);
62 }
63 
64 static const ksensor_ops_t ksensor_test_eio_ops = {
65 	ksensor_test_kind_eio,
66 	ksensor_test_temp_eio
67 };
68 
69 static int
70 ksensor_test_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
71 {
72 	int ret;
73 	char buf[128];
74 	ksensor_test_t *kt;
75 
76 	switch (cmd) {
77 	case DDI_RESUME:
78 		return (DDI_SUCCESS);
79 	case DDI_ATTACH:
80 		break;
81 	default:
82 		return (DDI_FAILURE);
83 	}
84 
85 	kt = kmem_zalloc(sizeof (ksensor_test_t), KM_SLEEP);
86 	kt->kt_dip = dip;
87 
88 	(void) snprintf(buf, sizeof (buf), "test.temp.%d.1",
89 	    ddi_get_instance(dip));
90 	if ((ret = ksensor_create(dip, &ksensor_test_temp_ops, NULL, buf,
91 	    "ddi_sensor:test", &kt->kt_sensor1)) != 0) {
92 		dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf,
93 		    ret);
94 		goto err;
95 	}
96 
97 	(void) snprintf(buf, sizeof (buf), "test.temp.%d.2",
98 	    ddi_get_instance(dip));
99 	if ((ret = ksensor_create(dip, &ksensor_test_temp_ops, NULL, buf,
100 	    "ddi_sensor:test", &kt->kt_sensor2)) != 0) {
101 		dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf,
102 		    ret);
103 		goto err;
104 	}
105 
106 	(void) snprintf(buf, sizeof (buf), "test.temp.%d.3",
107 	    ddi_get_instance(dip));
108 	if ((ret = ksensor_create(dip, &ksensor_test_temp_ops, NULL, buf,
109 	    "ddi_sensor:test", &kt->kt_sensor3)) != 0) {
110 		dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf,
111 		    ret);
112 		goto err;
113 	}
114 
115 	(void) snprintf(buf, sizeof (buf), "test.temp.%d.4",
116 	    ddi_get_instance(dip));
117 	if ((ret = ksensor_create(dip, &ksensor_test_temp_ops, NULL, buf,
118 	    "ddi_sensor:test", &kt->kt_sensor4)) != 0) {
119 		dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf,
120 		    ret);
121 		goto err;
122 	}
123 
124 	(void) snprintf(buf, sizeof (buf), "test.eio.%d",
125 	    ddi_get_instance(dip));
126 	if ((ret = ksensor_create(dip, &ksensor_test_eio_ops, NULL, buf,
127 	    "ddi_sensor:test", &kt->kt_sensor5)) != 0) {
128 		dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf,
129 		    ret);
130 		goto err;
131 	}
132 
133 	ddi_set_driver_private(dip, kt);
134 
135 	return (DDI_SUCCESS);
136 err:
137 	(void) ksensor_remove(dip, KSENSOR_ALL_IDS);
138 	kmem_free(kt, sizeof (ksensor_test_t));
139 	return (DDI_FAILURE);
140 }
141 
142 static int
143 ksensor_test_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
144 {
145 	ksensor_test_t *kt;
146 
147 	switch (cmd) {
148 	case DDI_DETACH:
149 		break;
150 	case DDI_SUSPEND:
151 		return (DDI_SUCCESS);
152 	default:
153 		return (DDI_FAILURE);
154 	}
155 
156 	kt = ddi_get_driver_private(dip);
157 	if (kt == NULL) {
158 		dev_err(dip, CE_WARN, "failed to find ksensor_test_t");
159 		return (DDI_FAILURE);
160 	}
161 
162 	if (kt->kt_sensor3 != 0 &&
163 	    ksensor_remove(dip, kt->kt_sensor3) != 0) {
164 		dev_err(dip, CE_WARN, "failed to remove sensor 3");
165 		return (DDI_FAILURE);
166 	}
167 	kt->kt_sensor3 = 0;
168 	if (ksensor_remove(dip, KSENSOR_ALL_IDS) != 0) {
169 		dev_err(dip, CE_WARN, "failed to remove sensors");
170 		return (DDI_FAILURE);
171 	}
172 	kmem_free(kt, sizeof (*kt));
173 	ddi_set_driver_private(dip, NULL);
174 	return (DDI_SUCCESS);
175 }
176 
177 static struct dev_ops ksensor_test_dev_ops = {
178 	.devo_rev = DEVO_REV,
179 	.devo_refcnt = 0,
180 	.devo_getinfo = nodev,
181 	.devo_identify = nulldev,
182 	.devo_probe = nulldev,
183 	.devo_attach = ksensor_test_attach,
184 	.devo_detach = ksensor_test_detach,
185 	.devo_reset = nodev,
186 	.devo_power = ddi_power,
187 	.devo_quiesce = ddi_quiesce_not_needed,
188 };
189 
190 static struct modldrv ksensor_test_modldrv = {
191 	.drv_modops = &mod_driverops,
192 	.drv_linkinfo = "Kernel Sensor test driver",
193 	.drv_dev_ops = &ksensor_test_dev_ops
194 };
195 
196 static struct modlinkage ksensor_test_modlinkage = {
197 	.ml_rev = MODREV_1,
198 	.ml_linkage = { &ksensor_test_modldrv, NULL }
199 };
200 
201 int
202 _init(void)
203 {
204 	return (mod_install(&ksensor_test_modlinkage));
205 }
206 
207 int
208 _info(struct modinfo *modinfop)
209 {
210 	return (mod_info(&ksensor_test_modlinkage, modinfop));
211 }
212 
213 int
214 _fini(void)
215 {
216 	return (mod_remove(&ksensor_test_modlinkage));
217 }
218