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

📄 ipmi_devintf.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (copy_to_user(arg, &val, sizeof(val))) {			rv = -EFAULT;			break;		}		break;	}	case IPMICTL_SET_MY_LUN_CMD:	{		unsigned int val;		if (copy_from_user(&val, arg, sizeof(val))) {			rv = -EFAULT;			break;		}		rv = ipmi_set_my_LUN(priv->user, 0, val);		break;	}	case IPMICTL_GET_MY_LUN_CMD:	{		unsigned int  val;		unsigned char rval;		rv = ipmi_get_my_LUN(priv->user, 0, &rval);		if (rv)			break;		val = rval;		if (copy_to_user(arg, &val, sizeof(val))) {			rv = -EFAULT;			break;		}		break;	}	case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:	{		struct ipmi_channel_lun_address_set val;		if (copy_from_user(&val, arg, sizeof(val))) {			rv = -EFAULT;			break;		}		return ipmi_set_my_address(priv->user, val.channel, val.value);		break;	}	case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD:	{		struct ipmi_channel_lun_address_set val;		if (copy_from_user(&val, arg, sizeof(val))) {			rv = -EFAULT;			break;		}		rv = ipmi_get_my_address(priv->user, val.channel, &val.value);		if (rv)			break;		if (copy_to_user(arg, &val, sizeof(val))) {			rv = -EFAULT;			break;		}		break;	}	case IPMICTL_SET_MY_CHANNEL_LUN_CMD:	{		struct ipmi_channel_lun_address_set val;		if (copy_from_user(&val, arg, sizeof(val))) {			rv = -EFAULT;			break;		}		rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);		break;	}	case IPMICTL_GET_MY_CHANNEL_LUN_CMD:	{		struct ipmi_channel_lun_address_set val;		if (copy_from_user(&val, arg, sizeof(val))) {			rv = -EFAULT;			break;		}		rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);		if (rv)			break;		if (copy_to_user(arg, &val, sizeof(val))) {			rv = -EFAULT;			break;		}		break;	}	case IPMICTL_SET_TIMING_PARMS_CMD:	{		struct ipmi_timing_parms parms;		if (copy_from_user(&parms, arg, sizeof(parms))) {			rv = -EFAULT;			break;		}		priv->default_retries = parms.retries;		priv->default_retry_time_ms = parms.retry_time_ms;		rv = 0;		break;	}	case IPMICTL_GET_TIMING_PARMS_CMD:	{		struct ipmi_timing_parms parms;		parms.retries = priv->default_retries;		parms.retry_time_ms = priv->default_retry_time_ms;		if (copy_to_user(arg, &parms, sizeof(parms))) {			rv = -EFAULT;			break;		}		rv = 0;		break;	}	}  	return rv;}#ifdef CONFIG_COMPAT/* * The following code contains code for supporting 32-bit compatible * ioctls on 64-bit kernels.  This allows running 32-bit apps on the * 64-bit kernel */#define COMPAT_IPMICTL_SEND_COMMAND	\	_IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)#define COMPAT_IPMICTL_SEND_COMMAND_SETTIME	\	_IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)#define COMPAT_IPMICTL_RECEIVE_MSG	\	_IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)#define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC	\	_IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)struct compat_ipmi_msg {	u8		netfn;	u8		cmd;	u16		data_len;	compat_uptr_t	data;};struct compat_ipmi_req {	compat_uptr_t		addr;	compat_uint_t		addr_len;	compat_long_t		msgid;	struct compat_ipmi_msg	msg;};struct compat_ipmi_recv {	compat_int_t		recv_type;	compat_uptr_t		addr;	compat_uint_t		addr_len;	compat_long_t		msgid;	struct compat_ipmi_msg	msg;};struct compat_ipmi_req_settime {	struct compat_ipmi_req	req;	compat_int_t		retries;	compat_uint_t		retry_time_ms;};/* * Define some helper functions for copying IPMI data */static long get_compat_ipmi_msg(struct ipmi_msg *p64,				struct compat_ipmi_msg __user *p32){	compat_uptr_t tmp;	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||			__get_user(p64->netfn, &p32->netfn) ||			__get_user(p64->cmd, &p32->cmd) ||			__get_user(p64->data_len, &p32->data_len) ||			__get_user(tmp, &p32->data))		return -EFAULT;	p64->data = compat_ptr(tmp);	return 0;}static long put_compat_ipmi_msg(struct ipmi_msg *p64,				struct compat_ipmi_msg __user *p32){	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||			__put_user(p64->netfn, &p32->netfn) ||			__put_user(p64->cmd, &p32->cmd) ||			__put_user(p64->data_len, &p32->data_len))		return -EFAULT;	return 0;}static long get_compat_ipmi_req(struct ipmi_req *p64,				struct compat_ipmi_req __user *p32){	compat_uptr_t	tmp;	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||			__get_user(tmp, &p32->addr) ||			__get_user(p64->addr_len, &p32->addr_len) ||			__get_user(p64->msgid, &p32->msgid) ||			get_compat_ipmi_msg(&p64->msg, &p32->msg))		return -EFAULT;	p64->addr = compat_ptr(tmp);	return 0;}static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,		struct compat_ipmi_req_settime __user *p32){	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||			get_compat_ipmi_req(&p64->req, &p32->req) ||			__get_user(p64->retries, &p32->retries) ||			__get_user(p64->retry_time_ms, &p32->retry_time_ms))		return -EFAULT;	return 0;}static long get_compat_ipmi_recv(struct ipmi_recv *p64,				 struct compat_ipmi_recv __user *p32){	compat_uptr_t tmp;	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||			__get_user(p64->recv_type, &p32->recv_type) ||			__get_user(tmp, &p32->addr) ||			__get_user(p64->addr_len, &p32->addr_len) ||			__get_user(p64->msgid, &p32->msgid) ||			get_compat_ipmi_msg(&p64->msg, &p32->msg))		return -EFAULT;	p64->addr = compat_ptr(tmp);	return 0;}static long put_compat_ipmi_recv(struct ipmi_recv *p64,				 struct compat_ipmi_recv __user *p32){	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||			__put_user(p64->recv_type, &p32->recv_type) ||			__put_user(p64->addr_len, &p32->addr_len) ||			__put_user(p64->msgid, &p32->msgid) ||			put_compat_ipmi_msg(&p64->msg, &p32->msg))		return -EFAULT;	return 0;}/* * Handle compatibility ioctls */static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,			      unsigned long arg){	int rc;	struct ipmi_file_private *priv = filep->private_data;	switch(cmd) {	case COMPAT_IPMICTL_SEND_COMMAND:	{		struct ipmi_req	rp;		if (get_compat_ipmi_req(&rp, compat_ptr(arg)))			return -EFAULT;		return handle_send_req(priv->user, &rp,				priv->default_retries,				priv->default_retry_time_ms);	}	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:	{		struct ipmi_req_settime	sp;		if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))			return -EFAULT;		return handle_send_req(priv->user, &sp.req,				sp.retries, sp.retry_time_ms);	}	case COMPAT_IPMICTL_RECEIVE_MSG:	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:	{		struct ipmi_recv   __user *precv64;		struct ipmi_recv   recv64;		if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))			return -EFAULT;		precv64 = compat_alloc_user_space(sizeof(recv64));		if (copy_to_user(precv64, &recv64, sizeof(recv64)))			return -EFAULT;		rc = ipmi_ioctl(filep->f_dentry->d_inode, filep,				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)				 ? IPMICTL_RECEIVE_MSG				 : IPMICTL_RECEIVE_MSG_TRUNC),				(unsigned long) precv64);		if (rc != 0)			return rc;		if (copy_from_user(&recv64, precv64, sizeof(recv64)))			return -EFAULT;		if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))			return -EFAULT;		return rc;	}	default:		return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);	}}#endifstatic struct file_operations ipmi_fops = {	.owner		= THIS_MODULE,	.ioctl		= ipmi_ioctl,#ifdef CONFIG_COMPAT	.compat_ioctl   = compat_ipmi_ioctl,#endif	.open		= ipmi_open,	.release	= ipmi_release,	.fasync		= ipmi_fasync,	.poll		= ipmi_poll,};#define DEVICE_NAME     "ipmidev"static int ipmi_major = 0;module_param(ipmi_major, int, 0);MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"		 " default, or if you set it to zero, it will choose the next"		 " available device.  Setting it to -1 will disable the"		 " interface.  Other values will set the major device number"		 " to that value.");static struct class *ipmi_class;static void ipmi_new_smi(int if_num){	dev_t dev = MKDEV(ipmi_major, if_num);	devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,		      "ipmidev/%d", if_num);	class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num);}static void ipmi_smi_gone(int if_num){	class_device_destroy(ipmi_class, MKDEV(ipmi_major, if_num));	devfs_remove("ipmidev/%d", if_num);}static struct ipmi_smi_watcher smi_watcher ={	.owner    = THIS_MODULE,	.new_smi  = ipmi_new_smi,	.smi_gone = ipmi_smi_gone,};static __init int init_ipmi_devintf(void){	int rv;	if (ipmi_major < 0)		return -EINVAL;	printk(KERN_INFO "ipmi device interface\n");	ipmi_class = class_create(THIS_MODULE, "ipmi");	if (IS_ERR(ipmi_class)) {		printk(KERN_ERR "ipmi: can't register device class\n");		return PTR_ERR(ipmi_class);	}	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);	if (rv < 0) {		class_destroy(ipmi_class);		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);		return rv;	}	if (ipmi_major == 0) {		ipmi_major = rv;	}	devfs_mk_dir(DEVICE_NAME);	rv = ipmi_smi_watcher_register(&smi_watcher);	if (rv) {		unregister_chrdev(ipmi_major, DEVICE_NAME);		class_destroy(ipmi_class);		printk(KERN_WARNING "ipmi: can't register smi watcher\n");		return rv;	}	return 0;}module_init(init_ipmi_devintf);static __exit void cleanup_ipmi(void){	class_destroy(ipmi_class);	ipmi_smi_watcher_unregister(&smi_watcher);	devfs_remove(DEVICE_NAME);	unregister_chrdev(ipmi_major, DEVICE_NAME);}module_exit(cleanup_ipmi);MODULE_LICENSE("GPL");MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");

⌨️ 快捷键说明

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