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