rf_compat80.c revision 1.2.2.6 1 /* $NetBSD: rf_compat80.c,v 1.2.2.6 2019/01/23 20:19:47 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 2017 Matthew R. Green
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34
35 #include <sys/compat_stub.h>
36
37 #include <dev/raidframe/raidframeio.h>
38 #include <dev/raidframe/raidframevar.h>
39
40 #include "rf_raid.h"
41 #include "rf_compat80.h"
42 #include "rf_compat80_mod.h"
43 #include "rf_kintf.h"
44
45 int
46 rf_check_recon_status_ext80(RF_Raid_t *raidPtr, void *data)
47 {
48 RF_ProgressInfo_t info, **infoPtr = data;
49
50 rf_check_recon_status_ext(raidPtr, &info);
51 return copyout(&info, *infoPtr, sizeof info);
52 }
53
54 int
55 rf_check_parityrewrite_status_ext80(RF_Raid_t *raidPtr, void *data)
56 {
57 RF_ProgressInfo_t info, **infoPtr = data;
58
59 rf_check_parityrewrite_status_ext(raidPtr, &info);
60 return copyout(&info, *infoPtr, sizeof info);
61 }
62
63 int
64 rf_check_copyback_status_ext80(RF_Raid_t *raidPtr, void *data)
65 {
66 RF_ProgressInfo_t info, **infoPtr = data;
67
68 rf_check_copyback_status_ext(raidPtr, &info);
69 return copyout(&info, *infoPtr, sizeof info);
70 }
71
72 static void
73 rf_copy_raiddisk80(RF_RaidDisk_t *disk, RF_RaidDisk_t80 *disk80)
74 {
75
76 /* Be sure the padding areas don't have kernel memory. */
77 memset(disk80, 0, sizeof *disk80);
78 memcpy(disk80->devname, disk->devname, sizeof(disk80->devname));
79 disk80->status = disk->status;
80 disk80->spareRow = 0;
81 disk80->spareCol = disk->spareCol;
82 disk80->numBlocks = disk->numBlocks;
83 disk80->blockSize = disk->blockSize;
84 disk80->partitionSize = disk->partitionSize;
85 disk80->auto_configured = disk->auto_configured;
86 disk80->dev = disk->dev;
87 }
88
89 int
90 rf_get_info80(RF_Raid_t *raidPtr, void *data)
91 {
92 RF_DeviceConfig_t *config;
93 RF_DeviceConfig_t80 *config80, **configPtr80 = data;
94 int rv;
95
96 RF_Malloc(config, sizeof *config, (RF_DeviceConfig_t *));
97 if (config == NULL)
98 return (ENOMEM);
99 RF_Malloc(config80, sizeof *config80, (RF_DeviceConfig_t80 *));
100 if (config80 == NULL) {
101 RF_Free(config, sizeof(RF_DeviceConfig_t))
102 return (ENOMEM);
103 }
104 rv = rf_get_info(raidPtr, config);
105 if (rv == 0) {
106 /* convert new to old */
107 config80->rows = 1;
108 config80->cols = config->cols;
109 config80->maxqdepth = config->maxqdepth;
110 config80->ndevs = config->ndevs;
111 config80->nspares = config->nspares;
112 for (size_t i = 0; i < RF_MAX_DISKS; i++) {
113 rf_copy_raiddisk80(&config->devs[i],
114 &config80->devs[i]);
115 rf_copy_raiddisk80(&config->spares[i],
116 &config80->spares[i]);
117 }
118 rv = copyout(config80, *configPtr80, sizeof *config80);
119 }
120 RF_Free(config, sizeof(RF_DeviceConfig_t));
121 RF_Free(config80, sizeof(RF_DeviceConfig_t80));
122
123 return rv;
124 }
125
126 int
127 rf_get_component_label80(RF_Raid_t *raidPtr, void *data)
128 {
129 RF_ComponentLabel_t **clabel_ptr = (RF_ComponentLabel_t **)data;
130 RF_ComponentLabel_t *clabel;
131 int retcode;
132
133 /*
134 * Perhaps there should be an option to skip the in-core
135 * copy and hit the disk, as with disklabel(8).
136 */
137 RF_Malloc(clabel, sizeof(*clabel), (RF_ComponentLabel_t *));
138 if (clabel == NULL)
139 return ENOMEM;
140 retcode = copyin(*clabel_ptr, clabel, sizeof(*clabel));
141 if (retcode) {
142 RF_Free(clabel, sizeof(*clabel));
143 return retcode;
144 }
145
146 rf_get_component_label(raidPtr, clabel);
147 retcode = copyout(clabel, *clabel_ptr, sizeof(**clabel_ptr));
148 RF_Free(clabel, sizeof(*clabel));
149
150 return retcode;
151 }
152
153 int
154 rf_config80(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp)
155 {
156 RF_Config_t80 *u80_cfg, *k80_cfg;
157 RF_Config_t *k_cfg;
158 size_t i, j;
159 int error;
160
161 if (raidPtr->valid) {
162 /* There is a valid RAID set running on this unit! */
163 printf("raid%d: Device already configured!\n", unit);
164 return EINVAL;
165 }
166
167 /* copy-in the configuration information */
168 /* data points to a pointer to the configuration structure */
169
170 u80_cfg = *((RF_Config_t80 **) data);
171 RF_Malloc(k80_cfg, sizeof(RF_Config_t80), (RF_Config_t80 *));
172 if (k80_cfg == NULL)
173 return ENOMEM;
174
175 error = copyin(u80_cfg, k80_cfg, sizeof(RF_Config_t80));
176 if (error) {
177 RF_Free(k80_cfg, sizeof(RF_Config_t80));
178 return error;
179 }
180 RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *));
181 if (k_cfg == NULL) {
182 RF_Free(k80_cfg, sizeof(RF_Config_t80));
183 return ENOMEM;
184 }
185
186 k_cfg->numCol = k80_cfg->numCol;
187 k_cfg->numSpare = k80_cfg->numSpare;
188
189 for (i = 0; i < RF_MAXROW; i++)
190 for (j = 0; j < RF_MAXCOL; j++)
191 k_cfg->devs[i][j] = k80_cfg->devs[i][j];
192
193 memcpy(k_cfg->devnames, k80_cfg->devnames,
194 sizeof(k_cfg->devnames));
195
196 for (i = 0; i < RF_MAXSPARE; i++)
197 k_cfg->spare_devs[i] = k80_cfg->spare_devs[i];
198
199 memcpy(k_cfg->spare_names, k80_cfg->spare_names,
200 sizeof(k_cfg->spare_names));
201
202 k_cfg->sectPerSU = k80_cfg->sectPerSU;
203 k_cfg->SUsPerPU = k80_cfg->SUsPerPU;
204 k_cfg->SUsPerRU = k80_cfg->SUsPerRU;
205 k_cfg->parityConfig = k80_cfg->parityConfig;
206
207 memcpy(k_cfg->diskQueueType, k80_cfg->diskQueueType,
208 sizeof(k_cfg->diskQueueType));
209
210 k_cfg->maxOutstandingDiskReqs = k80_cfg->maxOutstandingDiskReqs;
211
212 memcpy(k_cfg->debugVars, k80_cfg->debugVars,
213 sizeof(k_cfg->debugVars));
214
215 k_cfg->layoutSpecificSize = k80_cfg->layoutSpecificSize;
216 k_cfg->layoutSpecific = k80_cfg->layoutSpecific;
217 k_cfg->force = k80_cfg->force;
218
219 RF_Free(k80_cfg, sizeof(RF_Config_t80));
220 *k_cfgp = k_cfg;
221 return 0;
222 }
223
224 int
225 raidframe_ioctl_80(int cmd, int initted, RF_Raid_t *raidPtr, int unit,
226 void *data, RF_Config_t **k_cfg)
227 {
228 int error;
229
230 switch (cmd) {
231 case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
232 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80:
233 case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
234 case RAIDFRAME_GET_INFO80:
235 case RAIDFRAME_GET_COMPONENT_LABEL80:
236 if (initted == 0)
237 return ENXIO;
238 break;
239 case RAIDFRAME_CONFIGURE80:
240 break;
241 case RAIDFRAME_FAIL_DISK80:
242 return EPASSTHROUGH;
243 default:
244 return EINVAL;
245 }
246
247 switch (cmd) {
248 case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
249 return rf_check_recon_status_ext80(raidPtr, data);
250 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80:
251 return rf_check_parityrewrite_status_ext80(raidPtr, data);
252 case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
253 return rf_check_copyback_status_ext80(raidPtr, data);
254 case RAIDFRAME_GET_INFO80:
255 return rf_get_info80(raidPtr, data);
256 case RAIDFRAME_GET_COMPONENT_LABEL80:
257 return rf_get_component_label80(raidPtr, data);
258 case RAIDFRAME_CONFIGURE80:
259 error = rf_config80(raidPtr, unit, data, k_cfg);
260 if (error != 0)
261 return error;
262 return EAGAIN; /* flag mainline to call generic config */
263 }
264 return EPASSTHROUGH;
265 }
266
267 void
268 raidframe_80_init(void)
269 {
270
271 MODULE_SET_HOOK(raidframe80_ioctl_hook, "raid80", raidframe_ioctl_80);
272 }
273
274 void
275 raidframe_80_fini(void)
276 {
277
278 MODULE_UNSET_HOOK(raidframe80_ioctl_hook);
279 }
280