1 | /* $NetBSD: rf_compat50.c,v 1.2 2009/05/02 21:11:26 oster Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Christos Zoulas. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * 3. All advertising materials mentioning features or use of this software |
19 | * must display the following acknowledgement: |
20 | * This product includes software developed by the NetBSD |
21 | * Foundation, Inc. and its contributors. |
22 | * 4. Neither the name of The NetBSD Foundation nor the names of its |
23 | * contributors may be used to endorse or promote products derived |
24 | * from this software without specific prior written permission. |
25 | * |
26 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
27 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
28 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
30 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
36 | * POSSIBILITY OF SUCH DAMAGE. |
37 | */ |
38 | |
39 | #include <sys/types.h> |
40 | #include <sys/param.h> |
41 | #include <sys/systm.h> |
42 | |
43 | #include <dev/raidframe/raidframeio.h> |
44 | #include <dev/raidframe/raidframevar.h> |
45 | |
46 | #include "rf_raid.h" |
47 | #include "rf_compat50.h" |
48 | #include "rf_debugMem.h" |
49 | |
50 | typedef struct RF_Config50_s { |
51 | RF_RowCol_t numRow, numCol, numSpare; |
52 | int32_t devs[RF_MAXROW][RF_MAXCOL]; |
53 | char devnames[RF_MAXROW][RF_MAXCOL][50]; |
54 | int32_t spare_devs[RF_MAXSPARE]; |
55 | char spare_names[RF_MAXSPARE][50]; |
56 | RF_SectorNum_t sectPerSU; |
57 | RF_StripeNum_t SUsPerPU; |
58 | RF_StripeNum_t SUsPerRU; |
59 | RF_ParityConfig_t parityConfig; |
60 | RF_DiskQueueType_t diskQueueType; |
61 | char maxOutstandingDiskReqs; |
62 | char debugVars[RF_MAXDBGV][50]; |
63 | unsigned int layoutSpecificSize; |
64 | void *layoutSpecific; |
65 | int force; |
66 | } RF_Config50_t; |
67 | |
68 | typedef struct RF_RaidDisk50_s { |
69 | char devname[56]; |
70 | RF_DiskStatus_t status; |
71 | RF_RowCol_t spareRow; |
72 | RF_RowCol_t spareCol; |
73 | RF_SectorCount_t numBlocks; |
74 | int blockSize; |
75 | RF_SectorCount_t partitionSize; |
76 | int auto_configured; |
77 | int32_t dev; |
78 | } RF_RaidDisk50_t; |
79 | |
80 | typedef struct RF_DeviceConfig50_s { |
81 | u_int rows; |
82 | u_int cols; |
83 | u_int maxqdepth; |
84 | int ndevs; |
85 | RF_RaidDisk50_t devs[RF_MAX_DISKS]; |
86 | int nspares; |
87 | RF_RaidDisk50_t spares[RF_MAX_DISKS]; |
88 | } RF_DeviceConfig50_t; |
89 | |
90 | static void |
91 | rf_disk_to_disk50(RF_RaidDisk50_t *d50, const RF_RaidDisk_t *d) |
92 | { |
93 | memcpy(d50->devname, d->devname, sizeof(d50->devname)); |
94 | d50->status = d->status; |
95 | d50->spareRow = d->spareRow; |
96 | d50->spareCol = d->spareCol; |
97 | d50->numBlocks = d->numBlocks; |
98 | d50->blockSize = d->blockSize; |
99 | d50->partitionSize = d->partitionSize; |
100 | d50->auto_configured = d->auto_configured; |
101 | d50->dev = d->dev; |
102 | } |
103 | |
104 | int |
105 | rf_config50(RF_Raid_t *raidPtr, int unit, void *data, RF_Config_t **k_cfgp) |
106 | { |
107 | RF_Config50_t *u50_cfg, *k50_cfg; |
108 | RF_Config_t *k_cfg; |
109 | size_t i, j; |
110 | int error; |
111 | |
112 | if (raidPtr->valid) { |
113 | /* There is a valid RAID set running on this unit! */ |
114 | printf("raid%d: Device already configured!\n" , unit); |
115 | return EINVAL; |
116 | } |
117 | |
118 | /* copy-in the configuration information */ |
119 | /* data points to a pointer to the configuration structure */ |
120 | |
121 | u50_cfg = *((RF_Config50_t **) data); |
122 | RF_Malloc(k50_cfg, sizeof(RF_Config50_t), (RF_Config50_t *)); |
123 | if (k50_cfg == NULL) |
124 | return ENOMEM; |
125 | |
126 | error = copyin(u50_cfg, k50_cfg, sizeof(RF_Config50_t)); |
127 | if (error) { |
128 | RF_Free(k50_cfg, sizeof(RF_Config50_t)); |
129 | return error; |
130 | } |
131 | RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *)); |
132 | if (k_cfg == NULL) { |
133 | RF_Free(k50_cfg, sizeof(RF_Config50_t)); |
134 | return ENOMEM; |
135 | } |
136 | |
137 | k_cfg->numRow = k50_cfg->numRow; |
138 | k_cfg->numCol = k50_cfg->numCol; |
139 | k_cfg->numSpare = k50_cfg->numSpare; |
140 | |
141 | for (i = 0; i < RF_MAXROW; i++) |
142 | for (j = 0; j < RF_MAXCOL; j++) |
143 | k_cfg->devs[i][j] = k50_cfg->devs[i][j]; |
144 | |
145 | memcpy(k_cfg->devnames, k50_cfg->devnames, |
146 | sizeof(k_cfg->devnames)); |
147 | |
148 | for (i = 0; i < RF_MAXSPARE; i++) |
149 | k_cfg->spare_devs[i] = k50_cfg->spare_devs[i]; |
150 | |
151 | memcpy(k_cfg->spare_names, k50_cfg->spare_names, |
152 | sizeof(k_cfg->spare_names)); |
153 | |
154 | k_cfg->sectPerSU = k50_cfg->sectPerSU; |
155 | k_cfg->SUsPerPU = k50_cfg->SUsPerPU; |
156 | k_cfg->SUsPerRU = k50_cfg->SUsPerRU; |
157 | k_cfg->parityConfig = k50_cfg->parityConfig; |
158 | |
159 | memcpy(k_cfg->diskQueueType, k50_cfg->diskQueueType, |
160 | sizeof(k_cfg->diskQueueType)); |
161 | |
162 | k_cfg->maxOutstandingDiskReqs = k50_cfg->maxOutstandingDiskReqs; |
163 | |
164 | memcpy(k_cfg->debugVars, k50_cfg->debugVars, |
165 | sizeof(k_cfg->debugVars)); |
166 | |
167 | k_cfg->layoutSpecificSize = k50_cfg->layoutSpecificSize; |
168 | k_cfg->layoutSpecific = k50_cfg->layoutSpecific; |
169 | k_cfg->force = k50_cfg->force; |
170 | |
171 | RF_Free(k50_cfg, sizeof(RF_Config50_t)); |
172 | *k_cfgp = k_cfg; |
173 | return 0; |
174 | } |
175 | |
176 | int |
177 | rf_get_info50(RF_Raid_t *raidPtr, void *data) |
178 | { |
179 | RF_DeviceConfig50_t **ucfgp = data, *d_cfg; |
180 | size_t i, j; |
181 | int error; |
182 | |
183 | if (!raidPtr->valid) |
184 | return ENODEV; |
185 | |
186 | RF_Malloc(d_cfg, sizeof(RF_DeviceConfig50_t), (RF_DeviceConfig50_t *)); |
187 | |
188 | if (d_cfg == NULL) |
189 | return ENOMEM; |
190 | |
191 | d_cfg->rows = 1; /* there is only 1 row now */ |
192 | d_cfg->cols = raidPtr->numCol; |
193 | d_cfg->ndevs = raidPtr->numCol; |
194 | if (d_cfg->ndevs >= RF_MAX_DISKS) |
195 | goto nomem; |
196 | |
197 | d_cfg->nspares = raidPtr->numSpare; |
198 | if (d_cfg->nspares >= RF_MAX_DISKS) |
199 | goto nomem; |
200 | |
201 | d_cfg->maxqdepth = raidPtr->maxQueueDepth; |
202 | for (j = 0; j < d_cfg->cols; j++) |
203 | rf_disk_to_disk50(&d_cfg->devs[j], &raidPtr->Disks[j]); |
204 | |
205 | for (j = d_cfg->cols, i = 0; i < d_cfg->nspares; i++, j++) |
206 | rf_disk_to_disk50(&d_cfg->spares[i], &raidPtr->Disks[j]); |
207 | |
208 | error = copyout(d_cfg, *ucfgp, sizeof(RF_DeviceConfig50_t)); |
209 | RF_Free(d_cfg, sizeof(RF_DeviceConfig50_t)); |
210 | |
211 | return error; |
212 | nomem: |
213 | RF_Free(d_cfg, sizeof(RF_DeviceConfig_t)); |
214 | return ENOMEM; |
215 | } |
216 | |