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

📄 sysfs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	&port_pma_attr_symbol_error.attr.attr,	&port_pma_attr_link_error_recovery.attr.attr,	&port_pma_attr_link_downed.attr.attr,	&port_pma_attr_port_rcv_errors.attr.attr,	&port_pma_attr_port_rcv_remote_physical_errors.attr.attr,	&port_pma_attr_port_rcv_switch_relay_errors.attr.attr,	&port_pma_attr_port_xmit_discards.attr.attr,	&port_pma_attr_port_xmit_constraint_errors.attr.attr,	&port_pma_attr_port_rcv_constraint_errors.attr.attr,	&port_pma_attr_local_link_integrity_errors.attr.attr,	&port_pma_attr_excessive_buffer_overrun_errors.attr.attr,	&port_pma_attr_VL15_dropped.attr.attr,	&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_group.attrs[i]); ++i)		kfree(a);	kfree(p->gid_group.attrs);	for (i = 0; (a = p->pkey_group.attrs[i]); ++i)		kfree(a);	kfree(p->pkey_group.attrs);	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 struct attribute **alloc_group_attrs(ssize_t (*show)(struct ib_port *,				  struct port_attribute *, char *buf),		  int len){	struct attribute **tab_attr;	struct port_table_attribute *element;	int i;	tab_attr = kcalloc(1 + len, sizeof(struct attribute *), GFP_KERNEL);	if (!tab_attr)		return NULL;	for (i = 0; i < len; i++) {		element = kzalloc(sizeof(struct port_table_attribute),				  GFP_KERNEL);		if (!element)			goto err;		if (snprintf(element->name, sizeof(element->name),			     "%d", i) >= sizeof(element->name))			goto err;		element->attr.attr.name  = element->name;		element->attr.attr.mode  = S_IRUGO;		element->attr.attr.owner = THIS_MODULE;		element->attr.show       = show;		element->index		 = i;		tab_attr[i] = &element->attr.attr;	}	return tab_attr;err:	while (--i >= 0)		kfree(tab_attr[i]);	kfree(tab_attr);	return NULL;}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 = kzalloc(sizeof *p, GFP_KERNEL);	if (!p)		return -ENOMEM;	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;	p->gid_group.name  = "gids";	p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);	if (!p->gid_group.attrs)		goto err_remove_pma;	ret = sysfs_create_group(&p->kobj, &p->gid_group);	if (ret)		goto err_free_gid;	p->pkey_group.name  = "pkeys";	p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,						attr.pkey_tbl_len);	if (!p->pkey_group.attrs)		goto err_remove_gid;	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_group.attrs[i]);	kfree(p->pkey_group.attrs);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_group.attrs[i]);	kfree(p->gid_group.attrs);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);	if (!ibdev_is_alive(dev))		return -ENODEV;	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;	if (!ibdev_is_alive(dev))		return -ENODEV;	ret = ib_query_device(dev, &attr);	if (ret)		return ret;	return sprintf(buf, "%04x:%04x:%04x:%04x\n",		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),		       be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),		       be16_to_cpu(((__be16 *) &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;	if (!ibdev_is_alive(dev))		return -ENODEV;	ret = ib_query_device(dev, &attr);	if (ret)		return ret;	return sprintf(buf, "%04x:%04x:%04x:%04x\n",		       be16_to_cpu(((__be16 *) &attr.node_guid)[0]),		       be16_to_cpu(((__be16 *) &attr.node_guid)[1]),		       be16_to_cpu(((__be16 *) &attr.node_guid)[2]),		       be16_to_cpu(((__be16 *) &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 + -