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