Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * raid_class.c - implementation of a simple raid visualisation class
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This class is designed to allow raid attributes to be visualised and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * manipulated in a form independent of the underlying raid.  Ultimately this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * should work for both hardware and software raids.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/raid_class.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define RAID_NUM_ATTRS	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) struct raid_internal {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct raid_template r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	struct raid_function_template *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	/* The actual attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	struct device_attribute private_attrs[RAID_NUM_ATTRS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	/* The array of null terminated pointers to attributes 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	 * needed by scsi_sysfs.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	struct device_attribute *attrs[RAID_NUM_ATTRS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct raid_component {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define to_raid_internal(tmpl)	container_of(tmpl, struct raid_internal, r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define tc_to_raid_internal(tcont) ({					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct raid_template *r =					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		container_of(tcont, struct raid_template, raid_attrs);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	to_raid_internal(r);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define ac_to_raid_internal(acont) ({					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct transport_container *tc =				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		container_of(acont, struct transport_container, ac);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	tc_to_raid_internal(tc);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define device_to_raid_internal(dev) ({				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct attribute_container *ac =				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		attribute_container_classdev_to_container(dev);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	ac_to_raid_internal(ac);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static int raid_match(struct attribute_container *cont, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	/* We have to look for every subsystem that could house
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	 * emulated RAID devices, so start with SCSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct raid_internal *i = ac_to_raid_internal(cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (IS_ENABLED(CONFIG_SCSI) && scsi_is_sdev_device(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		struct scsi_device *sdev = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if (i->f->cookie != sdev->host->hostt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		return i->f->is_raid(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	/* FIXME: look at other subsystems too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static int raid_setup(struct transport_container *tc, struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		       struct device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct raid_data *rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	BUG_ON(dev_get_drvdata(cdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	rd = kzalloc(sizeof(*rd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (!rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	INIT_LIST_HEAD(&rd->component_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	dev_set_drvdata(cdev, rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static int raid_remove(struct transport_container *tc, struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		       struct device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct raid_data *rd = dev_get_drvdata(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct raid_component *rc, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	dev_printk(KERN_ERR, dev, "RAID REMOVE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	dev_set_drvdata(cdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	list_for_each_entry_safe(rc, next, &rd->component_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		list_del(&rc->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		dev_printk(KERN_ERR, rc->dev.parent, "RAID COMPONENT REMOVE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		device_unregister(&rc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	dev_printk(KERN_ERR, dev, "RAID REMOVE DONE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	kfree(rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static DECLARE_TRANSPORT_CLASS(raid_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			       "raid_devices",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			       raid_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			       raid_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			       NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	enum raid_state	value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	char		*name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) } raid_states[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{ RAID_STATE_UNKNOWN, "unknown" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	{ RAID_STATE_ACTIVE, "active" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	{ RAID_STATE_DEGRADED, "degraded" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	{ RAID_STATE_RESYNCING, "resyncing" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	{ RAID_STATE_OFFLINE, "offline" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static const char *raid_state_name(enum raid_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	for (i = 0; i < ARRAY_SIZE(raid_states); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		if (raid_states[i].value == state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			name = raid_states[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	enum raid_level value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) } raid_levels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	{ RAID_LEVEL_UNKNOWN, "unknown" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	{ RAID_LEVEL_LINEAR, "linear" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	{ RAID_LEVEL_0, "raid0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	{ RAID_LEVEL_1, "raid1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	{ RAID_LEVEL_10, "raid10" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	{ RAID_LEVEL_1E, "raid1e" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	{ RAID_LEVEL_3, "raid3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	{ RAID_LEVEL_4, "raid4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	{ RAID_LEVEL_5, "raid5" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	{ RAID_LEVEL_50, "raid50" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	{ RAID_LEVEL_6, "raid6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	{ RAID_LEVEL_JBOD, "jbod" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static const char *raid_level_name(enum raid_level level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	for (i = 0; i < ARRAY_SIZE(raid_levels); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		if (raid_levels[i].value == level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			name = raid_levels[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define raid_attr_show_internal(attr, fmt, var, code)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static ssize_t raid_show_##attr(struct device *dev, 			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				struct device_attribute *attr, 		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				char *buf)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct raid_data *rd = dev_get_drvdata(dev);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	code								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return snprintf(buf, 20, #fmt "\n", var);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define raid_attr_ro_states(attr, states, code)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) raid_attr_show_internal(attr, %s, name,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	const char *name;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	code								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	name = raid_##states##_name(rd->attr);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) )									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define raid_attr_ro_internal(attr, code)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) raid_attr_show_internal(attr, %d, rd->attr, code)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define ATTR_CODE(attr)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct raid_internal *i = device_to_raid_internal(dev);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	if (i->f->get_##attr)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		i->f->get_##attr(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define raid_attr_ro(attr)	raid_attr_ro_internal(attr, )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define raid_attr_ro_fn(attr)	raid_attr_ro_internal(attr, ATTR_CODE(attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define raid_attr_ro_state(attr)	raid_attr_ro_states(attr, attr, )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define raid_attr_ro_state_fn(attr)	raid_attr_ro_states(attr, attr, ATTR_CODE(attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) raid_attr_ro_state(level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) raid_attr_ro_fn(resync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) raid_attr_ro_state_fn(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static void raid_component_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	struct raid_component *rc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		container_of(dev, struct raid_component, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	dev_printk(KERN_ERR, rc->dev.parent, "COMPONENT RELEASE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	put_device(rc->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	kfree(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int raid_component_add(struct raid_template *r,struct device *raid_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		       struct device *component_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	struct device *cdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		attribute_container_find_class_device(&r->raid_attrs.ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 						      raid_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	struct raid_component *rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	struct raid_data *rd = dev_get_drvdata(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	rc = kzalloc(sizeof(*rc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	INIT_LIST_HEAD(&rc->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	device_initialize(&rc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	rc->dev.release = raid_component_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	rc->dev.parent = get_device(component_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	rc->num = rd->component_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	dev_set_name(&rc->dev, "component-%d", rc->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	list_add_tail(&rc->node, &rd->component_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	rc->dev.class = &raid_class.class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	err = device_add(&rc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	list_del(&rc->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	rd->component_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	put_device(component_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	kfree(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) EXPORT_SYMBOL(raid_component_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct raid_template *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) raid_class_attach(struct raid_function_template *ft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct raid_internal *i = kzalloc(sizeof(struct raid_internal),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 					  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (unlikely(!i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	i->f = ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	i->r.raid_attrs.ac.class = &raid_class.class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	i->r.raid_attrs.ac.match = raid_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	i->r.raid_attrs.ac.attrs = &i->attrs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	attribute_container_register(&i->r.raid_attrs.ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	i->attrs[count++] = &dev_attr_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	i->attrs[count++] = &dev_attr_resync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	i->attrs[count++] = &dev_attr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	i->attrs[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	BUG_ON(count > RAID_NUM_ATTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	return &i->r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) EXPORT_SYMBOL(raid_class_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) raid_class_release(struct raid_template *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct raid_internal *i = to_raid_internal(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	BUG_ON(attribute_container_unregister(&i->r.raid_attrs.ac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	kfree(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) EXPORT_SYMBOL(raid_class_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static __init int raid_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	return transport_class_register(&raid_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static __exit void raid_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	transport_class_unregister(&raid_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) MODULE_AUTHOR("James Bottomley");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) MODULE_DESCRIPTION("RAID device class");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) module_init(raid_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) module_exit(raid_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)