xref: /openbmc/linux/drivers/char/ipmi/ipmi_devintf.c (revision 22246614)
1 /*
2  * ipmi_devintf.c
3  *
4  * Linux device interface for the IPMI message handler.
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2002 MontaVista Software Inc.
11  *
12  *  This program is free software; you can redistribute it and/or modify it
13  *  under the terms of the GNU General Public License as published by the
14  *  Free Software Foundation; either version 2 of the License, or (at your
15  *  option) any later version.
16  *
17  *
18  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *  You should have received a copy of the GNU General Public License along
30  *  with this program; if not, write to the Free Software Foundation, Inc.,
31  *  675 Mass Ave, Cambridge, MA 02139, USA.
32  */
33 
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/errno.h>
37 #include <asm/system.h>
38 #include <linux/poll.h>
39 #include <linux/spinlock.h>
40 #include <linux/slab.h>
41 #include <linux/ipmi.h>
42 #include <linux/mutex.h>
43 #include <linux/init.h>
44 #include <linux/device.h>
45 #include <linux/compat.h>
46 
47 struct ipmi_file_private
48 {
49 	ipmi_user_t          user;
50 	spinlock_t           recv_msg_lock;
51 	struct list_head     recv_msgs;
52 	struct file          *file;
53 	struct fasync_struct *fasync_queue;
54 	wait_queue_head_t    wait;
55 	struct mutex	     recv_mutex;
56 	int                  default_retries;
57 	unsigned int         default_retry_time_ms;
58 };
59 
60 static void file_receive_handler(struct ipmi_recv_msg *msg,
61 				 void                 *handler_data)
62 {
63 	struct ipmi_file_private *priv = handler_data;
64 	int                      was_empty;
65 	unsigned long            flags;
66 
67 	spin_lock_irqsave(&(priv->recv_msg_lock), flags);
68 
69 	was_empty = list_empty(&(priv->recv_msgs));
70 	list_add_tail(&(msg->link), &(priv->recv_msgs));
71 
72 	if (was_empty) {
73 		wake_up_interruptible(&priv->wait);
74 		kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
75 	}
76 
77 	spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
78 }
79 
80 static unsigned int ipmi_poll(struct file *file, poll_table *wait)
81 {
82 	struct ipmi_file_private *priv = file->private_data;
83 	unsigned int             mask = 0;
84 	unsigned long            flags;
85 
86 	poll_wait(file, &priv->wait, wait);
87 
88 	spin_lock_irqsave(&priv->recv_msg_lock, flags);
89 
90 	if (!list_empty(&(priv->recv_msgs)))
91 		mask |= (POLLIN | POLLRDNORM);
92 
93 	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
94 
95 	return mask;
96 }
97 
98 static int ipmi_fasync(int fd, struct file *file, int on)
99 {
100 	struct ipmi_file_private *priv = file->private_data;
101 	int                      result;
102 
103 	result = fasync_helper(fd, file, on, &priv->fasync_queue);
104 
105 	return (result);
106 }
107 
108 static struct ipmi_user_hndl ipmi_hndlrs =
109 {
110 	.ipmi_recv_hndl	= file_receive_handler,
111 };
112 
113 static int ipmi_open(struct inode *inode, struct file *file)
114 {
115 	int                      if_num = iminor(inode);
116 	int                      rv;
117 	struct ipmi_file_private *priv;
118 
119 
120 	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
121 	if (!priv)
122 		return -ENOMEM;
123 
124 	priv->file = file;
125 
126 	rv = ipmi_create_user(if_num,
127 			      &ipmi_hndlrs,
128 			      priv,
129 			      &(priv->user));
130 	if (rv) {
131 		kfree(priv);
132 		return rv;
133 	}
134 
135 	file->private_data = priv;
136 
137 	spin_lock_init(&(priv->recv_msg_lock));
138 	INIT_LIST_HEAD(&(priv->recv_msgs));
139 	init_waitqueue_head(&priv->wait);
140 	priv->fasync_queue = NULL;
141 	mutex_init(&priv->recv_mutex);
142 
143 	/* Use the low-level defaults. */
144 	priv->default_retries = -1;
145 	priv->default_retry_time_ms = 0;
146 
147 	return 0;
148 }
149 
150 static int ipmi_release(struct inode *inode, struct file *file)
151 {
152 	struct ipmi_file_private *priv = file->private_data;
153 	int                      rv;
154 
155 	rv = ipmi_destroy_user(priv->user);
156 	if (rv)
157 		return rv;
158 
159 	ipmi_fasync (-1, file, 0);
160 
161 	/* FIXME - free the messages in the list. */
162 	kfree(priv);
163 
164 	return 0;
165 }
166 
167 static int handle_send_req(ipmi_user_t     user,
168 			   struct ipmi_req *req,
169 			   int             retries,
170 			   unsigned int    retry_time_ms)
171 {
172 	int              rv;
173 	struct ipmi_addr addr;
174 	struct kernel_ipmi_msg msg;
175 
176 	if (req->addr_len > sizeof(struct ipmi_addr))
177 		return -EINVAL;
178 
179 	if (copy_from_user(&addr, req->addr, req->addr_len))
180 		return -EFAULT;
181 
182 	msg.netfn = req->msg.netfn;
183 	msg.cmd = req->msg.cmd;
184 	msg.data_len = req->msg.data_len;
185 	msg.data = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
186 	if (!msg.data)
187 		return -ENOMEM;
188 
189 	/* From here out we cannot return, we must jump to "out" for
190 	   error exits to free msgdata. */
191 
192 	rv = ipmi_validate_addr(&addr, req->addr_len);
193 	if (rv)
194 		goto out;
195 
196 	if (req->msg.data != NULL) {
197 		if (req->msg.data_len > IPMI_MAX_MSG_LENGTH) {
198 			rv = -EMSGSIZE;
199 			goto out;
200 		}
201 
202 		if (copy_from_user(msg.data,
203 				   req->msg.data,
204 				   req->msg.data_len))
205 		{
206 			rv = -EFAULT;
207 			goto out;
208 		}
209 	} else {
210 		msg.data_len = 0;
211 	}
212 
213 	rv = ipmi_request_settime(user,
214 				  &addr,
215 				  req->msgid,
216 				  &msg,
217 				  NULL,
218 				  0,
219 				  retries,
220 				  retry_time_ms);
221  out:
222 	kfree(msg.data);
223 	return rv;
224 }
225 
226 static int ipmi_ioctl(struct inode  *inode,
227 		      struct file   *file,
228 		      unsigned int  cmd,
229 		      unsigned long data)
230 {
231 	int                      rv = -EINVAL;
232 	struct ipmi_file_private *priv = file->private_data;
233 	void __user *arg = (void __user *)data;
234 
235 	switch (cmd)
236 	{
237 	case IPMICTL_SEND_COMMAND:
238 	{
239 		struct ipmi_req req;
240 
241 		if (copy_from_user(&req, arg, sizeof(req))) {
242 			rv = -EFAULT;
243 			break;
244 		}
245 
246 		rv = handle_send_req(priv->user,
247 				     &req,
248 				     priv->default_retries,
249 				     priv->default_retry_time_ms);
250 		break;
251 	}
252 
253 	case IPMICTL_SEND_COMMAND_SETTIME:
254 	{
255 		struct ipmi_req_settime req;
256 
257 		if (copy_from_user(&req, arg, sizeof(req))) {
258 			rv = -EFAULT;
259 			break;
260 		}
261 
262 		rv = handle_send_req(priv->user,
263 				     &req.req,
264 				     req.retries,
265 				     req.retry_time_ms);
266 		break;
267 	}
268 
269 	case IPMICTL_RECEIVE_MSG:
270 	case IPMICTL_RECEIVE_MSG_TRUNC:
271 	{
272 		struct ipmi_recv      rsp;
273 		int              addr_len;
274 		struct list_head *entry;
275 		struct ipmi_recv_msg  *msg;
276 		unsigned long    flags;
277 
278 
279 		rv = 0;
280 		if (copy_from_user(&rsp, arg, sizeof(rsp))) {
281 			rv = -EFAULT;
282 			break;
283 		}
284 
285 		/* We claim a mutex because we don't want two
286                    users getting something from the queue at a time.
287                    Since we have to release the spinlock before we can
288                    copy the data to the user, it's possible another
289                    user will grab something from the queue, too.  Then
290                    the messages might get out of order if something
291                    fails and the message gets put back onto the
292                    queue.  This mutex prevents that problem. */
293 		mutex_lock(&priv->recv_mutex);
294 
295 		/* Grab the message off the list. */
296 		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
297 		if (list_empty(&(priv->recv_msgs))) {
298 			spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
299 			rv = -EAGAIN;
300 			goto recv_err;
301 		}
302 		entry = priv->recv_msgs.next;
303 		msg = list_entry(entry, struct ipmi_recv_msg, link);
304 		list_del(entry);
305 		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
306 
307 		addr_len = ipmi_addr_length(msg->addr.addr_type);
308 		if (rsp.addr_len < addr_len)
309 		{
310 			rv = -EINVAL;
311 			goto recv_putback_on_err;
312 		}
313 
314 		if (copy_to_user(rsp.addr, &(msg->addr), addr_len)) {
315 			rv = -EFAULT;
316 			goto recv_putback_on_err;
317 		}
318 		rsp.addr_len = addr_len;
319 
320 		rsp.recv_type = msg->recv_type;
321 		rsp.msgid = msg->msgid;
322 		rsp.msg.netfn = msg->msg.netfn;
323 		rsp.msg.cmd = msg->msg.cmd;
324 
325 		if (msg->msg.data_len > 0) {
326 			if (rsp.msg.data_len < msg->msg.data_len) {
327 				rv = -EMSGSIZE;
328 				if (cmd == IPMICTL_RECEIVE_MSG_TRUNC) {
329 					msg->msg.data_len = rsp.msg.data_len;
330 				} else {
331 					goto recv_putback_on_err;
332 				}
333 			}
334 
335 			if (copy_to_user(rsp.msg.data,
336 					 msg->msg.data,
337 					 msg->msg.data_len))
338 			{
339 				rv = -EFAULT;
340 				goto recv_putback_on_err;
341 			}
342 			rsp.msg.data_len = msg->msg.data_len;
343 		} else {
344 			rsp.msg.data_len = 0;
345 		}
346 
347 		if (copy_to_user(arg, &rsp, sizeof(rsp))) {
348 			rv = -EFAULT;
349 			goto recv_putback_on_err;
350 		}
351 
352 		mutex_unlock(&priv->recv_mutex);
353 		ipmi_free_recv_msg(msg);
354 		break;
355 
356 	recv_putback_on_err:
357 		/* If we got an error, put the message back onto
358 		   the head of the queue. */
359 		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
360 		list_add(entry, &(priv->recv_msgs));
361 		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
362 		mutex_unlock(&priv->recv_mutex);
363 		break;
364 
365 	recv_err:
366 		mutex_unlock(&priv->recv_mutex);
367 		break;
368 	}
369 
370 	case IPMICTL_REGISTER_FOR_CMD:
371 	{
372 		struct ipmi_cmdspec val;
373 
374 		if (copy_from_user(&val, arg, sizeof(val))) {
375 			rv = -EFAULT;
376 			break;
377 		}
378 
379 		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
380 					   IPMI_CHAN_ALL);
381 		break;
382 	}
383 
384 	case IPMICTL_UNREGISTER_FOR_CMD:
385 	{
386 		struct ipmi_cmdspec   val;
387 
388 		if (copy_from_user(&val, arg, sizeof(val))) {
389 			rv = -EFAULT;
390 			break;
391 		}
392 
393 		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
394 					     IPMI_CHAN_ALL);
395 		break;
396 	}
397 
398 	case IPMICTL_REGISTER_FOR_CMD_CHANS:
399 	{
400 		struct ipmi_cmdspec_chans val;
401 
402 		if (copy_from_user(&val, arg, sizeof(val))) {
403 			rv = -EFAULT;
404 			break;
405 		}
406 
407 		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
408 					   val.chans);
409 		break;
410 	}
411 
412 	case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
413 	{
414 		struct ipmi_cmdspec_chans val;
415 
416 		if (copy_from_user(&val, arg, sizeof(val))) {
417 			rv = -EFAULT;
418 			break;
419 		}
420 
421 		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
422 					     val.chans);
423 		break;
424 	}
425 
426 	case IPMICTL_SET_GETS_EVENTS_CMD:
427 	{
428 		int val;
429 
430 		if (copy_from_user(&val, arg, sizeof(val))) {
431 			rv = -EFAULT;
432 			break;
433 		}
434 
435 		rv = ipmi_set_gets_events(priv->user, val);
436 		break;
437 	}
438 
439 	/* The next four are legacy, not per-channel. */
440 	case IPMICTL_SET_MY_ADDRESS_CMD:
441 	{
442 		unsigned int val;
443 
444 		if (copy_from_user(&val, arg, sizeof(val))) {
445 			rv = -EFAULT;
446 			break;
447 		}
448 
449 		rv = ipmi_set_my_address(priv->user, 0, val);
450 		break;
451 	}
452 
453 	case IPMICTL_GET_MY_ADDRESS_CMD:
454 	{
455 		unsigned int  val;
456 		unsigned char rval;
457 
458 		rv = ipmi_get_my_address(priv->user, 0, &rval);
459 		if (rv)
460 			break;
461 
462 		val = rval;
463 
464 		if (copy_to_user(arg, &val, sizeof(val))) {
465 			rv = -EFAULT;
466 			break;
467 		}
468 		break;
469 	}
470 
471 	case IPMICTL_SET_MY_LUN_CMD:
472 	{
473 		unsigned int val;
474 
475 		if (copy_from_user(&val, arg, sizeof(val))) {
476 			rv = -EFAULT;
477 			break;
478 		}
479 
480 		rv = ipmi_set_my_LUN(priv->user, 0, val);
481 		break;
482 	}
483 
484 	case IPMICTL_GET_MY_LUN_CMD:
485 	{
486 		unsigned int  val;
487 		unsigned char rval;
488 
489 		rv = ipmi_get_my_LUN(priv->user, 0, &rval);
490 		if (rv)
491 			break;
492 
493 		val = rval;
494 
495 		if (copy_to_user(arg, &val, sizeof(val))) {
496 			rv = -EFAULT;
497 			break;
498 		}
499 		break;
500 	}
501 
502 	case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:
503 	{
504 		struct ipmi_channel_lun_address_set val;
505 
506 		if (copy_from_user(&val, arg, sizeof(val))) {
507 			rv = -EFAULT;
508 			break;
509 		}
510 
511 		return ipmi_set_my_address(priv->user, val.channel, val.value);
512 		break;
513 	}
514 
515 	case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD:
516 	{
517 		struct ipmi_channel_lun_address_set val;
518 
519 		if (copy_from_user(&val, arg, sizeof(val))) {
520 			rv = -EFAULT;
521 			break;
522 		}
523 
524 		rv = ipmi_get_my_address(priv->user, val.channel, &val.value);
525 		if (rv)
526 			break;
527 
528 		if (copy_to_user(arg, &val, sizeof(val))) {
529 			rv = -EFAULT;
530 			break;
531 		}
532 		break;
533 	}
534 
535 	case IPMICTL_SET_MY_CHANNEL_LUN_CMD:
536 	{
537 		struct ipmi_channel_lun_address_set val;
538 
539 		if (copy_from_user(&val, arg, sizeof(val))) {
540 			rv = -EFAULT;
541 			break;
542 		}
543 
544 		rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);
545 		break;
546 	}
547 
548 	case IPMICTL_GET_MY_CHANNEL_LUN_CMD:
549 	{
550 		struct ipmi_channel_lun_address_set val;
551 
552 		if (copy_from_user(&val, arg, sizeof(val))) {
553 			rv = -EFAULT;
554 			break;
555 		}
556 
557 		rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);
558 		if (rv)
559 			break;
560 
561 		if (copy_to_user(arg, &val, sizeof(val))) {
562 			rv = -EFAULT;
563 			break;
564 		}
565 		break;
566 	}
567 
568 	case IPMICTL_SET_TIMING_PARMS_CMD:
569 	{
570 		struct ipmi_timing_parms parms;
571 
572 		if (copy_from_user(&parms, arg, sizeof(parms))) {
573 			rv = -EFAULT;
574 			break;
575 		}
576 
577 		priv->default_retries = parms.retries;
578 		priv->default_retry_time_ms = parms.retry_time_ms;
579 		rv = 0;
580 		break;
581 	}
582 
583 	case IPMICTL_GET_TIMING_PARMS_CMD:
584 	{
585 		struct ipmi_timing_parms parms;
586 
587 		parms.retries = priv->default_retries;
588 		parms.retry_time_ms = priv->default_retry_time_ms;
589 
590 		if (copy_to_user(arg, &parms, sizeof(parms))) {
591 			rv = -EFAULT;
592 			break;
593 		}
594 
595 		rv = 0;
596 		break;
597 	}
598 
599 	case IPMICTL_GET_MAINTENANCE_MODE_CMD:
600 	{
601 		int mode;
602 
603 		mode = ipmi_get_maintenance_mode(priv->user);
604 		if (copy_to_user(arg, &mode, sizeof(mode))) {
605 			rv = -EFAULT;
606 			break;
607 		}
608 		rv = 0;
609 		break;
610 	}
611 
612 	case IPMICTL_SET_MAINTENANCE_MODE_CMD:
613 	{
614 		int mode;
615 
616 		if (copy_from_user(&mode, arg, sizeof(mode))) {
617 			rv = -EFAULT;
618 			break;
619 		}
620 		rv = ipmi_set_maintenance_mode(priv->user, mode);
621 		break;
622 	}
623 	}
624 
625 	return rv;
626 }
627 
628 #ifdef CONFIG_COMPAT
629 
630 /*
631  * The following code contains code for supporting 32-bit compatible
632  * ioctls on 64-bit kernels.  This allows running 32-bit apps on the
633  * 64-bit kernel
634  */
635 #define COMPAT_IPMICTL_SEND_COMMAND	\
636 	_IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
637 #define COMPAT_IPMICTL_SEND_COMMAND_SETTIME	\
638 	_IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
639 #define COMPAT_IPMICTL_RECEIVE_MSG	\
640 	_IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
641 #define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC	\
642 	_IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
643 
644 struct compat_ipmi_msg {
645 	u8		netfn;
646 	u8		cmd;
647 	u16		data_len;
648 	compat_uptr_t	data;
649 };
650 
651 struct compat_ipmi_req {
652 	compat_uptr_t		addr;
653 	compat_uint_t		addr_len;
654 	compat_long_t		msgid;
655 	struct compat_ipmi_msg	msg;
656 };
657 
658 struct compat_ipmi_recv {
659 	compat_int_t		recv_type;
660 	compat_uptr_t		addr;
661 	compat_uint_t		addr_len;
662 	compat_long_t		msgid;
663 	struct compat_ipmi_msg	msg;
664 };
665 
666 struct compat_ipmi_req_settime {
667 	struct compat_ipmi_req	req;
668 	compat_int_t		retries;
669 	compat_uint_t		retry_time_ms;
670 };
671 
672 /*
673  * Define some helper functions for copying IPMI data
674  */
675 static long get_compat_ipmi_msg(struct ipmi_msg *p64,
676 				struct compat_ipmi_msg __user *p32)
677 {
678 	compat_uptr_t tmp;
679 
680 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
681 			__get_user(p64->netfn, &p32->netfn) ||
682 			__get_user(p64->cmd, &p32->cmd) ||
683 			__get_user(p64->data_len, &p32->data_len) ||
684 			__get_user(tmp, &p32->data))
685 		return -EFAULT;
686 	p64->data = compat_ptr(tmp);
687 	return 0;
688 }
689 
690 static long put_compat_ipmi_msg(struct ipmi_msg *p64,
691 				struct compat_ipmi_msg __user *p32)
692 {
693 	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
694 			__put_user(p64->netfn, &p32->netfn) ||
695 			__put_user(p64->cmd, &p32->cmd) ||
696 			__put_user(p64->data_len, &p32->data_len))
697 		return -EFAULT;
698 	return 0;
699 }
700 
701 static long get_compat_ipmi_req(struct ipmi_req *p64,
702 				struct compat_ipmi_req __user *p32)
703 {
704 
705 	compat_uptr_t	tmp;
706 
707 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
708 			__get_user(tmp, &p32->addr) ||
709 			__get_user(p64->addr_len, &p32->addr_len) ||
710 			__get_user(p64->msgid, &p32->msgid) ||
711 			get_compat_ipmi_msg(&p64->msg, &p32->msg))
712 		return -EFAULT;
713 	p64->addr = compat_ptr(tmp);
714 	return 0;
715 }
716 
717 static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
718 		struct compat_ipmi_req_settime __user *p32)
719 {
720 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
721 			get_compat_ipmi_req(&p64->req, &p32->req) ||
722 			__get_user(p64->retries, &p32->retries) ||
723 			__get_user(p64->retry_time_ms, &p32->retry_time_ms))
724 		return -EFAULT;
725 	return 0;
726 }
727 
728 static long get_compat_ipmi_recv(struct ipmi_recv *p64,
729 				 struct compat_ipmi_recv __user *p32)
730 {
731 	compat_uptr_t tmp;
732 
733 	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
734 			__get_user(p64->recv_type, &p32->recv_type) ||
735 			__get_user(tmp, &p32->addr) ||
736 			__get_user(p64->addr_len, &p32->addr_len) ||
737 			__get_user(p64->msgid, &p32->msgid) ||
738 			get_compat_ipmi_msg(&p64->msg, &p32->msg))
739 		return -EFAULT;
740 	p64->addr = compat_ptr(tmp);
741 	return 0;
742 }
743 
744 static long put_compat_ipmi_recv(struct ipmi_recv *p64,
745 				 struct compat_ipmi_recv __user *p32)
746 {
747 	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
748 			__put_user(p64->recv_type, &p32->recv_type) ||
749 			__put_user(p64->addr_len, &p32->addr_len) ||
750 			__put_user(p64->msgid, &p32->msgid) ||
751 			put_compat_ipmi_msg(&p64->msg, &p32->msg))
752 		return -EFAULT;
753 	return 0;
754 }
755 
756 /*
757  * Handle compatibility ioctls
758  */
759 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
760 			      unsigned long arg)
761 {
762 	int rc;
763 	struct ipmi_file_private *priv = filep->private_data;
764 
765 	switch(cmd) {
766 	case COMPAT_IPMICTL_SEND_COMMAND:
767 	{
768 		struct ipmi_req	rp;
769 
770 		if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
771 			return -EFAULT;
772 
773 		return handle_send_req(priv->user, &rp,
774 				priv->default_retries,
775 				priv->default_retry_time_ms);
776 	}
777 	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
778 	{
779 		struct ipmi_req_settime	sp;
780 
781 		if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
782 			return -EFAULT;
783 
784 		return handle_send_req(priv->user, &sp.req,
785 				sp.retries, sp.retry_time_ms);
786 	}
787 	case COMPAT_IPMICTL_RECEIVE_MSG:
788 	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
789 	{
790 		struct ipmi_recv   __user *precv64;
791 		struct ipmi_recv   recv64;
792 
793 		if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
794 			return -EFAULT;
795 
796 		precv64 = compat_alloc_user_space(sizeof(recv64));
797 		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
798 			return -EFAULT;
799 
800 		rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep,
801 				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
802 				 ? IPMICTL_RECEIVE_MSG
803 				 : IPMICTL_RECEIVE_MSG_TRUNC),
804 				(unsigned long) precv64);
805 		if (rc != 0)
806 			return rc;
807 
808 		if (copy_from_user(&recv64, precv64, sizeof(recv64)))
809 			return -EFAULT;
810 
811 		if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
812 			return -EFAULT;
813 
814 		return rc;
815 	}
816 	default:
817 		return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg);
818 	}
819 }
820 #endif
821 
822 static const struct file_operations ipmi_fops = {
823 	.owner		= THIS_MODULE,
824 	.ioctl		= ipmi_ioctl,
825 #ifdef CONFIG_COMPAT
826 	.compat_ioctl   = compat_ipmi_ioctl,
827 #endif
828 	.open		= ipmi_open,
829 	.release	= ipmi_release,
830 	.fasync		= ipmi_fasync,
831 	.poll		= ipmi_poll,
832 };
833 
834 #define DEVICE_NAME     "ipmidev"
835 
836 static int ipmi_major;
837 module_param(ipmi_major, int, 0);
838 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
839 		 " default, or if you set it to zero, it will choose the next"
840 		 " available device.  Setting it to -1 will disable the"
841 		 " interface.  Other values will set the major device number"
842 		 " to that value.");
843 
844 /* Keep track of the devices that are registered. */
845 struct ipmi_reg_list {
846 	dev_t            dev;
847 	struct list_head link;
848 };
849 static LIST_HEAD(reg_list);
850 static DEFINE_MUTEX(reg_list_mutex);
851 
852 static struct class *ipmi_class;
853 
854 static void ipmi_new_smi(int if_num, struct device *device)
855 {
856 	dev_t dev = MKDEV(ipmi_major, if_num);
857 	struct ipmi_reg_list *entry;
858 
859 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
860 	if (!entry) {
861 		printk(KERN_ERR "ipmi_devintf: Unable to create the"
862 		       " ipmi class device link\n");
863 		return;
864 	}
865 	entry->dev = dev;
866 
867 	mutex_lock(&reg_list_mutex);
868 	device_create(ipmi_class, device, dev, "ipmi%d", if_num);
869 	list_add(&entry->link, &reg_list);
870 	mutex_unlock(&reg_list_mutex);
871 }
872 
873 static void ipmi_smi_gone(int if_num)
874 {
875 	dev_t dev = MKDEV(ipmi_major, if_num);
876 	struct ipmi_reg_list *entry;
877 
878 	mutex_lock(&reg_list_mutex);
879 	list_for_each_entry(entry, &reg_list, link) {
880 		if (entry->dev == dev) {
881 			list_del(&entry->link);
882 			kfree(entry);
883 			break;
884 		}
885 	}
886 	device_destroy(ipmi_class, dev);
887 	mutex_unlock(&reg_list_mutex);
888 }
889 
890 static struct ipmi_smi_watcher smi_watcher =
891 {
892 	.owner    = THIS_MODULE,
893 	.new_smi  = ipmi_new_smi,
894 	.smi_gone = ipmi_smi_gone,
895 };
896 
897 static __init int init_ipmi_devintf(void)
898 {
899 	int rv;
900 
901 	if (ipmi_major < 0)
902 		return -EINVAL;
903 
904 	printk(KERN_INFO "ipmi device interface\n");
905 
906 	ipmi_class = class_create(THIS_MODULE, "ipmi");
907 	if (IS_ERR(ipmi_class)) {
908 		printk(KERN_ERR "ipmi: can't register device class\n");
909 		return PTR_ERR(ipmi_class);
910 	}
911 
912 	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
913 	if (rv < 0) {
914 		class_destroy(ipmi_class);
915 		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
916 		return rv;
917 	}
918 
919 	if (ipmi_major == 0) {
920 		ipmi_major = rv;
921 	}
922 
923 	rv = ipmi_smi_watcher_register(&smi_watcher);
924 	if (rv) {
925 		unregister_chrdev(ipmi_major, DEVICE_NAME);
926 		class_destroy(ipmi_class);
927 		printk(KERN_WARNING "ipmi: can't register smi watcher\n");
928 		return rv;
929 	}
930 
931 	return 0;
932 }
933 module_init(init_ipmi_devintf);
934 
935 static __exit void cleanup_ipmi(void)
936 {
937 	struct ipmi_reg_list *entry, *entry2;
938 	mutex_lock(&reg_list_mutex);
939 	list_for_each_entry_safe(entry, entry2, &reg_list, link) {
940 		list_del(&entry->link);
941 		device_destroy(ipmi_class, entry->dev);
942 		kfree(entry);
943 	}
944 	mutex_unlock(&reg_list_mutex);
945 	class_destroy(ipmi_class);
946 	ipmi_smi_watcher_unregister(&smi_watcher);
947 	unregister_chrdev(ipmi_major, DEVICE_NAME);
948 }
949 module_exit(cleanup_ipmi);
950 
951 MODULE_LICENSE("GPL");
952 MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
953 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
954