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

📄 ucm.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_rtu);}static ssize_t ib_ucm_send_dreq(struct ib_ucm_file *file,				const char __user *inbuf,				int in_len, int out_len){	return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_dreq);}static ssize_t ib_ucm_send_drep(struct ib_ucm_file *file,				const char __user *inbuf,				int in_len, int out_len){	return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_drep);}static ssize_t ib_ucm_send_info(struct ib_ucm_file *file,				const char __user *inbuf, int in_len,				int (*func)(struct ib_cm_id *cm_id,					    int status,					    const void *info,					    u8 info_len,					    const void *data,					    u8 data_len)){	struct ib_ucm_context *ctx;	struct ib_ucm_info cmd;	const void *data = NULL;	const void *info = NULL;	int result;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&data, cmd.data, cmd.data_len);	if (result)		goto done;	result = ib_ucm_alloc_data(&info, cmd.info, cmd.info_len);	if (result)		goto done;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = func(ctx->cm_id, cmd.status, info, cmd.info_len,			      data, cmd.data_len);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);done:	kfree(data);	kfree(info);	return result;}static ssize_t ib_ucm_send_rej(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){	return ib_ucm_send_info(file, inbuf, in_len, (void *)ib_send_cm_rej);}static ssize_t ib_ucm_send_apr(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){	return ib_ucm_send_info(file, inbuf, in_len, (void *)ib_send_cm_apr);}static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){	struct ib_ucm_context *ctx;	struct ib_ucm_mra cmd;	const void *data = NULL;	int result;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&data, cmd.data, cmd.len);	if (result)		return result;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = ib_send_cm_mra(ctx->cm_id, cmd.timeout, data, cmd.len);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);	kfree(data);	return result;}static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file,			       const char __user *inbuf,			       int in_len, int out_len){	struct ib_ucm_context *ctx;	struct ib_sa_path_rec *path = NULL;	struct ib_ucm_lap cmd;	const void *data = NULL;	int result;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&data, cmd.data, cmd.len);	if (result)		goto done;	result = ib_ucm_path_get(&path, cmd.path);	if (result)		goto done;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);done:	kfree(data);	kfree(path);	return result;}static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file,				    const char __user *inbuf,				    int in_len, int out_len){	struct ib_cm_sidr_req_param param;	struct ib_ucm_context *ctx;	struct ib_ucm_sidr_req cmd;	int result;	param.private_data = NULL;	param.path = NULL;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&param.private_data, cmd.data, cmd.len);	if (result)		goto done;	result = ib_ucm_path_get(&param.path, cmd.path);	if (result)		goto done;	param.private_data_len = cmd.len;	param.service_id       = cmd.sid;	param.timeout_ms       = cmd.timeout;	param.max_cm_retries   = cmd.max_cm_retries;	param.pkey             = cmd.pkey;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = ib_send_cm_sidr_req(ctx->cm_id, &param);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);done:	kfree(param.private_data);	kfree(param.path);	return result;}static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file,				    const char __user *inbuf,				    int in_len, int out_len){	struct ib_cm_sidr_rep_param param;	struct ib_ucm_sidr_rep cmd;	struct ib_ucm_context *ctx;	int result;	param.info = NULL;	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))		return -EFAULT;	result = ib_ucm_alloc_data(&param.private_data,				   cmd.data, cmd.data_len);	if (result)		goto done;	result = ib_ucm_alloc_data(&param.info, cmd.info, cmd.info_len);	if (result)		goto done;	param.qp_num		= cmd.qpn;	param.qkey		= cmd.qkey;	param.status		= cmd.status;	param.info_length	= cmd.info_len;	param.private_data_len	= cmd.data_len;	ctx = ib_ucm_ctx_get(file, cmd.id);	if (!IS_ERR(ctx)) {		result = ib_send_cm_sidr_rep(ctx->cm_id, &param);		ib_ucm_ctx_put(ctx);	} else		result = PTR_ERR(ctx);done:	kfree(param.private_data);	kfree(param.info);	return result;}static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file,				  const char __user *inbuf,				  int in_len, int out_len) = {	[IB_USER_CM_CMD_CREATE_ID]     = ib_ucm_create_id,	[IB_USER_CM_CMD_DESTROY_ID]    = ib_ucm_destroy_id,	[IB_USER_CM_CMD_ATTR_ID]       = ib_ucm_attr_id,	[IB_USER_CM_CMD_LISTEN]        = ib_ucm_listen,	[IB_USER_CM_CMD_ESTABLISH]     = ib_ucm_establish,	[IB_USER_CM_CMD_SEND_REQ]      = ib_ucm_send_req,	[IB_USER_CM_CMD_SEND_REP]      = ib_ucm_send_rep,	[IB_USER_CM_CMD_SEND_RTU]      = ib_ucm_send_rtu,	[IB_USER_CM_CMD_SEND_DREQ]     = ib_ucm_send_dreq,	[IB_USER_CM_CMD_SEND_DREP]     = ib_ucm_send_drep,	[IB_USER_CM_CMD_SEND_REJ]      = ib_ucm_send_rej,	[IB_USER_CM_CMD_SEND_MRA]      = ib_ucm_send_mra,	[IB_USER_CM_CMD_SEND_LAP]      = ib_ucm_send_lap,	[IB_USER_CM_CMD_SEND_APR]      = ib_ucm_send_apr,	[IB_USER_CM_CMD_SEND_SIDR_REQ] = ib_ucm_send_sidr_req,	[IB_USER_CM_CMD_SEND_SIDR_REP] = ib_ucm_send_sidr_rep,	[IB_USER_CM_CMD_EVENT]	       = ib_ucm_event,	[IB_USER_CM_CMD_INIT_QP_ATTR]  = ib_ucm_init_qp_attr,};static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,			    size_t len, loff_t *pos){	struct ib_ucm_file *file = filp->private_data;	struct ib_ucm_cmd_hdr hdr;	ssize_t result;	if (len < sizeof(hdr))		return -EINVAL;	if (copy_from_user(&hdr, buf, sizeof(hdr)))		return -EFAULT;	if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table))		return -EINVAL;	if (hdr.in + sizeof(hdr) > len)		return -EINVAL;	result = ucm_cmd_table[hdr.cmd](file, buf + sizeof(hdr),					hdr.in, hdr.out);	if (!result)		result = len;	return result;}static unsigned int ib_ucm_poll(struct file *filp,				struct poll_table_struct *wait){	struct ib_ucm_file *file = filp->private_data;	unsigned int mask = 0;	poll_wait(filp, &file->poll_wait, wait);	if (!list_empty(&file->events))		mask = POLLIN | POLLRDNORM;	return mask;}static int ib_ucm_open(struct inode *inode, struct file *filp){	struct ib_ucm_file *file;	file = kmalloc(sizeof(*file), GFP_KERNEL);	if (!file)		return -ENOMEM;	INIT_LIST_HEAD(&file->events);	INIT_LIST_HEAD(&file->ctxs);	init_waitqueue_head(&file->poll_wait);	init_MUTEX(&file->mutex);	filp->private_data = file;	file->filp = filp;	file->device = container_of(inode->i_cdev, struct ib_ucm_device, dev);	return 0;}static int ib_ucm_close(struct inode *inode, struct file *filp){	struct ib_ucm_file *file = filp->private_data;	struct ib_ucm_context *ctx;	down(&file->mutex);	while (!list_empty(&file->ctxs)) {		ctx = list_entry(file->ctxs.next,				 struct ib_ucm_context, file_list);		up(&file->mutex);		down(&ctx_id_mutex);		idr_remove(&ctx_id_table, ctx->id);		up(&ctx_id_mutex);		ib_destroy_cm_id(ctx->cm_id);		ib_ucm_cleanup_events(ctx);		kfree(ctx);		down(&file->mutex);	}	up(&file->mutex);	kfree(file);	return 0;}static void ib_ucm_release_class_dev(struct class_device *class_dev){	struct ib_ucm_device *dev;	dev = container_of(class_dev, struct ib_ucm_device, class_dev);	cdev_del(&dev->dev);	clear_bit(dev->devnum, dev_map);	kfree(dev);}static struct file_operations ucm_fops = {	.owner 	 = THIS_MODULE,	.open 	 = ib_ucm_open,	.release = ib_ucm_close,	.write 	 = ib_ucm_write,	.poll    = ib_ucm_poll,};static struct class ucm_class = {	.name    = "infiniband_cm",	.release = ib_ucm_release_class_dev};static ssize_t show_dev(struct class_device *class_dev, char *buf){	struct ib_ucm_device *dev;		dev = container_of(class_dev, struct ib_ucm_device, class_dev);	return print_dev_t(buf, dev->dev.dev);}static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);static ssize_t show_ibdev(struct class_device *class_dev, char *buf){	struct ib_ucm_device *dev;		dev = container_of(class_dev, struct ib_ucm_device, class_dev);	return sprintf(buf, "%s\n", dev->ib_dev->name);}static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);static void ib_ucm_add_one(struct ib_device *device){	struct ib_ucm_device *ucm_dev;	if (!device->alloc_ucontext)		return;	ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL);	if (!ucm_dev)		return;	ucm_dev->ib_dev = device;	ucm_dev->devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES);	if (ucm_dev->devnum >= IB_UCM_MAX_DEVICES)		goto err;	set_bit(ucm_dev->devnum, dev_map);	cdev_init(&ucm_dev->dev, &ucm_fops);	ucm_dev->dev.owner = THIS_MODULE;	kobject_set_name(&ucm_dev->dev.kobj, "ucm%d", ucm_dev->devnum);	if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1))		goto err;	ucm_dev->class_dev.class = &ucm_class;	ucm_dev->class_dev.dev = device->dma_device;	snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",		 ucm_dev->devnum);	if (class_device_register(&ucm_dev->class_dev))		goto err_cdev;	if (class_device_create_file(&ucm_dev->class_dev,				     &class_device_attr_dev))		goto err_class;	if (class_device_create_file(&ucm_dev->class_dev,				     &class_device_attr_ibdev))		goto err_class;	ib_set_client_data(device, &ucm_client, ucm_dev);	return;err_class:	class_device_unregister(&ucm_dev->class_dev);err_cdev:	cdev_del(&ucm_dev->dev);	clear_bit(ucm_dev->devnum, dev_map);err:	kfree(ucm_dev);	return;}static void ib_ucm_remove_one(struct ib_device *device){	struct ib_ucm_device *ucm_dev = ib_get_client_data(device, &ucm_client);	if (!ucm_dev)		return;	class_device_unregister(&ucm_dev->class_dev);}static ssize_t show_abi_version(struct class *class, char *buf){	return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION);}static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);static int __init ib_ucm_init(void){	int ret;	ret = register_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES,				     "infiniband_cm");	if (ret) {		printk(KERN_ERR "ucm: couldn't register device number\n");		goto err;	}	ret = class_register(&ucm_class);	if (ret) {		printk(KERN_ERR "ucm: couldn't create class infiniband_cm\n");		goto err_chrdev;	}	ret = class_create_file(&ucm_class, &class_attr_abi_version);	if (ret) {		printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");		goto err_class;	}	ret = ib_register_client(&ucm_client);	if (ret) {		printk(KERN_ERR "ucm: couldn't register client\n");		goto err_class;	}	return 0;err_class:	class_unregister(&ucm_class);err_chrdev:	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);err:	return ret;}static void __exit ib_ucm_cleanup(void){	ib_unregister_client(&ucm_client);	class_unregister(&ucm_class);	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);	idr_destroy(&ctx_id_table);}module_init(ib_ucm_init);module_exit(ib_ucm_cleanup);

⌨️ 快捷键说明

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