⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysfs.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	&port_pma_attr_port_xmit_data.attr.attr,	&port_pma_attr_port_rcv_data.attr.attr,	&port_pma_attr_port_xmit_packets.attr.attr,	&port_pma_attr_port_rcv_packets.attr.attr,	NULL};static struct attribute_group pma_group = {	.name  = "counters",	.attrs  = pma_attrs};static void ib_port_release(struct kobject *kobj){	struct ib_port *p = container_of(kobj, struct ib_port, kobj);	struct attribute *a;	int i;	for (i = 0; (a = p->gid_attr[i]); ++i) {		kfree(a->name);		kfree(a);	}	for (i = 0; (a = p->pkey_attr[i]); ++i) {		kfree(a->name);		kfree(a);	}	kfree(p->gid_attr);	kfree(p);}static struct kobj_type port_type = {	.release       = ib_port_release,	.sysfs_ops     = &port_sysfs_ops,	.default_attrs = port_default_attrs};static void ib_device_release(struct class_device *cdev){	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);	kfree(dev);}static int ib_device_hotplug(struct class_device *cdev, char **envp,			     int num_envp, char *buf, int size){	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);	int i = 0, len = 0;	if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len,				"NAME=%s", dev->name))		return -ENOMEM;	/*	 * It might be nice to pass the node GUID to hotplug, but	 * right now the only way to get it is to query the device	 * provider, and this can crash during device removal because	 * we are will be running after driver removal has started.	 * We could add a node_guid field to struct ib_device, or we	 * could just let the hotplug script read the node GUID from	 * sysfs when devices are added.	 */	envp[i] = NULL;	return 0;}static int alloc_group(struct attribute ***attr,		       ssize_t (*show)(struct ib_port *,				       struct port_attribute *, char *buf),		       int len){	struct port_table_attribute ***tab_attr =		(struct port_table_attribute ***) attr;	int i;	int ret;	*tab_attr = kmalloc((1 + len) * sizeof *tab_attr, GFP_KERNEL);	if (!*tab_attr)		return -ENOMEM;	memset(*tab_attr, 0, (1 + len) * sizeof *tab_attr);	for (i = 0; i < len; ++i) {		(*tab_attr)[i] = kmalloc(sizeof *(*tab_attr)[i], GFP_KERNEL);		if (!(*tab_attr)[i]) {			ret = -ENOMEM;			goto err;		}		memset((*tab_attr)[i], 0, sizeof *(*tab_attr)[i]);		(*tab_attr)[i]->attr.attr.name = kmalloc(8, GFP_KERNEL);		if (!(*tab_attr)[i]->attr.attr.name) {			ret = -ENOMEM;			goto err;		}		if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) {			ret = -ENOMEM;			goto err;		}		(*tab_attr)[i]->attr.attr.mode  = S_IRUGO;		(*tab_attr)[i]->attr.attr.owner = THIS_MODULE;		(*tab_attr)[i]->attr.show       = show;		(*tab_attr)[i]->index           = i;	}	return 0;err:	for (i = 0; i < len; ++i) {		if ((*tab_attr)[i])			kfree((*tab_attr)[i]->attr.attr.name);		kfree((*tab_attr)[i]);	}	kfree(*tab_attr);	return ret;}static int add_port(struct ib_device *device, int port_num){	struct ib_port *p;	struct ib_port_attr attr;	int i;	int ret;	ret = ib_query_port(device, port_num, &attr);	if (ret)		return ret;	p = kmalloc(sizeof *p, GFP_KERNEL);	if (!p)		return -ENOMEM;	memset(p, 0, sizeof *p);	p->ibdev      = device;	p->port_num   = port_num;	p->kobj.ktype = &port_type;	p->kobj.parent = kobject_get(&device->ports_parent);	if (!p->kobj.parent) {		ret = -EBUSY;		goto err;	}	ret = kobject_set_name(&p->kobj, "%d", port_num);	if (ret)		goto err_put;	ret = kobject_register(&p->kobj);	if (ret)		goto err_put;	ret = sysfs_create_group(&p->kobj, &pma_group);	if (ret)		goto err_put;	ret = alloc_group(&p->gid_attr, show_port_gid, attr.gid_tbl_len);	if (ret)		goto err_remove_pma;	p->gid_group.name  = "gids";	p->gid_group.attrs = p->gid_attr;	ret = sysfs_create_group(&p->kobj, &p->gid_group);	if (ret)		goto err_free_gid;	ret = alloc_group(&p->pkey_attr, show_port_pkey, attr.pkey_tbl_len);	if (ret)		goto err_remove_gid;	p->pkey_group.name  = "pkeys";	p->pkey_group.attrs = p->pkey_attr;	ret = sysfs_create_group(&p->kobj, &p->pkey_group);	if (ret)		goto err_free_pkey;	list_add_tail(&p->kobj.entry, &device->port_list);	return 0;err_free_pkey:	for (i = 0; i < attr.pkey_tbl_len; ++i) {		kfree(p->pkey_attr[i]->name);		kfree(p->pkey_attr[i]);	}	kfree(p->pkey_attr);err_remove_gid:	sysfs_remove_group(&p->kobj, &p->gid_group);err_free_gid:	for (i = 0; i < attr.gid_tbl_len; ++i) {		kfree(p->gid_attr[i]->name);		kfree(p->gid_attr[i]);	}	kfree(p->gid_attr);err_remove_pma:	sysfs_remove_group(&p->kobj, &pma_group);err_put:	kobject_put(&device->ports_parent);err:	kfree(p);	return ret;}static ssize_t show_node_type(struct class_device *cdev, char *buf){	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);	switch (dev->node_type) {	case IB_NODE_CA:     return sprintf(buf, "%d: CA\n", dev->node_type);	case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);	case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);	default:             return sprintf(buf, "%d: <unknown>\n", dev->node_type);	}}static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf){	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);	struct ib_device_attr attr;	ssize_t ret;	ret = ib_query_device(dev, &attr);	if (ret)		return ret;	return sprintf(buf, "%04x:%04x:%04x:%04x\n",		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]),		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]),		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]),		       be16_to_cpu(((u16 *) &attr.sys_image_guid)[3]));}static ssize_t show_node_guid(struct class_device *cdev, char *buf){	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);	struct ib_device_attr attr;	ssize_t ret;	ret = ib_query_device(dev, &attr);	if (ret)		return ret;	return sprintf(buf, "%04x:%04x:%04x:%04x\n",		       be16_to_cpu(((u16 *) &attr.node_guid)[0]),		       be16_to_cpu(((u16 *) &attr.node_guid)[1]),		       be16_to_cpu(((u16 *) &attr.node_guid)[2]),		       be16_to_cpu(((u16 *) &attr.node_guid)[3]));}static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);static struct class_device_attribute *ib_class_attributes[] = {	&class_device_attr_node_type,	&class_device_attr_sys_image_guid,	&class_device_attr_node_guid};static struct class ib_class = {	.name    = "infiniband",	.release = ib_device_release,	.hotplug = ib_device_hotplug,};int ib_device_register_sysfs(struct ib_device *device){	struct class_device *class_dev = &device->class_dev;	int ret;	int i;	class_dev->class      = &ib_class;	class_dev->class_data = device;	strlcpy(class_dev->class_id, device->name, BUS_ID_SIZE);	INIT_LIST_HEAD(&device->port_list);	ret = class_device_register(class_dev);	if (ret)		goto err;	for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) {		ret = class_device_create_file(class_dev, ib_class_attributes[i]);		if (ret)			goto err_unregister;	}	device->ports_parent.parent = kobject_get(&class_dev->kobj);	if (!device->ports_parent.parent) {		ret = -EBUSY;		goto err_unregister;	}	ret = kobject_set_name(&device->ports_parent, "ports");	if (ret)		goto err_put;	ret = kobject_register(&device->ports_parent);	if (ret)		goto err_put;	if (device->node_type == IB_NODE_SWITCH) {		ret = add_port(device, 0);		if (ret)			goto err_put;	} else {		int i;		for (i = 1; i <= device->phys_port_cnt; ++i) {			ret = add_port(device, i);			if (ret)				goto err_put;		}	}	return 0;err_put:	{		struct kobject *p, *t;		struct ib_port *port;		list_for_each_entry_safe(p, t, &device->port_list, entry) {			list_del(&p->entry);			port = container_of(p, struct ib_port, kobj);			sysfs_remove_group(p, &pma_group);			sysfs_remove_group(p, &port->pkey_group);			sysfs_remove_group(p, &port->gid_group);			kobject_unregister(p);		}	}	kobject_put(&class_dev->kobj);err_unregister:	class_device_unregister(class_dev);err:	return ret;}void ib_device_unregister_sysfs(struct ib_device *device){	struct kobject *p, *t;	struct ib_port *port;	list_for_each_entry_safe(p, t, &device->port_list, entry) {		list_del(&p->entry);		port = container_of(p, struct ib_port, kobj);		sysfs_remove_group(p, &pma_group);		sysfs_remove_group(p, &port->pkey_group);		sysfs_remove_group(p, &port->gid_group);		kobject_unregister(p);	}	kobject_unregister(&device->ports_parent);	class_device_unregister(&device->class_dev);}int ib_sysfs_setup(void){	return class_register(&ib_class);}void ib_sysfs_cleanup(void){	class_unregister(&ib_class);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -