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