Home | History | Annotate | Line # | Download | only in raidframe
rf_compat80.c revision 1.14
      1  1.14  pgoyette /*	$NetBSD: rf_compat80.c,v 1.14 2019/12/12 02:15:43 pgoyette 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.1       mrg #include "rf_kintf.h"
     44   1.1       mrg 
     45  1.11  christos /* NetBSD 8.99.x removed the row, raidPtr and next members */
     46  1.11  christos struct rf_recon_req80 {
     47  1.11  christos 	RF_RowCol_t row, col;
     48  1.11  christos 	RF_ReconReqFlags_t flags;
     49  1.11  christos 	void   *raidPtr;	/* used internally; need not be set at ioctl
     50  1.11  christos 				 * time */
     51  1.11  christos 	struct rf_recon_req *next;	/* used internally; need not be set at
     52  1.11  christos 					 * ioctl time */
     53  1.11  christos };
     54  1.11  christos 
     55  1.11  christos /* NetBSD 8.99.x made this structure alignment neutral */
     56  1.11  christos typedef struct RF_RaidDisk_s80 {
     57  1.11  christos         char    devname[56];    /* name of device file */
     58  1.11  christos         RF_DiskStatus_t status; /* whether it is up or down */
     59  1.11  christos         RF_RowCol_t spareRow;   /* if in status "spared", this identifies the
     60  1.11  christos                                  * spare disk */
     61  1.11  christos         RF_RowCol_t spareCol;   /* if in status "spared", this identifies the
     62  1.11  christos                                  * spare disk */
     63  1.11  christos         RF_SectorCount_t numBlocks;     /* number of blocks, obtained via READ
     64  1.11  christos                                          * CAPACITY */
     65  1.11  christos         int     blockSize;
     66  1.11  christos         RF_SectorCount_t partitionSize; /* The *actual* and *full* size of
     67  1.11  christos                                            the partition, from the disklabel */
     68  1.11  christos         int     auto_configured;/* 1 if this component was autoconfigured.
     69  1.11  christos                                    0 otherwise. */
     70  1.11  christos         dev_t   dev;
     71  1.11  christos } RF_RaidDisk_t80;
     72  1.11  christos 
     73  1.11  christos typedef struct RF_DeviceConfig_s80 {
     74  1.11  christos 	u_int   rows;
     75  1.11  christos 	u_int   cols;
     76  1.11  christos 	u_int   maxqdepth;
     77  1.11  christos 	int     ndevs;
     78  1.11  christos 	RF_RaidDisk_t80 devs[RF_MAX_DISKS];
     79  1.11  christos 	int     nspares;
     80  1.11  christos 	RF_RaidDisk_t80 spares[RF_MAX_DISKS];
     81  1.11  christos } RF_DeviceConfig_t80;
     82  1.11  christos 
     83  1.11  christos typedef struct RF_Config_s80 {
     84  1.11  christos 	RF_RowCol_t numRow, numCol, numSpare;	/* number of rows, columns,
     85  1.11  christos 						 * and spare disks */
     86  1.11  christos 	dev_t   devs[RF_MAXROW][RF_MAXCOL];	/* device numbers for disks
     87  1.11  christos 						 * comprising array */
     88  1.11  christos 	char    devnames[RF_MAXROW][RF_MAXCOL][50];	/* device names */
     89  1.11  christos 	dev_t   spare_devs[RF_MAXSPARE];	/* device numbers for spare
     90  1.11  christos 						 * disks */
     91  1.11  christos 	char    spare_names[RF_MAXSPARE][50];	/* device names */
     92  1.11  christos 	RF_SectorNum_t sectPerSU;	/* sectors per stripe unit */
     93  1.11  christos 	RF_StripeNum_t SUsPerPU;/* stripe units per parity unit */
     94  1.11  christos 	RF_StripeNum_t SUsPerRU;/* stripe units per reconstruction unit */
     95  1.11  christos 	RF_ParityConfig_t parityConfig;	/* identifies the RAID architecture to
     96  1.11  christos 					 * be used */
     97  1.11  christos 	RF_DiskQueueType_t diskQueueType;	/* 'f' = fifo, 'c' = cvscan,
     98  1.11  christos 						 * not used in kernel */
     99  1.11  christos 	char    maxOutstandingDiskReqs;	/* # concurrent reqs to be sent to a
    100  1.11  christos 					 * disk.  not used in kernel. */
    101  1.11  christos 	char    debugVars[RF_MAXDBGV][50];	/* space for specifying debug
    102  1.11  christos 						 * variables & their values */
    103  1.11  christos 	unsigned int layoutSpecificSize;	/* size in bytes of
    104  1.11  christos 						 * layout-specific info */
    105  1.11  christos 	void   *layoutSpecific;	/* a pointer to a layout-specific structure to
    106  1.11  christos 				 * be copied in */
    107  1.11  christos 	int     force;                          /* if !0, ignore many fatal
    108  1.11  christos 						   configuration conditions */
    109  1.11  christos 	/*
    110  1.11  christos 	   "force" is used to override cases where the component labels would
    111  1.11  christos 	   indicate that configuration should not proceed without user
    112  1.11  christos 	   intervention
    113  1.11  christos 	 */
    114  1.11  christos } RF_Config_t80;
    115  1.11  christos 
    116  1.11  christos static int
    117   1.1       mrg rf_check_recon_status_ext80(RF_Raid_t *raidPtr, void *data)
    118   1.1       mrg {
    119   1.1       mrg 	RF_ProgressInfo_t info, **infoPtr = data;
    120   1.1       mrg 
    121   1.1       mrg 	rf_check_recon_status_ext(raidPtr, &info);
    122  1.12  christos 	return copyout(&info, *infoPtr, sizeof(info));
    123   1.1       mrg }
    124   1.1       mrg 
    125  1.11  christos static int
    126   1.1       mrg rf_check_parityrewrite_status_ext80(RF_Raid_t *raidPtr, void *data)
    127   1.1       mrg {
    128   1.1       mrg 	RF_ProgressInfo_t info, **infoPtr = data;
    129   1.1       mrg 
    130   1.1       mrg 	rf_check_parityrewrite_status_ext(raidPtr, &info);
    131  1.12  christos 	return copyout(&info, *infoPtr, sizeof(info));
    132   1.1       mrg }
    133   1.1       mrg 
    134  1.11  christos static int
    135   1.1       mrg rf_check_copyback_status_ext80(RF_Raid_t *raidPtr, void *data)
    136   1.1       mrg {
    137   1.1       mrg 	RF_ProgressInfo_t info, **infoPtr = data;
    138   1.1       mrg 
    139   1.1       mrg 	rf_check_copyback_status_ext(raidPtr, &info);
    140  1.12  christos 	return copyout(&info, *infoPtr, sizeof(info));
    141   1.1       mrg }
    142   1.1       mrg 
    143   1.1       mrg static void
    144   1.1       mrg rf_copy_raiddisk80(RF_RaidDisk_t *disk, RF_RaidDisk_t80 *disk80)
    145   1.1       mrg {
    146   1.1       mrg 
    147   1.1       mrg 	/* Be sure the padding areas don't have kernel memory. */
    148  1.12  christos 	memset(disk80, 0, sizeof(*disk80));
    149   1.1       mrg 	memcpy(disk80->devname, disk->devname, sizeof(disk80->devname));
    150   1.1       mrg 	disk80->status = disk->status;
    151   1.1       mrg 	disk80->spareRow = 0;
    152   1.1       mrg 	disk80->spareCol = disk->spareCol;
    153   1.1       mrg 	disk80->numBlocks = disk->numBlocks;
    154   1.1       mrg 	disk80->blockSize = disk->blockSize;
    155   1.1       mrg 	disk80->partitionSize = disk->partitionSize;
    156   1.1       mrg 	disk80->auto_configured = disk->auto_configured;
    157   1.1       mrg 	disk80->dev = disk->dev;
    158   1.1       mrg }
    159   1.1       mrg 
    160  1.11  christos static int
    161   1.1       mrg rf_get_info80(RF_Raid_t *raidPtr, void *data)
    162   1.1       mrg {
    163   1.1       mrg 	RF_DeviceConfig_t *config;
    164   1.1       mrg 	RF_DeviceConfig_t80 *config80, **configPtr80 = data;
    165   1.1       mrg 	int rv;
    166   1.1       mrg 
    167  1.12  christos 	config = RF_Malloc(sizeof(*config));
    168   1.1       mrg 	if (config == NULL)
    169  1.12  christos 		return ENOMEM;
    170  1.12  christos 	config80 = RF_Malloc(sizeof(*config80));
    171   1.1       mrg 	if (config80 == NULL) {
    172  1.12  christos 		RF_Free(config, sizeof(*config));
    173  1.12  christos 		return ENOMEM;
    174   1.1       mrg 	}
    175   1.1       mrg 	rv = rf_get_info(raidPtr, config);
    176   1.1       mrg 	if (rv == 0) {
    177   1.1       mrg 		/* convert new to old */
    178   1.1       mrg 		config80->rows = 1;
    179   1.1       mrg 		config80->cols = config->cols;
    180   1.1       mrg 		config80->maxqdepth = config->maxqdepth;
    181   1.1       mrg 		config80->ndevs = config->ndevs;
    182   1.1       mrg 		config80->nspares = config->nspares;
    183   1.1       mrg 		for (size_t i = 0; i < RF_MAX_DISKS; i++) {
    184   1.1       mrg 			rf_copy_raiddisk80(&config->devs[i],
    185   1.1       mrg 					   &config80->devs[i]);
    186   1.1       mrg 			rf_copy_raiddisk80(&config->spares[i],
    187   1.1       mrg 					   &config80->spares[i]);
    188   1.1       mrg 		}
    189  1.12  christos 		rv = copyout(config80, *configPtr80, sizeof(*config80));
    190   1.1       mrg 	}
    191  1.12  christos 	RF_Free(config, sizeof(*config));
    192  1.12  christos 	RF_Free(config80, sizeof(*config80));
    193   1.1       mrg 
    194   1.1       mrg 	return rv;
    195   1.1       mrg }
    196   1.1       mrg 
    197  1.11  christos static int
    198   1.1       mrg rf_get_component_label80(RF_Raid_t *raidPtr, void *data)
    199   1.1       mrg {
    200   1.1       mrg 	RF_ComponentLabel_t **clabel_ptr = (RF_ComponentLabel_t **)data;
    201   1.1       mrg 	RF_ComponentLabel_t *clabel;
    202   1.1       mrg 	int retcode;
    203   1.1       mrg 
    204   1.1       mrg 	/*
    205   1.1       mrg 	 * Perhaps there should be an option to skip the in-core
    206   1.1       mrg 	 * copy and hit the disk, as with disklabel(8).
    207   1.1       mrg 	 */
    208  1.12  christos 	clabel = RF_Malloc(sizeof(*clabel));
    209   1.1       mrg 	if (clabel == NULL)
    210   1.1       mrg 		return ENOMEM;
    211   1.1       mrg 	retcode = copyin(*clabel_ptr, clabel, sizeof(*clabel));
    212   1.1       mrg 	if (retcode) {
    213   1.1       mrg 		RF_Free(clabel, sizeof(*clabel));
    214   1.1       mrg 		return retcode;
    215   1.1       mrg 	}
    216   1.1       mrg 
    217   1.1       mrg 	rf_get_component_label(raidPtr, clabel);
    218   1.1       mrg 	retcode = copyout(clabel, *clabel_ptr, sizeof(**clabel_ptr));
    219   1.1       mrg 	RF_Free(clabel, sizeof(*clabel));
    220   1.1       mrg 
    221   1.1       mrg 	return retcode;
    222   1.1       mrg }
    223   1.2       mrg 
    224  1.11  christos static int
    225  1.11  christos rf_config80(struct raid_softc *rs, void *data)
    226   1.2       mrg {
    227   1.2       mrg 	RF_Config_t80 *u80_cfg, *k80_cfg;
    228   1.2       mrg 	RF_Config_t *k_cfg;
    229  1.11  christos 	RF_Raid_t *raidPtr = rf_get_raid(rs);
    230   1.2       mrg 	size_t i, j;
    231   1.2       mrg 	int error;
    232   1.2       mrg 
    233   1.2       mrg 	if (raidPtr->valid) {
    234   1.2       mrg 		/* There is a valid RAID set running on this unit! */
    235  1.11  christos 		printf("raid%d: Device already configured!\n", rf_get_unit(rs));
    236   1.2       mrg 		return EINVAL;
    237   1.2       mrg 	}
    238   1.2       mrg 
    239   1.2       mrg 	/* copy-in the configuration information */
    240   1.2       mrg 	/* data points to a pointer to the configuration structure */
    241   1.2       mrg 
    242   1.2       mrg 	u80_cfg = *((RF_Config_t80 **) data);
    243  1.12  christos 	k80_cfg = RF_Malloc(sizeof(*k80_cfg));
    244   1.2       mrg 	if (k80_cfg == NULL)
    245   1.2       mrg 		return ENOMEM;
    246   1.2       mrg 
    247  1.12  christos 	error = copyin(u80_cfg, k80_cfg, sizeof(*k80_cfg));
    248   1.2       mrg 	if (error) {
    249  1.12  christos 		RF_Free(k80_cfg, sizeof(*k80_cfg));
    250   1.2       mrg 		return error;
    251   1.2       mrg 	}
    252  1.12  christos 	k_cfg = RF_Malloc(sizeof(*k_cfg));
    253   1.2       mrg 	if (k_cfg == NULL) {
    254  1.12  christos 		RF_Free(k80_cfg, sizeof(*k80_cfg));
    255   1.2       mrg 		return ENOMEM;
    256   1.2       mrg 	}
    257   1.2       mrg 
    258   1.2       mrg 	k_cfg->numCol = k80_cfg->numCol;
    259   1.2       mrg 	k_cfg->numSpare = k80_cfg->numSpare;
    260   1.2       mrg 
    261   1.2       mrg 	for (i = 0; i < RF_MAXROW; i++)
    262   1.2       mrg 		for (j = 0; j < RF_MAXCOL; j++)
    263   1.2       mrg 			k_cfg->devs[i][j] = k80_cfg->devs[i][j];
    264   1.2       mrg 
    265   1.2       mrg 	memcpy(k_cfg->devnames, k80_cfg->devnames,
    266   1.2       mrg 	    sizeof(k_cfg->devnames));
    267   1.2       mrg 
    268   1.2       mrg 	for (i = 0; i < RF_MAXSPARE; i++)
    269   1.2       mrg 		k_cfg->spare_devs[i] = k80_cfg->spare_devs[i];
    270   1.2       mrg 
    271   1.2       mrg 	memcpy(k_cfg->spare_names, k80_cfg->spare_names,
    272   1.2       mrg 	    sizeof(k_cfg->spare_names));
    273   1.2       mrg 
    274   1.2       mrg 	k_cfg->sectPerSU = k80_cfg->sectPerSU;
    275   1.2       mrg 	k_cfg->SUsPerPU = k80_cfg->SUsPerPU;
    276   1.2       mrg 	k_cfg->SUsPerRU = k80_cfg->SUsPerRU;
    277   1.2       mrg 	k_cfg->parityConfig = k80_cfg->parityConfig;
    278   1.2       mrg 
    279   1.2       mrg 	memcpy(k_cfg->diskQueueType, k80_cfg->diskQueueType,
    280   1.2       mrg 	    sizeof(k_cfg->diskQueueType));
    281   1.2       mrg 
    282   1.2       mrg 	k_cfg->maxOutstandingDiskReqs = k80_cfg->maxOutstandingDiskReqs;
    283   1.2       mrg 
    284   1.2       mrg 	memcpy(k_cfg->debugVars, k80_cfg->debugVars,
    285   1.2       mrg 	    sizeof(k_cfg->debugVars));
    286   1.2       mrg 
    287   1.2       mrg 	k_cfg->layoutSpecificSize = k80_cfg->layoutSpecificSize;
    288   1.2       mrg 	k_cfg->layoutSpecific = k80_cfg->layoutSpecific;
    289   1.2       mrg 	k_cfg->force = k80_cfg->force;
    290   1.2       mrg 
    291  1.12  christos 	RF_Free(k80_cfg, sizeof(*k80_cfg));
    292  1.11  christos 	return rf_construct(rs, k_cfg);
    293   1.2       mrg }
    294   1.3  pgoyette 
    295   1.9  christos static int
    296   1.9  christos rf_fail_disk80(RF_Raid_t *raidPtr, struct rf_recon_req80 *req80)
    297   1.9  christos {
    298   1.9  christos 	struct rf_recon_req req = {
    299  1.10  christos 		.col = req80->col,
    300  1.10  christos 		.flags = req80->flags,
    301   1.9  christos 	};
    302   1.9  christos 	return rf_fail_disk(raidPtr, &req);
    303   1.9  christos }
    304   1.9  christos 
    305  1.11  christos static int
    306  1.11  christos raidframe_ioctl_80(struct raid_softc *rs, u_long cmd, void *data)
    307   1.3  pgoyette {
    308  1.11  christos 	RF_Raid_t *raidPtr = rf_get_raid(rs);
    309   1.3  pgoyette 
    310   1.3  pgoyette 	switch (cmd) {
    311   1.3  pgoyette 	case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
    312   1.3  pgoyette 	case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80:
    313   1.3  pgoyette 	case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
    314   1.3  pgoyette 	case RAIDFRAME_GET_INFO80:
    315   1.3  pgoyette 	case RAIDFRAME_GET_COMPONENT_LABEL80:
    316  1.11  christos 		if (!rf_inited(rs))
    317   1.3  pgoyette 			return ENXIO;
    318   1.3  pgoyette 		break;
    319   1.3  pgoyette 	case RAIDFRAME_CONFIGURE80:
    320   1.9  christos 	case RAIDFRAME_FAIL_DISK80:
    321   1.3  pgoyette 		break;
    322   1.3  pgoyette 	default:
    323   1.5     oster 		return EPASSTHROUGH;
    324   1.3  pgoyette 	}
    325   1.3  pgoyette 
    326   1.3  pgoyette 	switch (cmd) {
    327   1.3  pgoyette 	case RAIDFRAME_CHECK_RECON_STATUS_EXT80:
    328   1.3  pgoyette 		return rf_check_recon_status_ext80(raidPtr, data);
    329   1.3  pgoyette 	case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT80:
    330   1.3  pgoyette 		return rf_check_parityrewrite_status_ext80(raidPtr, data);
    331   1.3  pgoyette 	case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT80:
    332   1.3  pgoyette 		return rf_check_copyback_status_ext80(raidPtr, data);
    333   1.3  pgoyette 	case RAIDFRAME_GET_INFO80:
    334   1.3  pgoyette 		return rf_get_info80(raidPtr, data);
    335   1.3  pgoyette 	case RAIDFRAME_GET_COMPONENT_LABEL80:
    336   1.3  pgoyette 		return rf_get_component_label80(raidPtr, data);
    337   1.3  pgoyette 	case RAIDFRAME_CONFIGURE80:
    338  1.11  christos 		return rf_config80(rs, data);
    339   1.9  christos 	case RAIDFRAME_FAIL_DISK80:
    340   1.9  christos 		return rf_fail_disk80(raidPtr, data);
    341   1.9  christos 	default:
    342   1.9  christos 		/* abort really */
    343   1.9  christos 		return EPASSTHROUGH;
    344   1.3  pgoyette 	}
    345   1.3  pgoyette }
    346   1.3  pgoyette 
    347   1.8  pgoyette static void
    348   1.3  pgoyette raidframe_80_init(void)
    349   1.3  pgoyette {
    350   1.3  pgoyette 
    351  1.14  pgoyette 	MODULE_HOOK_SET(raidframe_ioctl_80_hook, raidframe_ioctl_80);
    352   1.3  pgoyette }
    353   1.3  pgoyette 
    354   1.8  pgoyette static void
    355   1.3  pgoyette raidframe_80_fini(void)
    356   1.3  pgoyette {
    357   1.3  pgoyette 
    358  1.13  pgoyette 	MODULE_HOOK_UNSET(raidframe_ioctl_80_hook);
    359   1.3  pgoyette }
    360   1.3  pgoyette 
    361   1.3  pgoyette MODULE(MODULE_CLASS_EXEC, compat_raid_80, "raid,compat_80");
    362   1.3  pgoyette 
    363   1.3  pgoyette static int
    364   1.3  pgoyette compat_raid_80_modcmd(modcmd_t cmd, void *arg)
    365   1.3  pgoyette {
    366   1.3  pgoyette 
    367   1.3  pgoyette 	switch (cmd) {
    368   1.3  pgoyette 	case MODULE_CMD_INIT:
    369   1.3  pgoyette 		raidframe_80_init();
    370   1.3  pgoyette 		return 0;
    371   1.3  pgoyette 	case MODULE_CMD_FINI:
    372   1.3  pgoyette 		raidframe_80_fini();
    373   1.3  pgoyette 		return 0;
    374   1.3  pgoyette 	default:
    375   1.3  pgoyette 		return ENOTTY;
    376   1.3  pgoyette 	}
    377   1.3  pgoyette }
    378